I have this formula
=IF( B2>3.5, (((B3*B1*1.4*12)/100))+((B1/3)*45*(B3*12/13/4/40)), (B1/3)*45*(B3*12/13/4/40) )
The outcome is in full euro's. Is it possible to round to whole euros? Like this with a point between the thousands and hundreds €25.962
I have this formula
=IF( B2>3.5, (((B3*B1*1.4*12)/100))+((B1/3)*45*(B3*12/13/4/40)), (B1/3)*45*(B3*12/13/4/40) )
The outcome is in full euro's. Is it possible to round to whole euros? Like this with a point between the thousands and hundreds €25.962
I am using openpyxl version 2.3.5 to write data into an existing, formatted, excel template (with .xlsx extension). The problem is that when I write to a cell, the formatting of that cell is completely overwritten. For example, Cell A1 has a blue fill. When I execute the following code:
wb = xl.load_workbook('Template.xlsx')ws = wb.worksheets[0]ws['A1'] = "TEST"wb.save('test.xlsx')
The fill of cell A1 is lost. There is a lot of formatting in the spreadsheet, so I do not want to manually specify all of it. I have tried copying the original formatting of the cell from itself to no avail. This code did not work:
ws['A1'].style = ws['A1'].style
Is there any way to keep and/or copy the original style/formatting of the excel spreadsheet, and only write in the data?
In Power Query, I have one query with bank transactions and an empty column for transaction coding. If I set up another query with transaction coding rules (e.g., Column A equals "abc" and Column B contains "xyz"), is there a way to merge the two queries to code the bank transactions in the first query based on the transaction coding rules in the second query?
So, Listbox1 is populated (from another sub, linked to range of cells in the workbook) and users can select (one at a time) items from that Listbox to be shown in Listbox2, using a Command Button (Add) to move them. I've nearly managed to get it perfect. My problem is that if a user only selects the final entry in Listbox1, all other possible entries in Listbox1 are removed (blanked out/not visible/cannot be selected).
I want only the entry which has been selected from Listbox1 to be removed from Listbox1 as it appears in Listbox2.
Here's the code:
Private Sub Add_Click()Dim i as Integer For i = 0 To Me.ListBox1.ListCount - 1 If Me.ListBox1.Selected(i) = True Then Me.ListBox2.AddItem Me.ListBox1.List(i) End If Next i For i = Me.ListBox1.ListCount - 1 To 0 Step -1 If Me.ListBox1.Selected(i) = True Then Me.ListBox1.RemoveItem i End If NextEnd Sub
If there's anything obvious here, I'm really sorry. But these Listboxes have been driving me crazy for about 3 days now.Thanks in advance
I have a problem with exporting table from Access Table to Excel file.If I use transferspreadsheet:
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, tableName, _"PathToFile\export.xlsx", True
one of the rows from the Access Table is not exported.But if I right click on the Access table and go to Export -> Excel, this file is with all rows from the table. I don't know what the difference is between these 2 ways of exporting.
So does anybody can help me why this one row missing when I use transferspreadsheet?
Final final results:
I was wondering whether the results below changed if the string was longer. I ran exactly the same tests on the same computer, except each cell had a random string of 34 characters rather than four. These were the results:
Comintern (Regexp): 136.1 ms brettdj (Regexp): 139.9 ms Slai (Regexp): 158.4 ms *Original Regex: 161.0 ms* Comintern (AN): 170.1 ms Comintern (Hash): 183.6 ms ThunderFrame: 232.9 ms *Original replace: 372.9 ms* *Original InStr: 478.1 ms* CallumDA33: 1218.1 ms
This really shows the speed of the Regex - all the solutions utilising Regex.replace are significantly faster, with the best being Comintern's implementation.
In summary, if the strings are long, use arrays, if they are short, use the clipboard. If unsure, the optimal result is to use arrays, but this may sacrifice a little performance on short strings.
Final results:
Thanks very much for all of your suggestions, clearly I still have a lot to learn. I was thinking about this all yesterday, so I decided to rerun everything at home. Here are the final results, based on applying each of these to 30,000 four character strings.
My computer at home is an Intel i7 @ 3.6 GHz, 8GB RAM, 64-bit Windows 10 and Excel 2016. Similar conditions to before in that I have processes running in the background, but I'm not actively doing anything throughout the tests.
Original replace: 97.67 msOriginal InStr: 106.54 msOriginal Regex: 113.46 msThunderFrame: 82.21 msComintern (AN): 96.98 msComintern (OR): 81.87 msComintern (Hash): 101.18 msbrettdj: 81.66 msCallumDA33: 201.64 msSlai: 68.38 ms
I've therefore accepted Slai's answer as it is clearly the fastest for general implementation, but I'll rerun them all at work against the actual data to check this still works.
Original post:
I have an array in Excel that is a list of part numbers. I need to turn every member of the array alphanumeric, for example
ABC123-001 -> ABC123001ABC123/001 -> ABC123001ABC123001 -> ABC123001
What is the fastest way of doing this?
For context, our part numbers can come in different forms, so I'm writing a function that finds the best match within a given range. At the moment, the part of the function that makes everything alphanumeric takes about 50ms to run, whereas the rest of the function takes around 30ms in total. I also can't avoid using Excel.
I've done some work myself (see answer below), but the main issue is that I have to loop through every element of the array one-by-one - could there be a better way? I've also never run tests before, so any feedback on improving them would be much appreciated.
Here is what I've tried so far.
I'm using MicroTimer and my computer has an Intel i5 @2.5GHz, 4GB of RAM, 64-bit Windows 7. I've got processes running in the background, but I'm not actively doing anything else whilst these are run.
I created 30,000 lines of random symbols using this code:
=CHAR(RANDBETWEEN(1,60))&CHAR(RANDBETWEEN(48,57))&CHAR(RANDBETWEEN(37,140))&CHAR(RANDBETWEEN(37,140))
(note how we stop the first character at 60 because '=' is char(61)
and we want to avoid Excel interpreting this as a formula. Also we force the second character to be a number so we can guarantee at least one alphanumeric character in there.)
1. Using a loop based on cases. Average time: 175ms
Using the function in this post, we load the range into an array, apply the function to each element of the array and paste it back. Code:
Function AlphaNumericOnly(strSource As Variant) As String Dim i As Integer Dim strResult As String For i = 1 To Len(strSource) Select Case Asc(Mid(strSource, i, 1)) Case 48 To 57, 65 To 90, 97 To 122: 'include 32 if you want to include space strResult = strResult & Mid(strSource, i, 1) End Select Next AlphaNumericOnly = strResultEnd FunctionSub Replace() Dim inputSh As Worksheet Dim inputRng As Range Set inputSh = Sheets("Data") Set inputRng = inputSh.Range("A1:A30000") Dim outputSh As Worksheet Dim outputRng As Range Set outputSh = Sheets("Replace") Set outputRng = outputSh.Range("A1:A30000") Dim time1 As Double, time2 As Double time1 = MicroTimer Dim arr As Variant arr = inputRng Dim i As Integer For i = LBound(arr) To UBound(arr) arr(i, 1) = AlphaNumericOnly(arr(i, 1)) Next i outputRng = arr time2 = MicroTimer Debug.Print (time2 - time1) * 1000End Sub
2. Using InStr() to check each character. Average time: 201ms
Define a string of valid values. Check one-by-one if the valid values appear in the array elements:
Sub InStr() Dim inputSh As Worksheet Dim inputRng As Range Set inputSh = Sheets("Data") Set inputRng = inputSh.Range("A1:A30000") Dim outputSh As Worksheet Dim outputRng As Range Set outputSh = Sheets("InStr") Set outputRng = outputSh.Range("A1:A30000") Dim time1 As Double, time2 As Double time1 = MicroTimer Dim arr As Variant arr = inputRng Dim validValues As String validValues = "01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"'put numbers and capitals at the start as they are more likely' Dim i As Integer, j As Integer Dim result As String For i = LBound(arr) To UBound(arr) result = vbNullString For j = 1 To Len(arr(i, 1)) If InStr(validValues, Mid(arr(i, 1), j, 1)) <> 0 Then result = result & Mid(arr(i, 1), j, 1) End If Next j arr(i, 1) = result Next i outputRng = arr time2 = MicroTimer Debug.Print (time2 - time1) * 1000End Sub
3. Using regex.Replace on the array. Time: 171ms
Define a regex and use this to replace each element of the array.
Sub Regex() Dim inputSh As Worksheet Dim inputRng As Range Set inputSh = Sheets("Data") Set inputRng = inputSh.Range("A1:A30000") Dim outputSh As Worksheet Dim outputRng As Range Set outputSh = Sheets("Regex") Set outputRng = outputSh.Range("A1:A30000") Dim time1 As Double, time2 As Double time1 = MicroTimer Dim arr As Variant arr = inputRng Dim objRegex As Object Set objRegex = CreateObject("vbscript.regexp") With objRegex .Global = True .ignorecase = True .Pattern = "[^\w]" End With Dim i As Integer For i = LBound(arr) To UBound(arr) arr(i, 1) = objRegex.Replace(arr(i, 1), vbNullString) Next i outputRng = arr time2 = MicroTimer Debug.Print (time2 - time1) * 1000End Sub
Edit:
@ThunderFrame - our part numbers generally come in the following formats:
I have thought about using regex.test on each string before launching into the replacement, but I'm not sure if this will just copy the string to then test it, in which case I may as well just make the replacement to start with.
@Slai - thanks for the link - I will look into that in more detail
I'm new in using excel vba. Would like to know a smart way to count amount of consecutive 1s in an array (or excel column) of zeros and ones.
Considering the following array:
A = [0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 1 1 1 1 0 0 1 1 1 1 1 0 0];
I would like to get the following output:
Result = [4 4 1 5 5];
I know that in matlab it's easy to achieve with RunLength function, but in vba I can't find a similar function.
I tried adapting the following matlab code but cannot reach what I want due to proper use of find function.
clcclear allA = [0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 1 1 1 1 0 0 1 1 1 1 1 0 0];B = A(2:end);C = A(1:end-1) - B;D = find(C~=0);Result = [D(1) D(2:end) - D(1:end-1) length(A)-D(end)]
Thanks a lot for any help!
I am trying to create a website that will produce dynamic tables/graphs from custom data I have collected about companies. Because I want to make the data I've collected scalable for a website, I decided to convert my source excel data into a PHPmyadmin database.
However, I am not very technical. Therefore I find the process of converting my source excel data into a csv file for each worksheet, then inserting into the PHPmyadmin database long-winded and impractical.
Is there a better, more efficient way to collect data so that it can be inserted into a (wordpress) website database quickly and easily? I find collecting the source data in excel very straightforward, but then the conversion process difficult, so looking for alternative ways! (Happy to change collecting source data from excel into another user-friendly application if recommended)
Thanks in advance!!!
So i have a workbook i am trying to bring into a number of tabs into a workbook opened as part of a loop but i keep getting the error code "Runtime error 9 subscript out of range" and can't figure out why:
Here is my code so far:
Sub Rollforward()
Application.Calculation = xlCalculationManualApplication.EnableEvents = FalseApplication.ScreenUpdating = FalseApplication.AskToUpdateLinks = FalseApplication.DisplayAlerts = FalseSet wb1 = Workbooks.Open("C:\Users\Desktop\700 Test\700 code template") 'move to shared file location when finishedSet wb2 = Workbooks.Open("C:\Users\Documents\Rollforward\2020 TB.xlsx")Set wb3 = Workbooks.Open("C:\Users\Documents\Rollforward\2019 TB.xlsx") Dim wb4 As Workbook Application.ScreenUpdating = FalseSet MyFile = Application.FileDialog(msoFileDialogFolderPicker) With MyFile .Title = "Please select folder" .Show .AllowMultiSelect = False If .SelectedItems.Count = 0 Then MsgBox "You did not select a folder." Exit Sub End If MyFolder = .SelectedItems(1) & "\"'Assign the selected folder to MyFolder (defines it)End WithMyFile = Dir(MyFolder) Do While MyFile <> "" Set wb4 = Workbooks.Open(Filename:=MyFolder & MyFile)wb4.ActivateApplication.ScreenUpdating = FalseApplication.AskToUpdateLinks = FalseApplication.DisplayAlerts = FalseSheets("P&L").DeleteSheets("B-S").Deletewb1.Sheets("Cover").Range("A9:B20").Copywb4.Sheets("Cover").Range("A9").PasteSpecialwb2.ActivateDim arr As Variantarr = wb4.Sheets("March 2020 TB").Range("A1").ValueWorksheets("Report1").Range("A3").Autofilter _ Field:=1, _ Criteria1:=arr, _ VisibleDropDown:=FalseDim startCell As Range, LastRow As Long, LastCol As Long, ws As WorksheetSet ws = Sheets("Report1")Set startCell = Range("A4") LastRow = ws.Cells(ws.Rows.Count, startCell.Column).End(xlUp).Row LastCol = ws.Cells(startCell.Row, ws.Columns.Count).End(xlToLeft).Columnws.Range(startCell, ws.Cells(LastRow, LastCol)).SelectSelection.Copywb4.ActivateSheets("March 2020 TB").SelectRange("B3").PasteSpecial Paste:=xlPasteValueswb3.ActivateWorksheets("Report1").Range("A3").Autofilter _ Field:=1, _ Criteria1:=arr, _ VisibleDropDown:=FalseSet ws = Sheets("Report1")Set startCell = Range("A4") LastRow = ws.Cells(ws.Rows.Count, startCell.Column).End(xlUp).Row LastCol = ws.Cells(startCell.Row, ws.Columns.Count).End(xlToLeft).Columnws.Range(startCell, ws.Cells(LastRow, LastCol)).SelectSelection.Copywb4.ActivateSheets("March 2019 TB").SelectRange("B3").PasteSpecial Paste:=xlPasteValueswb1.Activate 'Template fileWorksheets("P&L").Activate ActiveSheet.Copy After:=wb4.Sheets(6)wb1.ActivateWorksheets("B-S").Activate ActiveSheet.Copy After:=wb4.Sheets(7)wb4.ActivateSheets("Cover").ActivateRange("B9").Formula = "=VLOOKUP(""Net Assets"",'B-S'!A6:E37,5,0)*1000"wb1.ActivateWorksheets("P1 - Trade creditors").Activate ActiveSheet.Copy After:=Workbooks("wb4").Sheets(13)
The last line is where i get the error. Any help would be great!!
I am new to Python and working on a project that I could use some help on. So I am trying to modify an existing excel workbook in order to compare stock data. Luckily, there was a program online that retrieved all the data I need and I have successful been able to pull the data and write the data into a new excel file. However, the goal is to pull the data and put it into an existing excel file. Furthermore, I need to overwrite the cell values in the existing file. I believe xlwings is able to do this and I think my code is on the write track, but I ran into an unexpected error. The error I get is:
com_error: (-2147023174, 'The RPC server is unavailable.', None, None)
I was wondering if anyone knew why this error came up? Also, does anyone know how to fix it? Is it fixable? Is my code wrong? Any help or guidance is appreciated. Thank you.
import good_morning as gmimport pandas as pdimport xlwings as xw#import income statement, balance sheet, and cash flow of AAPLfd = gm.FinancialsDownloader()fd_frames = fd.download('AAPL')#Creates a DataFrame for only the balance sheetdf1 = pd.DataFrame(list(fd_frames.values())[0])#connects to workbook I want to modifywb = xw.Book(r'C:/Users/vince/OneDrive/Documents/Python/Project/spreadsheet.xlsm')#sheet I would like to modifysht = wb.sheets[1]#modifies & overwrites values in my spreadsheetsht.range('M6').value = df1
I have a dynamic named range that I use and I am looking into using the filter function to reduce that data down on another worksheet using references to criteria on that new worksheet.
=FILTER(Loss_Run, ULGTACCT Code = $B$2,"")
ULGTACCT is the column name,
$B$2 will have a number stored as text
Loss_Run is dynamic named range that is an indirect formula (This could be the cause of my headache)
Online I found If its named I can just reference the name of the range and columns by name but since its a formula will that not work?
Update=FILTER('Loss Template'!A:M, 'Loss Template'!A:A = $B$2,"")
The formula directly above references a "printout" of the named range that is used in workbook and if I hardcode the value for B2 it works but it does not work if i try to reference B2.
Note: It would be kinda difficult to mock up Loss_Run because of the nature of the range being a complicated indirect().
In the chart below, I would like to show an area fill where the line plot should not enter. I've gotten close to a solution, but I can't seem to line up the x-axis correctly. This is where I am currently at:
I wanted the area fill to be in alignment with the x-y scatter plot. Where the x-y scatter line plot appears, there should be an associated area fill.
How to go about lining up the scatter plot with the area plot?
Here is the data for the area plot:
and here is the data for the line plot:
I have a workbook that I'd like to copy sheets and transfer them to another workbook. This works, and the conditional formatting is brought over as well, just not for the whole sheet. Only half of the conditional formatting is being copied to the new sheet.
source_workbook.sheets(1).copy After:=target_workbook.sheets(target_workbook.sheets.count)
I have a 500k line excel like the sample below:
ref, RSRQ, Signal, SNR, TestDate ST782347, -13, -116, 40, 01/04/2020ST782347, -9, -111, 110, 22/02/2020ST782347, -10, -115, 70, 22/02/2020ST782347, -9, -111, 110, 22/02/2020ST782349, -10, -110, 90, 22/02/2020ST782349, -10, -114, 50, 22/02/2020
Now the "ref" can have 1 to 800 equal values, but I only want the most recent 10 if it has 10 or more, otherwise should be discarded. I have been stuck here for a couple of days now, any help will be extremely appreciated.
I have created two excel sheets:
I am writing data to data_sheet
and generating a graph in graph_sheet
. I want to hide the data_sheet
. But I am not able to do so using the function - data_sheet.hide()
.
I am able to hide a blank sheet using that method but it doesn't seem to work for the data_sheet
.
Hello you beautiful people,
I'm hoping one of you can save me hours and hours of work by giving me a genius solution to automate this task...
I have 200 PDFs in a document on my Mac. The file name of each PDF is a unique 8 letter code.
I also have an Excel Glossary where common terms used in those PDFs are defined - there are around 1500 glossary terms.
My boss wants that we create an additional column in the excel called "Documents Where Term is Used" and list all of the documents using that term.
We will then transfer this into a database to manage the upkeep of this mapping going forward. My need here is the initial mapping
Instead of manually opening each PDF which is just not do-able. how can i have some sort of script or tool take the term in each row of the Excel, scan the 200 documents to see if that term is used, and populate the column in the Excel with the file names of the PDFs where that term is actually used.
As you can imagine, 1500 terms times 200 PDFs = i will die before i finish this if i try to do this manually
All ideas welcome and happy to pay for a tool if thats what is needed. I can also do this on a Windows machine if need be
Thanks all, realllllly excited to hear your solutions
I have several MySQL queries, including some that aggregate but don't necessarily return dates in the results, that have either a date or date range hardcoded into the query. I've loaded these into separate Excel worksheets through ODBC to output the results. Instead of going into the query and editing the source as needed to change the dates, how can I have the 'start' or 'start and end' date(s) of the query be a cell reference on that particular worksheet?
The date part of my SQL predicates look like:
WHERE post.trans_date >= '2020-03-01'
or
WHERE post.trans_date >= '2020-03-01'AND post.trans_date <= '2020-03-31'
I'd like to just be able to change the dates directly in the cell(s), without VBA, and click Refresh to return the correct results. Thanks!
I have my data structured like this (extracted from SQL) of people taking the bus in one section and getting off in another (or the same):
Track Direction Hour Passengers Section In Section Out1175 Going 6 1 1 41175 Going 6 1 2 51175 Going 7 1 1 41175 Going 8 1 1 41175 Going 12 1 2 5... ... ... ... ... ...
I need the following 3 tables to be dynamic so I can apply filters:
My biggest problem is how to do the filter context in the TOTAL table because I have 2 columns of sections (Section In and Section Out). I don't know how to combine them or create a new one so I can have the expected result in a pivot table.
Also the the TOTAL table should calculate the Maximun value instead of doing the difference of the other 2 tables.
Ask me if you need more details. Here is the the data so you can test a possible solution. Thank you!