how can i optimize the VBA code for formatting? - excel

I have below code which will help me to do some formatting. but i want increase the efficiency of the code by reducing the time. Below are the formatting steps which macro will be doing.
Convert "Q" and "S" column" to number format.
Replicate the "I" column to new column by inserting column next to it.
Cut the Column "AD" and paste to column "O".
Remove columns ("A:A,AD:AG")
Replace "#" with null and "OUT" with P input value in "AC" column.
Round the "Q" and "S" column numbers to 2 decimal.
Change the sign of values in column Q by multiplying -1(*-1)
Filter on "Q" column with "0" and filter on "S" column with "0". Then
remove those rows with "Q" and "S" is Zero.
Filter 0 on Q column, Clear only visible cells of "Q" and "R" Columns.
Filter 0 on "S" column, Clear only visible cells of "S" and "T" Columns.
Copy the headers (ThisWorkbook.Sheets("Tool").Range("A20:AC20").Copy) and
paste to the A1 of file formatted.
Remove all columns and rows which doesn’t have data apart from used
range.
Currently macro working fine but taking some time.As i am new to VBA not sure how to optimize the code. Hence i here looking for help from experts. Thanks in advance.
Below is the code
Sub Ananplan_to_BPM()
Dim LastRow As Long
Dim Lastcol As Long
Dim P As String
'Display a Dialog Box that allows to select a single file.
'The path for the file picked will be stored in fullpath variable
With Application.FileDialog(msoFileDialogFilePicker)
'Makes sure the user can select only one file
.AllowMultiSelect = True
'Filter to just the following types of files to narrow down selection options
'.Filters.Add "All Files", "*.xlsx; *.xlsm; *.xls; *.xlsb; *.csv"
'Show the dialog box
.Show
'Store in fullpath variable
fullpath = .SelectedItems.Item(1)
End With
'It's a good idea to still check if the file type selected is accurate.
'Quit the procedure if the user didn't select the type of file we need.
If InStr(fullpath, ".xls") = 0 Then
If InStr(fullpath, ".csv") = 0 Then
Exit Sub
End If
End If
'Open the file selected by the user
Workbooks.Open fullpath
P = InputBox("Please Enter the Version")
Application.ScreenUpdating = False
With ActiveWorkbook
Columns(17).NumberFormat = "0"
Columns(19).NumberFormat = "0"
LastRow = Cells(Rows.Count, 2).End(xlUp).Row
Lastcol = Cells(1, Columns.Count).End(xlToLeft).Column
Columns("I").Copy
Columns("I").Insert Shift:=xlToRight
'Range("AE2").Value = P
'Range("AE2", "AE" & Cells(Rows.Count, "B").End(xlUp).Row).FillDown
Columns("AE").Copy
Columns("P").PasteSpecial xlPasteValues
ActiveSheet.Range("A:A,AE:AG").EntireColumn.Delete
Columns("AC").Replace What:="#", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Columns("AC").Replace What:="OUT", Replacement:=P, LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Range("AD2").Formula = "=Round(Q2,2)"
Range("AD2", "AD" & Cells(Rows.Count, "B").End(xlUp).Row).FillDown
Range("AD2", "AD" & Cells(Rows.Count, "B").End(xlUp).Row).Copy
Range("Q2").PasteSpecial xlPasteValues
Range("AD2").Formula = "=Round(S2,2)"
Range("AD2", "AD" & Cells(Rows.Count, "B").End(xlUp).Row).FillDown
Range("AD2", "AD" & Cells(Rows.Count, "B").End(xlUp).Row).Copy
Range("S2").PasteSpecial xlPasteValues
Range("AD2").Formula = "=(Q2*-1)"
Range("AD2", "AD" & Cells(Rows.Count, "B").End(xlUp).Row).FillDown
Range("AD2", "AD" & Cells(Rows.Count, "B").End(xlUp).Row).Copy
Range("Q2").PasteSpecial xlPasteValues
Columns("AD:AD").EntireColumn.Delete
With ActiveSheet.Range("A:AC")
.AutoFilter Field:=17, Criteria1:="0"
.AutoFilter Field:=19, Criteria1:="0"
.Range("A2:A" & LastRow).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.AutoFilter
.AutoFilter Field:=17, Criteria1:="0"
.Range("Q2:R" & LastRow).SpecialCells(xlCellTypeVisible).Clear
.AutoFilter
.AutoFilter Field:=19, Criteria1:="0"
.Range("S2:T" & LastRow).SpecialCells(xlCellTypeVisible).Clear
.AutoFilter
'.Range("C2").AutoFill .Range("C2:C" & .Cells(.Rows.Count, "B").End(xlUp).Row)
End With
End With
ThisWorkbook.Sheets("Tool").Range("A20:AC20").Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlPasteValues
Columns("A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
Rows("1").SpecialCells(xlCellTypeBlanks).EntireColumn.Delete
'ActiveWorkbook.Save
'ActiveWorkbook.Close
MsgBox "Done With Farmatting"
End Sub

This isn't a site for reviewing code. There is another one, especially for that purpose in the StackOverflow family. I nevertheless reviewed your code and found nothing that I might point to to make it slow in particular. There should be ways to do the job faster but they require knowledge of your intentions. It seems you have a big worksheet. So it may take a little time but not enough to have a coffee. My comments, therefore, focus on the code's inherent imprecision which makes it prone to crash as well as prone to do untold damage if it's let lose on the wrong worksheet. I have added comments.
Sub Ananplan_to_BPM()
Dim LastRow As Long
Dim LastCol As Long
Dim P As String
' Display a Dialog Box that allows to select a single file.
' The path for the file picked will be stored in fullpath variable
With Application.FileDialog(msoFileDialogFilePicker)
' Makes sure the user can select only one file - quite the opposite
.AllowMultiSelect = True
'Filter to just the following types of files to narrow down selection options
'.Filters.Add "All Files", "*.xlsx; *.xlsm; *.xls; *.xlsb; *.csv"
'Show the dialog box
.Show
'Store in fullpath variable
fullpath = .SelectedItems.Item(1)
End With
' It's a good idea to still check if the file type selected is accurate.
If InStr(fullpath, ".xls") = 0 Or InStr(fullpath, ".csv") = 0 Then
' Quit the procedure if the user didn't select the type of file we need.
Exit Sub
End If
'Open the file selected by the user
Workbooks.Open fullpath
P = InputBox("Please Enter the Version")
Application.ScreenUpdating = False
With ActiveWorkbook
' There isn't a single reference to the ActiveWorkbook
' in the entire 'With' bracket.
' Create a link to the 'With' object by a leading period.
' Example:-
' With .Worksheets(1) ' linked to ActiveWorkbook
' ' below, both cells and Rows.Count of Worksheets(1)
' LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
' End With
' which sheet are you working on here?
LastRow = Cells(Rows.Count, 2).End(xlUp).Row
LastCol = Cells(1, Columns.Count).End(xlToLeft).Column
Columns(17).NumberFormat = "0"
Columns(19).NumberFormat = "0"
Columns("I").Copy
Columns("I").Insert Shift:=xlToRight
'Range("AE2").Value = P
'Range("AE2", "AE" & Cells(Rows.Count, "B").End(xlUp).Row).FillDown
Columns("AE").Copy
Columns("P").PasteSpecial xlPasteValues
' You didn't activate any sheet
ActiveSheet.Range("A:A,AE:AG").EntireColumn.Delete
' everything you do above or below this line
'' is done to the ActiveSheet
Columns("AC").Replace What:="#", Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
Columns("AC").Replace What:="OUT", Replacement:=P, LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
' This should probably be done using a cell format.
' If you need rounded values in later calculations do
' the rounding in later calculations, not in the original data.
Range("AD2").Formula = "=Round(Q2,2)"
Range("AD2", "AD" & Cells(Rows.Count, "B").End(xlUp).Row).FillDown
Range("AD2", "AD" & Cells(Rows.Count, "B").End(xlUp).Row).Copy
Range("Q2").PasteSpecial xlPasteValues
Range("AD2").Formula = "=Round(S2,2)"
Range("AD2", "AD" & Cells(Rows.Count, "B").End(xlUp).Row).FillDown
Range("AD2", "AD" & Cells(Rows.Count, "B").End(xlUp).Row).Copy
Range("S2").PasteSpecial xlPasteValues
Range("AD2").Formula = "=(Q2*-1)"
Range("AD2", "AD" & Cells(Rows.Count, "B").End(xlUp).Row).FillDown
Range("AD2", "AD" & Cells(Rows.Count, "B").End(xlUp).Row).Copy
Range("Q2").PasteSpecial xlPasteValues
Columns("AD:AD").EntireColumn.Delete
End With
With ActiveSheet.Range("A:AC")
' This method will throw an error if there are no visible cells
' why not suppress the display of zero with a CellFormat?
.AutoFilter Field:=17, Criteria1:="0"
.AutoFilter Field:=19, Criteria1:="0"
.Range("A2:A" & LastRow).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.AutoFilter
.AutoFilter Field:=17, Criteria1:="0"
.Range("Q2:R" & LastRow).SpecialCells(xlCellTypeVisible).Clear
.AutoFilter
.AutoFilter Field:=19, Criteria1:="0"
.Range("S2:T" & LastRow).SpecialCells(xlCellTypeVisible).Clear
.AutoFilter
'.Range("C2").AutoFill .Range("C2:C" & .Cells(.Rows.Count, "B").End(xlUp).Row)
End With
ThisWorkbook.Sheets("Tool").Range("A20:AC20").Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlPasteValues
' you are still working on the undefined ActiveSheet
Columns("A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
Rows("1").SpecialCells(xlCellTypeBlanks).EntireColumn.Delete
'ActiveWorkbook.Save
'ActiveWorkbook.Close
MsgBox "Done With Formatting"
End Sub

Related

To add the excel formulas into VBA Macro with condition

I have recorded some formulas into Macros and they are functioning properly, however I am not able to update them so that they should select the range themselves where the data ends in the last end in Column C. These 3 formulas extracts Date, File Name and Status of Files from Column A. As you see for now the range is e.g. "F3 to F313" where next time if the Data in Column C is up to C500 Range than I have to manually copy and paste the formulas. Is there anyway these 3 formulas should automatically detect the last text cell from Column C and ends there. That would be much helpful.
To Extract Date
Sub Macro13() 'To Extract Date
ActiveCell.FormulaR1C1 = "=extractDate(RC[-1])"
Range("D2").Select
Selection.Copy
Range("D3:D313").Select
ActiveSheet.Paste
Application.CutCopyMode = False
End Sub
To Find Status of File
Sub Macro15() 'To Find Status of File
ActiveCell.FormulaR1C1 = _
"=IFERROR(LOOKUP(2^15,SEARCH({""Feed"",""Feed 1"",""Feed 2""},RC[-3]),{""Feed"",""Feed 1"",""Feed 2""}),""Combine"")"
Range("F2").Select
Selection.Copy
Range("F3:F313").Select
ActiveSheet.Paste
Application.CutCopyMode = False
End Sub
To extract File Name
Sub Macro17() 'To extract File Name
ActiveCell.FormulaR1C1 = _
"=IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))-1))=""ABCD - GAMA "",LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+2),IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))-1))=""ALPHA "",LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+2),IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9," & _
"0},RC[-2]&""1234567890""))-1))=""ABCD - BETA "",LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+8),IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))-1))=""DBETA "",LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+8),IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))-1))=""A"",LEFT(RC[-2]," & _
"MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+6),IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))-1))="""",LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+8),IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))-1))=""ABETA"",LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+6),LEF" & _
"T(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2] & ""1234567890""))-1))))))))"
Range("E2").Select
Selection.Copy
Range("E3:E313").Select
ActiveSheet.Paste
Application.CutCopyMode = False
End Sub
Try this:
Sub TestThis()
Dim LastRow As Long, ws As Worksheet
Set ws = ActiveSheet
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
ws.Range("D2:D" & LastRow).FormulaR1C1 = "=extractDate(RC[-1])"
ws.Range("F2:F" & LastRow).FormulaR1C1 = "=IFERROR(LOOKUP(2^15,SEARCH({""Feed"",""Feed 1"",""Feed 2""},RC[-3]),{""Feed"",""Feed 1"",""Feed 2""}),""Combine"")"
ws.Range("E2:E" & LastRow).FormulaR1C1 = _
"=IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))-1))=""ABCD - GAMA "",LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+2),IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))-1))=""ALPHA "",LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+2),IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9," & _
"0},RC[-2]&""1234567890""))-1))=""ABCD - BETA "",LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+8),IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))-1))=""DBETA "",LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+8),IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))-1))=""A"",LEFT(RC[-2]," & _
"MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+6),IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))-1))="""",LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+8),IF((LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))-1))=""ABETA"",LEFT(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2]&""1234567890""))+6),LEF" & _
"T(RC[-2],MIN(FIND({1,2,3,4,5,6,7,8,9,0},RC[-2] & ""1234567890""))-1))))))))"
End Sub

Excel VBA Search, Copy, & Paste

I am looking for some help modifying existing code in a worksheet that I had created a while back to copy and paste a range from a row rather than the entire row itself.
The original code, which has worked perfect in the original intended function, it would search column A in the Data worksheet for a specified match. it would then copy that row into a specified worksheet and paste each match as a new row.
What I have been trying to modify the code to do now is perform that same search of column A for either " New, Existing Being Removed, Existing To Remain". When finding one of the 3 options it would then copy the data from columns b:g of that matching row and paste it into the rent worksheet starting at a specified cell. For instance rows marked as Existing to remain would need to star being pasted at cell B3, Existing being removed cell m3, and New cell x3. In total there would not be more than 20 rows from the data sheet that would need to be copied and pasted appropriately.
The code below is the current working code that will search, copy, and paste the entire matching row. Not being extremely proficient with VBA code I didn't want to post the muddled mess that I had made of the original code.
Edit With Photos*
#Toddleson I made the changes you suggested but ended up getting an error with the copyfrom.copy line. It is probably much easier to see what I am trying to accomplish visually. In the Data sheet image link below you will see that row A is where the search occurs. For each match it will copy the values from columns B:G of that row and then paste that into the rent sheet.
If you take a look at the rent image you will see that it is broken into the 3 cooresponding sections. From the match that was found in the cooresponing deisgnation from column A in the data sheet it will then paste the information from columns B:G in the Data to the B:G columns in the Rent sheet.
Data Sheet
Rent
Private Sub CommandButton4_Click()
Dim wb1 As Workbook, wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim copyFrom As Range
Dim lRow As Long '<~~ Not Integer. Might give you error in higher versions of excel
Dim strSearch As String
Set wb1 = ThisWorkbook
Set ws1 = wb1.Worksheets("Data")
strSearch = "New"
With ws1
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("A1:A" & lRow)
.AutoFilter Field:=1, Criteria1:="=*" & strSearch & "*"
Set copyFrom = .Resize(lRow - 1, 7)
End With
.AutoFilterMode = False
End With
Set ws2 = wb1.Worksheets("Rent")
With ws2
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=Range("p3"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
copyFrom.Copy ws2.Cells(3, 16).Resize(copyFrom.Rows.Count, copyFrom.Columns.Count)
End With
strSearch = "Existing Being Removed"
With ws1
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("A1:A" & lRow)
.AutoFilter Field:=1, Criteria1:="=*" & strSearch & "*"
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End With
Set ws2 = wb1.Worksheets("Rent")
With ws2
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=Range("p19"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
copyFrom.Copy ws2.Cells(3, 16).Resize(copyFrom.Rows.Count, copyFrom.Columns.Count)
End With
strSearch = "Existing To Remain"
With ws1
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("A1:A" & lRow)
.AutoFilter Field:=1, Criteria1:="=*" & strSearch & "*"
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End With
Set ws2 = wb1.Worksheets("Existing To Remain")
With ws2
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("p35"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
copyFrom.Copy ws2.Cells(3, 16).Resize(copyFrom.Rows.Count, copyFrom.Columns.Count)
End With
End Sub

How can I include only particular words when autofiltering a column using VBA

I am trying to include only certain words in a particular column when autofiltering, but am finding a syntax error message, but cannot see where the error is. The column is H, which is column 8, but when I run the macro, it brings up a compile error...syntax error, with the code which has all the words highlighted.
I have a smaller version of the same code working beautifully in another sheet, though it only filters for 4 words and is looking to exclude them, so has .AutoFilter .Columns.Count, "<>X". With this one I wanted to filter out anything except the words I chose, so I copied the code, everything from With to End With, from the other sheet, amended the words and changed the autofilter line to remove the <>
I'm sure someone here will spot the mistake immediately, but for the life of me I cannot see it.
Here is the code
Sub FA_Racing_1()
'
' FA_Racing_1 Macro
' VDW Rank, RnkPFP, Distance, PR Odds, Handicap
'
Dim ws As Worksheet, lc As Long, lr As Long
Set ws = ActiveSheet
'range from A1 to last column header and last row
lc = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
lr = ws.Cells.Find("*", after:=ws.Range("A1"), LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
With ws.Range("A1", ws.Cells(lr, lc))
With .Cells(2, .Columns.Count).Resize(.Rows.Count - 1)
.FormulaR1C1 = "=if(or(rc8={""Ballinrobe"",""Bellewstown"",""Clonmel"",""Cork"", _
""Curragh"",""Downpatrick"",""Down Royal"",""Dundalk"",""Fairyhouse"", _
""Galway"",""Gowran Park"",""Kilbeggan"",""Killarney"",""Laytown"",""Leopardstown"", _
""Limerick"",""Listowel"",""Naas"",""Navan"",""Punchestown"",""Roscommon"", _
""Sligo"",""Thurles"",""Tipperary"",""Tramore"",""Wexford""}),""X"","""")"
.Value = .Value
End With
.HorizontalAlignment = xlCenter
.AutoFilter .Columns.Count, "X"
.AutoFilter Field:=3, Criteria1:= _
"<>*Handicap*"
.AutoFilter Field:=38, Criteria1:="<=5"
.AutoFilter Field:=24, Criteria1:="=~*", _
Operator:=xlOr, Criteria2:="=~*~*"
.AutoFilter Field:=100, Criteria1:="1"
If .Rows.Count - 1 > 0 Then
On Error Resume Next
.Columns("C:C").EntireColumn.Hidden = True
.Columns("G:G").EntireColumn.Hidden = True
.Columns("I:I").EntireColumn.Hidden = True
.Columns("K:L").EntireColumn.Hidden = True
.Columns("N:W").EntireColumn.Hidden = True
.Columns("Z:AJ").EntireColumn.Hidden = True
.Columns("AN:AO").EntireColumn.Hidden = True
.Columns("AQ:BQ").EntireColumn.Hidden = True
.Columns("BT:CU").EntireColumn.Hidden = True
.Columns("CW:CW").EntireColumn.Hidden = True
.Offset(1, 0).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible).Copy
On Error GoTo 0
Else
Exit Sub
End If
End With
Workbooks("New Results File Active.xlsm").Sheets("FA Racing 1") _
.Range("A" & Rows.Count).End(xlUp).Offset(1).PasteSpecial xlPasteValues
Application.CutCopyMode = False
End Sub
Any thoughts as to what is causing the error?

Search a worksheet for a cell value, then copy the adjacent cells into a variable range

I have several Excel workbooks with each workbook containing multiple sheets.
I do a keyword search across all worksheets using a particular value ("James Smith"). If the value is found, then I need to offset five columns over from that cell location (i.e. the "found cell" which will always be in Column C somewhere so the offset is pointing to column H) and then select/copy the adjacent rows into a range that will ultimately be pasted into a new worksheet "masterSheet".
The problems are:
The cell address in each of these sheets will vary so that the cell address is not the same in each worksheet
I get errors when I try to set the FoundRange value below.
'Search multiple workbooks, look only for sheetnames that begin with "Week of" and don't contain the word "old"
If currentSheet.Name Like "*Week of*" And InStr(currentSheet.Name, "Old") = 0 Then
'If currentSheet.Name Like "*Week of*" Then
'Within the current sheet look for a cell that contains "James Smith"
With currentSheet
.Range("C:C").Columns.Select
Set FoundCell = Selection.Find(What:="James Smith", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'When "James Smith" is found in the current worksheet, get the cell address and offset from that cell location"
OffsetCell = currentSheet.Range(FoundCell.Address).Offset(0, 5).Address
'In Column "H" select the adjacent non-blank cells and copy into a range <line below where I define "FoundRange" is where I keep getting the "runtime error 424 object required error"
Set FoundRange = Range(OffsetCell, OffsetCell.End(xlDown))
For Each cell In currentSheet.Range(FoundRange)
If Not IsEmpty(cell) Then
currentSheet.Range(cell.Address).Copy
masterSheet.Range("D" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
masterSheet.Range("C" & Rows.Count).End(xlUp).Offset(1, 0) = Format(CDate(Replace(Replace(currentSheet.Name, "Week of ", " "), ".", "/")), "mm/dd/yyyy")
masterSheet.Range("C" & Rows.Count).End(xlUp).Offset(0, -1) = "James Bradford"
currentSheet.Range(cell.Address).Offset(0, 1).Copy
masterSheet.Range("E" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
currentSheet.Range(cell.Address).Offset(0, 2).Copy
masterSheet.Range("F" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
currentSheet.Range(cell.Address).Offset(0, 3).Copy
masterSheet.Range("G" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next
End With
End If
This works. FYI... You have James Smith in the find and James Bradford in the loop. I added a mastersheet for testing, so get rid of the "Set masterSheet" line.
Sub RngTest()
'Search multiple workbooks, look only for sheetnames that begin with "Week of" and don't contain the word "old"
Set currentSheet = ActiveSheet
Set masterSheet = ActiveWorkbook.Sheets("MasterSheet")
If currentSheet.Name Like "*Week of*" And InStr(currentSheet.Name, "Old") = 0 Then
'If currentSheet.Name Like "*Week of*" Then
'Within the current sheet look for a cell that contains "James Smith"
With currentSheet
.Range("C:C").Columns.Select
Set FoundCell = Selection.Find(What:="James Smith", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'When "James Smith" is found in the current worksheet, get the cell address and offset from that cell location"
Set OffsetCell = currentSheet.Range(FoundCell.Address).Offset(0, 5)
'In Column "H" select the adjacent non-blank cells and copy into a range <line below where I define "FoundRange" is where I keep getting the "runtime error 424 object required error"
Set FoundRange = Range(OffsetCell, OffsetCell.End(xlDown))
For Each cell In FoundRange.Cells
If Not IsEmpty(cell) Then
currentSheet.Range(cell.Address).Copy
masterSheet.Range("D" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
masterSheet.Range("C" & Rows.Count).End(xlUp).Offset(1, 0) = Format(CDate(Replace(Replace(currentSheet.Name, "Week of ", " "), ".", "/")), "mm/dd/yyyy")
masterSheet.Range("C" & Rows.Count).End(xlUp).Offset(0, -1) = "James Bradford"
currentSheet.Range(cell.Address).Offset(0, 1).Copy
masterSheet.Range("E" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
currentSheet.Range(cell.Address).Offset(0, 2).Copy
masterSheet.Range("F" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
currentSheet.Range(cell.Address).Offset(0, 3).Copy
masterSheet.Range("G" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next
End With
End If
End Sub

How to accelerate an Excel VB Macro

I am trying to accelerate my Excel VB Macro.
I have tried the 5 alternatives below.
But I wonder if I could shorten the execution further.
I found 2 alternatives in User Blogs which I could not get to work.
One alternative is also found in a User Blog but do not understand.
Sub AccelerateMacro()
'
' v1 052817 by eb+mb
' Macro to copy as fast as possible sheet from one workbook into another workbooks
' Declarations for variables are not shown to make code example more legible
' Macro is stored in and run from "DestinationWorkBook.xlsm"
StartTime = Timer
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Alternative = "First"
If Alternative = "First" Then
Workbooks.Open Filename:="SourceWorkBook.xls"
Cells.Select
Selection.Copy
Windows("DestinationWorkBook.xlsm").Activate
Sheets("DestinationSheet").Select
Range("A1").Select
ActiveSheet.Paste
Windows("SourceWorkBook.xls").Activate
ActiveWorkbook.Close
End If
If Alternative = "Second" Then
Workbooks.Open Filename:="SourceWorkBook.xls", ReadOnly:=True
Cells.Select
Selection.Copy
Windows("DestinationWorkBook.xlsm").Activate
Sheets("DestinationSheet").Select
Range("A1").Select
ActiveSheet.Paste
Workbooks("SourceWorkBook.xls").Close SaveChanges:=False
End If
If Alternative = "Third" Then
' I could not get this alternative to work
Workbooks.Open("SourceWorkBook.xls").Worksheets("SourceSheet").Copy
Workbooks.Open("DestinationWorkBook.xlsm").Worksheets("DestinationSheet").Range("A1").PasteSpecial
End If
If Alternative = "Fourth" Then
' I could not get this alternative to work
Workbooks.Open("DestinationWorkBook.xlsm").Worksheets("DestinationSheet").Range("A1") = Workbooks.Open("SourceWorkBook.xls").Worksheets("SourceSheet")
End If
If Alternative = "Fifth" Then
' I don't understand the code in this alternative
Dim wbIn As Workbook
Dim wbOut As Workbook
Dim rSource As Range
Dim rDest As Range
Set wbOut = Application.Workbooks.Open("DestinationWorkBook.xlsm")
Set wbIn = Application.Workbooks.Open("SourceWorkBook.xls")
With wbIn.Sheets("SourceSheet").UsedRange
wbOut.Sheets("DestinationSheet").Range("A1").Resize(.Rows.Count, .Columns.Count) = .Value
End With
SecondsElapsed = Round(Timer - StartTime, 2)
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub
Instead of using UsedRange, find the actual Last Row and Last Column and use that range. UsedRange may not be the range that you think it is :). You may want to see THIS for an explanation.
See this example (UNTESTED)
Sub Sample()
Dim wbIn As Workbook, wbOut As Workbook
Dim rSource As Range
Dim lRow As Long, LCol As Long
Dim LastCol As String
Set wbOut = Workbooks.Open("DestinationWorkBook.xlsm")
Set wbIn = Workbooks.Open("SourceWorkBook.xls")
With wbIn.Sheets("SourceSheet")
'~~> Find Last Row
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
'~~> Find Last Column
LCol = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
'~~> Column Number to Column Name
LastCol = Split(Cells(, LCol).Address, "$")(1)
'~~> This is the range you want
Set rSource = .Range("A1:" & LastCol & lRow)
'~~> Get the values across
wbOut.Sheets("DestinationSheet").Range("A1:" & LastCol & lRow).Value = _
rSource.Value
End With
End Sub

Resources