How to optimize multiple loops in VBA code within Excel - excel
I am not a very efficient vba coder, but I can brute force my way through something. I am trying to optimize this code to have it run more quickly. I would imagine it should be possible to combine the loops somehow, but I am not exactly sure where to start since the Sheets are within the formulas. Any assistance would be greatly appreciated.
Sub Import()
Application.EnableEvents = False 'This stops the background codes on the sheets from activating (smoothens out the process).
Application.ScreenUpdating = False 'Stops the screen from switching back and forth between the Input and the Master
Application.DisplayAlerts = False
If InStr(1, Worksheets("Lookup").Range("B44").Value, "STATE1", vbTextCompare) <> 0 Then
Sheets("SHEET2").Activate
Range("A4").Select
ElseIf InStr(1, Worksheets("Lookup").Range("B44").Value, "STATE2", vbTextCompare) <> 0 Then
Sheets("SHEET2").Activate
Range("A4").Select
ElseIf InStr(1, Worksheets("Lookup").Range("B44").Value, "STATE3", vbTextCompare) <> 0 Then
Sheets("SHEET2").Activate
Range("A4").Select
ElseIf InStr(1, Worksheets("Lookup").Range("B44").Value, "All", vbTextCompare) <> 0 Then
Sheets("SHEET2").Activate
Range("A4").Select
Else:
Sheets("SHEET1").Columns("KA:KC").Hidden = True
Sheets("SHEET2").Columns("KA:KC").Hidden = True
Sheets("SHEET3").Columns("KA:KC").Hidden = True
Sheets("SHEET4").Columns("KA:KC").Hidden = True
MsgBox "Doesn't exist for these locations"
Exit Sub
End If
Sheets("SHEET1").Columns("KA:KC").Hidden = False
Sheets("SHEET2").Columns("KA:KC").Hidden = False
Sheets("SHEET3").Columns("KA:KC").Hidden = False
Sheets("SHEET4").Columns("KA:KC").Hidden = False
`'This removes the old DATASHEET tab from the model before starting (if it exists)
Dim SummaryWB As Workbook
Dim vrtSelectedItem As Variant
For Each Sheet In ActiveWorkbook.Worksheets
If Sheet.Name = "DATASHEET" Then
Sheet.Delete
End If
Next Sheet
''' The below opens the RRS file from the file path defined
Workbooks.Open Filename:="\\Template_Current.xlsx"
'' This just pauses the operating for 1 second to allow the file to be opened seamlessly, can probably be removed.
Application.Wait Now + #12:00:01 AM#
'' This copies the Data from the RRS file and moves it into the CPM model in a new tab, and renames it.
'' It then closes the Source file.
Sheets("Data").Select
Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
Windows("Report.xlsm").Activate
Sheets("YAdd").Select
Sheets.Add After:=ActiveSheet
ActiveSheet.Paste
ActiveSheet.Select
ActiveSheet.Name = "DATASHEET"
Windows("Template_Current.xlsx").Activate
Sheets("List View").Select
Range("D3").Select
Selection.Copy
Windows("Report.xlsm").Activate
Sheets("DATASHEET").Select
Range("W1").Select
ActiveSheet.Paste
Windows("Template_Current.xlsx").Activate
ActiveWorkbook.Close True
Windows("Report.xlsm").Activate
'' and performs a lookup against the DATASHEET tab, matching the Account Number. It currently only
'' shows values if they are found/non-zero. It also clears old data from the columns
'' This also copies the outputed data and pastes only the values.
'' By doing so, we are saving future memory space, so that it doesn't need to recalc everytime you open
'' the file, only when you run this macro.
Sheets("SHEET1").Select
Range("KA25:KC5000").Select
Selection.Delete
Dim LastRow As Long, i As Long
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
For i = 25 To LastRow
Range("KA1").Offset(i - 1, 0).Select
ActiveCell.FormulaR1C1 = _
"=IF(SUMIF(DATASHEET!R2C1:R712C1,SHEET1!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275])>0,SUMIF(DATASHEET!R2C1:R712C1,SHEET1!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275]),"""")"
Range("KB1").Offset(i - 1, 0).Select
ActiveCell.FormulaR1C1 = _
"=IF(SHEET1!RC[-1]="""","""",If(SHEET1!RC[-1]>1.1,""RED"",If(SHEET1!RC[-1]<0.8,""GREEN"",""YELLOW"")))"
Range("KC1").Offset(i - 1, 0).Select
ActiveCell.FormulaR1C1 = _
"=IF(SHEET1!RC[-1]="""","""",SUMIF(DATASHEET!R2C1:R712C1,SHEET1!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275]))"
Next i
Sheets("SHEET1").Select
Range("KA25").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
Selection.PasteSpecial xlPasteValues
Range("KA25").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.NumberFormat = "0.00"
Range("KC25").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.NumberFormat = "0.00%"
Range("KA25").Select
Sheets("SHEET2").Select
Range("KA25:KC5000").Select
Selection.Delete
Dim LastRow1 As Long, i1 As Long
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
For i1 = 25 To LastRow
Range("KA1").Offset(i1 - 1, 0).Select
ActiveCell.FormulaR1C1 = _
"=IF(SUMIF(DATASHEET!R2C1:R712C1,SHEET2!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275])>0,SUMIF(DATASHEET!R2C1:R712C1,SHEET2!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275]),"""")"
Range("KB1").Offset(i1 - 1, 0).Select
ActiveCell.FormulaR1C1 = _
"=IF(SHEET2!RC[-1]="""","""",If(SHEET2!RC[-1]>1.1,""RED"",If(SHEET2!RC[-1]<0.8,""GREEN"",""YELLOW"")))"
Range("KC1").Offset(i1 - 1, 0).Select
ActiveCell.FormulaR1C1 = _
"=IF(SHEET2!RC[-1]="""","""",SUMIF(DATASHEET!R2C1:R712C1,SHEET2!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275]))"
Next i1
Sheets("SHEET2").Select
Range("KA25").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
Selection.PasteSpecial xlPasteValues
Range("KA25").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.NumberFormat = "0.00"
Range("KC25").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.NumberFormat = "0.00%"
Range("KA25").Select
Sheets("SHEET3").Select
Range("KA25:KC5000").Select
Selection.Delete
Dim LastRow2 As Long, i2 As Long
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
For i2 = 25 To LastRow
Range("KA1").Offset(i2 - 1, 0).Select
ActiveCell.FormulaR1C1 = _
"=IF(SUMIF(DATASHEET!R2C1:R712C1,SHEET3!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275])>0,SUMIF(DATASHEET!R2C1:R712C1,SHEET3!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275]),"""")"
Range("KB1").Offset(i2 - 1, 0).Select
ActiveCell.FormulaR1C1 = _
"=IF(SHEET3!RC[-1]="""","""",If(SHEET3!RC[-1]>1.1,""RED"",If(SHEET3!RC[-1]<0.8,""GREEN"",""YELLOW"")))"
Range("KC1").Offset(i2 - 1, 0).Select
ActiveCell.FormulaR1C1 = _
"=IF(SHEET3!RC[-1]="""","""",SUMIF(DATASHEET!R2C1:R712C1,SHEET3!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275]))"
Next i2
Sheets("SHEET3").Select
Range("KA25").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
Selection.PasteSpecial xlPasteValues
Range("KA25").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.NumberFormat = "0.00"
Range("KC25").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.NumberFormat = "0.00%"
Range("KA25").Select
Sheets("SHEET4").Select
Range("KA25:KC5000").Select
Selection.Delete
Dim LastRow3 As Long, i3 As Long
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
For i3 = 25 To LastRow
Range("KA1").Offset(i3 - 1, 0).Select
ActiveCell.FormulaR1C1 = _
"=IF(SUMIF(DATASHEET!R2C1:R712C1,SHEET4!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275])>0,SUMIF(DATASHEET!R2C1:R712C1,SHEET4!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275]),"""")"
Range("KB1").Offset(i3 - 1, 0).Select
ActiveCell.FormulaR1C1 = _
"=IF(SHEET4!RC[-1]="""","""",If(SHEET4!RC[-1]>1.1,""RED"",If(SHEET4!RC[-1]<0.8,""GREEN"",""YELLOW"")))"
Range("KC1").Offset(i3 - 1, 0).Select
ActiveCell.FormulaR1C1 = _
"=IF(SHEET4!RC[-1]="""","""",SUMIF(DATASHEET!R2C1:R712C1,SHEET4!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275]))"
Next i3
Sheets("SHEET4").Select
Range("KA25").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
Selection.PasteSpecial xlPasteValues
Range("KA25").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.NumberFormat = "0.00"
Range("KC25").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.NumberFormat = "0.00%"
Range("KA25").Select
Sheets("DATASHEET").Visible = xlSheetHidden
Application.EnableEvents = True 'Turns background code back on.
Application.ScreenUpdating = True 'Turns ScreenUpdating back on.
Application.DisplayAlerts = True 'Turns Alerts back on.
MsgBox "Import Complete"
End Sub
You want to avoid repeating yourself. Whenever you have duplicate code you need to break it out in to it's own procedure and then call it using the variable that makes it unique. In your case the only unique part is the sheet you are operating on. So I made this example procedure that you can pass sheet objects to:
Private Sub ProcessSheet(thisSheet As Worksheet)
thisSheet.Range("KA25:KC5000").Delete
Dim LastRow As Long, i As Long
LastRow = thisSheet.Cells(thisSheet.Rows.Count, "A").End(xlUp).Row
For i = 25 To LastRow
thisSheet.Range("KA1").Offset(i - 1, 0).FormulaR1C1 = _
"=IF(SUMIF(DATASHEET!R2C1:R712C1," & thisSheet.Name & "!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275])>0,SUMIF(DATASHEET!R2C1:R712C1," & thisSheet.Name & "!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275]),"""")"
thisSheet.Range("KB1").Offset(i - 1, 0).FormulaR1C1 = _
"=IF(" & thisSheet.Name & "!RC[-1]="""","""",If(" & thisSheet.Name & "!RC[-1]>1.1,""RED"",If(" & thisSheet.Name & "!RC[-1]<0.8,""GREEN"",""YELLOW"")))"
thisSheet.Range("KC1").Offset(i - 1, 0).FormulaR1C1 = _
"=IF(" & thisSheet.Name & "!RC[-1]="""","""",SUMIF(DATASHEET!R2C1:R712C1," & thisSheet.Name & "!R25C2:R59C2,DATASHEET!R2C[-275]:R712C[-275]))"
Next i
With thisSheet
.Range("KA25").UsedRange = Sheets("SHEET1").Range("KA25").UsedRange
.Range("KA25", Selection.End(xlDown)).NumberFormat = "0.00"
.Range("KC25", Selection.End(xlDown)).NumberFormat = "0.00%"
End With
End Sub
Then you can call it from your main import procedure like this:
Sub Import()
With Application
.EnableEvents = False 'This stops the background codes on the sheets from activating (smoothens out the process).
.ScreenUpdating = False 'Stops the screen from switching back and forth between the Input and the Master
.DisplayAlerts = False
End With
If InStr(1, Worksheets("Lookup").Range("B44").Value, "STATE1", vbTextCompare) <> 0 Then
Sheets("SHEET2").Activate
Range("A4").Select
ElseIf InStr(1, Worksheets("Lookup").Range("B44").Value, "STATE2", vbTextCompare) <> 0 Then
Sheets("SHEET2").Activate
Range("A4").Select
ElseIf InStr(1, Worksheets("Lookup").Range("B44").Value, "STATE3", vbTextCompare) <> 0 Then
Sheets("SHEET2").Activate
Range("A4").Select
ElseIf InStr(1, Worksheets("Lookup").Range("B44").Value, "All", vbTextCompare) <> 0 Then
Sheets("SHEET2").Activate
Range("A4").Select
Else
Sheets("SHEET1").Columns("KA:KC").Hidden = True
Sheets("SHEET2").Columns("KA:KC").Hidden = True
Sheets("SHEET3").Columns("KA:KC").Hidden = True
Sheets("SHEET4").Columns("KA:KC").Hidden = True
MsgBox "Doesn't exist for these locations"
Exit Sub
End If
Sheets("SHEET1").Columns("KA:KC").Hidden = False
Sheets("SHEET2").Columns("KA:KC").Hidden = False
Sheets("SHEET3").Columns("KA:KC").Hidden = False
Sheets("SHEET4").Columns("KA:KC").Hidden = False
'This removes the old DATASHEET tab from the model before starting (if it exists)
Dim SummaryWB As Workbook
Dim vrtSelectedItem As Variant
For Each Sheet In ActiveWorkbook.Worksheets
If Sheet.Name = "DATASHEET" Then
Sheet.Delete
End If
Next Sheet
''' The below opens the RRS file from the file path defined
Dim RRSFile As Workbook
Set RRSFile = Workbooks.Open(Filename:="\\Template_Current.xlsx")
'' This will allow the workbook to open before continuing
DoEvents
'' This copies the Data from the RRS file and moves it into the CPM model in a new tab, and renames it.
'' It then closes the Source file.
Dim dataRange As Range
dataRange = RRSFile.Sheets("Data").Range("A1").UsedRange
Dim dataSheet As Worksheet
Windows("Report.xlsm").Activate
Set dataSheet = Sheets.Add(After:=Sheets("YAdd"))
dataSheet.Range("A1") = dataRange
dataSheet.Name = "DATASHEET"
RRSFile.Sheets("List View").Range ("D3")
dataSheet.Range("W1") = RRSFile.Sheets("List View").Range("D3")
RSSFile.Close True
Windows("Report.xlsm").Activate
'' and performs a lookup against the DATASHEET tab, matching the Account Number. It currently only
'' shows values if they are found/non-zero. It also clears old data from the columns
'' This also copies the outputed data and pastes only the values.
'' By doing so, we are saving future memory space, so that it doesn't need to recalc everytime you open
'' the file, only when you run this macro.
ProcessSheet Sheets("SHEET1")
ProcessSheet Sheets("SHEET2")
ProcessSheet Sheets("SHEET3")
ProcessSheet Sheets("SHEET4")
Sheets("DATASHEET").Visible = xlSheetHidden
With Application
.EnableEvents = True 'Turns background code back on.
.ScreenUpdating = True 'Turns ScreenUpdating back on.
.DisplayAlerts = True 'Turns Alerts back on.
End With
MsgBox "Import Complete"
End Sub
The big benefit you get here is that you can change that code in one place and it affects all 4 of your loops. Instead of trying to maintain 4 identical copies of the same code.
Related
Is there a way to speed up my code that selects a lot of cells for formatting and creates external sheets faster? Is there a worksheet selection alt?
This demo will be scaled up to perform this operation on data ranges with 100's of rows, so I'm not sure how to make the runtime faster, and avoid selecting different sized ranges using the xlToRight if there was adjacent data. Attached is a view-only xlsm. spreadsheet Sub Main_Loop() ' This script references the number of unique items in the ' filter then loops the data extraction based on this value. ' ' Keyboard Shortcut: Ctrl+Shift+Z ' ' Nate_Ayers Application.ScreenUpdating = False Range("H1").Select Dim i As Integer 'counter Dim Loop_var As String Loop_end = Range("A2").Value2 'Stop loop at end of unique items For i = 1 To Loop_end Selection.Copy Range("A3").Select 'Helper cell location chosen where data wont overwrite the cell Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False 'Paste values only (avoids unique function) Application.CutCopyMode = False Selection.Copy Columns("C:C").AutoFilter ActiveSheet.Range("C:C").AutoFilter Field:=1, Criteria1:=Range("A3") 'Data block grab: Range("C2").Select Range(Selection, Selection.End(xlToRight)).Select Range(Selection, Selection.End(xlDown)).Select Application.CutCopyMode = False Selection.Copy Sheets.Add After:=ActiveSheet Range("A2").Select ActiveSheet.Paste Range("A2").Select Application.CutCopyMode = False Selection.Copy Worksheets(ActiveSheet.Index).Select 'could have efficiency improvement Worksheets(ActiveSheet.Index).Name = Selection 'Name the sheet Range("A1").Select ActiveSheet.Paste Selection.Font.Bold = True Sheets("Demo").Select Range("A3").Select Selection.ClearContents Selection.AutoFilter Range("H1").Select ActiveCell.Offset(0, i).Select 'Reference next row to repeat operations Next i Application.ScreenUpdating = True End Sub
It's hard to know what some of your subroutine is doing without seeing the underlying spreadsheet, and some of the variables don't seem to be referenced. But here are a few examples of how you might be able to speed things up. As already mentioned the main issue is the unnecessary use of copy and paste. This probably won't be a solution that works, but I hope it helps you on the way. Sub Main_Loop() Dim vCalc, vEvents As Variant Dim ws, new_ws As Worksheet Dim i As Integer 'counter Application.ScreenUpdating = False vCalc = Application.Calculation Application.Calculation = xlCalculationManual vEvents = Application.EnableEvents Application.EnableEvents = False Set ws = ActiveSheet i = 1 While ws.Range("H" & i) <> "" ws.Range("A3").Value = ws.Range("H" & i).Value ws.Range("C:C").AutoFilter Field:=1, Criteria1:=Range("A3") Set new_ws = Sheets.Add(After:=ActiveSheet) ws.Range("C2").CurrentRegion.Copy new_ws.Range("A2").Paste new_ws.Name = new_ws.Range("A2").Value new_ws.Range("A1").Value = new_ws.Range("A2").Value new_ws.Range("A1").Font.Bold = True i=i+1 Wend ws.Range("A3").ClearContents Application.ScreenUpdating = True Application.Calculation = vCalc Application.EnableEvents = vEvents End Sub
Run-time error ‘1004’: Method ‘Name’ of object ‘_Worksheet’ failed
I have inherited a file to perform a task. Whenever I run the "Process" button I get this error: Run-time error ‘1004’: Method ‘Name’ of object ‘_Worksheet’ failed Pressing the Process button should do the following: Create new workbooks with a set filename Filter data from the Data sheet Copy filtered data in the created workbooks, separate sheets (renamed according to filters) I have marked the code accordingly with: 'THIS IS THE LINE THE DEBUG POINTS OUT Additional information, this code runs perfectly in a windows machine. I encounter this issue when using Mac. I am very, very new to VBA, any help and guidance are appreciated. Sub Process() Run "Openfiles" Dim x As Long, y As Long, teamtrgt As String, filetrgt As String, Celltrgt As String Dim cellrange As Long, OMtrgt As String, ws As Worksheet Windows("Macro file - extract and harvest v2.xlsm").Activate Sheets("Macro Sheet").Select x = 1 y = 0 cellrange = Range("a16").Value Do Until x = Range("c1").Value Range("D" & (x + 1)).Select Selection.Copy Range("G2").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False teamtrgt = Range("G2").Value OMtrgt = Range("h2").Value filetrgt = Range("i2").Value On Error GoTo Sheetadd Windows(filetrgt & ".xlsx").Activate Sheets(teamtrgt).Select GoTo SheetExisting Sheetadd: With ActiveWorkbook Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count)) ws.Name = teamtrgt 'THIS IS THE LINE THE DEBUG POINTS OUT End With Windows("Macro file - extract and harvest v2.xlsm").Activate Sheets("Data").Select Range("A1").Select Range(Selection, Selection.End(xlToRight)).Select Application.CutCopyMode = False Selection.Copy Windows(filetrgt & ".xlsx").Activate ActiveSheet.Paste Resume Next SheetExisting: Windows("Macro file - extract and harvest v2.xlsm").Activate Sheets("Macro Sheet").Select Celltrgt = Range("j2").Value Sheets("Data").Select Cells.Select Range("D1").Activate ActiveSheet.Range("$A$1:$P$" & cellrange).AutoFilter Field:=14, Criteria1:=teamtrgt Range("A2:P" & cellrange).Select ' Range(Selection, ActiveCell.SpecialCells(xlVisible)).Select Selection.Copy Windows(filetrgt & ".xlsx").Activate Sheets(teamtrgt).Select Range("A" & Celltrgt).Select ActiveSheet.Paste Application.CutCopyMode = False Windows("Macro file - extract and harvest v2.xlsm").Activate Sheets("Data").Select ActiveSheet.ShowAllData Sheets("Macro Sheet").Select x = x + 1 Loop End Sub
Format worksheets 5 and on, then copy&paste that info into "Sheet3" with source width and format
I am currently try to make a code that will format sheets 5 and on to module one's code and then have the program copy all the information in each of those newly formatted sheets and paste them into "sheet3" with original width and format. I have tried the "for each" and "integer" functions but can't seem to get 'the program to move past "sheet5". This sub is suppose to go through all of the sheets and and 'format them to my needs: Sub TEST2() Dim ws As Worksheet Dim wsDest As Worksheet Dim LastRow As Long Set wsDest = Sheets("sheet3") For Each ws In ActiveWorkbook.Sheets If ws.Name <> wsDest.Name And _ ws.Name <> "sheet1" And _ ws.Name <> "sheet2" And _ ws.Name <> "sheet4" Then 'code here Columns.Range("A:A,B:B,H:H,I:I").Delete Columns("A").ColumnWidth = 12 Columns("B").ColumnWidth = 17 Columns("C").ColumnWidth = 10 Columns("D").ColumnWidth = 85 Columns("E").ColumnWidth = 17 ActiveSheet.Range("D:D").WrapText = True ActiveSheet.Range("F:F").EntireColumn.Insert ActiveSheet.Range("F1").Formula = "Product ID" LastRow = Cells(Rows.Count, 1).End(xlUp).Row Range("F2:F" & LastRow).Formula = "=$G$2" ActiveSheet.Range("F2").Copy Range("F2:F" & LastRow).PasteSpecial Paste:=xlPasteValues End If Next ws End Sub This sub is meant to go to "sheet5" first and paste it into '"sheet3", than the second half of the sub should start at "sheet6" and go on 'until the end of the work sheets and then copy & paste onto "sheet3" with 'original width. Sub Test1() Dim sht As Worksheet Dim LastRow As Long Dim WS_Count As Integer Dim I As Integer Sheets("Sheet5").Select Application.CutCopyMode = False Application.Run "PERSONAL.XLSB!Module1.Del_move_insert_colmuns" Range("G2").Select ActiveCell.Offset(0, -1).Select Range(Selection, Selection.End(xlDown)).Select Range(Selection, Selection.End(xlToLeft)).Select Application.CutCopyMode = False Selection.Copy Sheets("Sheet3").Select Range("A1").Select ActiveSheet.Paste Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _ SkipBlanks:=False, Transpose:=False ActiveSheet.Range("D:D").WrapText = True WS_Count = ActiveWorkbook.Worksheets.Count ' Begin the loop For I = 5 To WS_Count 'code here Sheets("Sheet6").Select Application.Run "PERSONAL.XLSB!Module1.Del_move_insert_colmuns" Application.CutCopyMode = False Range("G2").Select ActiveCell.Offset(0, -1).Select Range(Selection, Selection.End(xlDown)).Select Range(Selection, Selection.End(xlToLeft)).SelectApplication.CutCopyMode = False Selection.Copy Sheets("Sheet3").Select Range("A1").Select 'crtl shift + down Selection.End(xlDown).Select 'moves down one cell to paste ActiveCell.Offset(1, 0).Select ActiveSheet.Paste Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _ SkipBlanks:=False, Transpose:=False Next I End Sub What im getting right now is it does "sheet5" and "sheet6" fine,but after that doesn't format and on sheet there all i get is a bunch of columns with top labeled as product ID and a bunch of 0's.
A big part of your problem is that most of your code is "assuming" that you are working with a certain worksheet when you're really working with the ActiveSheet. As an example in your TEST2 routine, you're looping through all of the worksheets in the workbook, skipping certain sheets. This part works fine. But when you want to format the other sheets, you're really only working with whatever worksheet is currently active. To fix this, you should make a habit of making sure all of your Worksheet, Range, and Cells reference are always fully qualified. So then your code works like this: ws.Columns.Range("A:A,B:B,H:H,I:I").Delete ws.Columns("A").ColumnWidth = 12 ws.Columns("B").ColumnWidth = 17 ws.Columns("C").ColumnWidth = 10 ws.Columns("D").ColumnWidth = 85 ws.Columns("E").ColumnWidth = 17 ws.Range("D:D").WrapText = True ws.Range("F:F").EntireColumn.Insert ws.Range("F1").Formula = "Product ID" LastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row ws.Range("F2:F" & LastRow).Formula = "=$G$2" ws.Range("F2").Copy ws.Range("F2:F" & LastRow).PasteSpecial Paste:=xlPasteValues Notice how every single reference is locked to the same worksheet. You can take a shortcut though, by using the With statement. But you must make sure that each reference has the . in front of it to lock it back to the With object, like this: With ws .Columns.Range("A:A,B:B,H:H,I:I").Delete .Columns("A").ColumnWidth = 12 .Columns("B").ColumnWidth = 17 .Columns("C").ColumnWidth = 10 .Columns("D").ColumnWidth = 85 .Columns("E").ColumnWidth = 17 .Range("D:D").WrapText = True .Range("F:F").EntireColumn.Insert .Range("F1").Formula = "Product ID" LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row .Range("F2:F" & LastRow).Formula = "=$G$2" .Range("F2").Copy .Range("F2:F" & LastRow).PasteSpecial Paste:=xlPasteValues End With For the rest of your code, you can make improvements by avoiding the use of Select and Activate. Consider also the tips discussed in this article that will give you excellent guidance.
VBA: Call a Macro with a Variable
I'm a beginner in VBA and i have done a script which would call different macros according to the sheet name which is assigned to a variable SheetName. I'm trying to execute the below code and I'm getting a Compile Error. Hope you guys can help me!! Sub ScrubeCareOutput() Dim SheetName, Header, PolicyNumber As String Dim CheckPoint As Integer StartTime = Now() Application.ScreenUpdating = False Application.DisplayAlerts = False Sheets("ConsolidatedData").Select Range("P:P").Cut Range("A1").Select ActiveCell.EntireColumn.Insert Range("A1").Select 'Deleting old sheet Application.StatusBar = "Calculating Loop .." Sheets("Reference").Select Range("L2").Select ActiveCell.Offset(1, 0).Select SheetName = ActiveCell.Value 'Scrubbing Output Do Until SheetName = "" Application.StatusBar = "Scrubbing " & SheetName & " Output.." Sheets(SheetName).Select Range("a1").Select If IsEmpty(Range("A2")) = False Then Range("A2").Select Header = ActiveCell.Value End If 'Deleting Headers Selection.AutoFilter Field:=1, Criteria1:=Header ActiveSheet.AutoFilter.Range.Offset(1, 0).Rows.SpecialCells(xlCellTypeVisible).Delete (xlShiftUp) ActiveSheet.AutoFilterMode = False Selection.AutoFilter Field:=1, Criteria1:="" ActiveSheet.AutoFilter.Range.Offset(1, 0).Rows.SpecialCells(xlCellTypeVisible).Delete (xlShiftUp) ActiveSheet.AutoFilterMode = False Selection.AutoFilter Field:=1, Criteria1:="©Copyright Nebo Systems, Inc." ActiveSheet.AutoFilter.Range.Offset(1, 0).Rows.SpecialCells(xlCellTypeVisible).Delete (xlShiftUp) ActiveSheet.AutoFilterMode = False Selection.AutoFilter Field:=1, Criteria1:="Powered by ECARE?" ActiveSheet.AutoFilter.Range.Offset(1, 0).Rows.SpecialCells(xlCellTypeVisible).Delete (xlShiftUp) ActiveSheet.AutoFilterMode = False Range("1:1").Delete 'Scrubbing Data Call SheetName 'Creating fields For i = 1 To 4 ActiveCell.EntireColumn.Insert Next Range("A1").Select ActiveCell.Value = "Account Number" ActiveCell.Offset(0, 1).Select ActiveCell.Value = "Mnemonic" ActiveCell.Offset(0, 1).Select ActiveCell.Value = "Begin Date" ActiveCell.Offset(0, 1).Select ActiveCell.Value = "End Date" 'Formulating data ActiveCell.Offset(1, -3).Select ActiveCell.Value = "=VLOOKUP(E2,ConsolidatedData!$A:$S,3,0)" ActiveCell.Offset(0, 1).Select ActiveCell.Value = "=VLOOKUP(E2,ConsolidatedData!$A:$S,16,0)" ActiveCell.Offset(0, 1).Select ActiveCell.Value = "=VLOOKUP(E2,ConsolidatedData!$A:$S,17,0)" ActiveCell.Offset(0, 1).Select ActiveCell.Value = "=VLOOKUP(E2,ConsolidatedData!$A:$S,18,0)" ActiveCell.Offset(0, 1).Select Selection.End(xlDown).Select ActiveCell.Offset(0, -4).Select Range(Selection, Selection.End(xlUp)).Select Range(Selection, Selection.Offset(0, 3)).Select Selection.FillDown Selection.Copy Selection.PasteSpecial xlPasteValues Range("a1").Select 'Formatting data Application.StatusBar = "Formatting " & SheetName & " Output.." With ActiveSheet .Cells.Font.Name = "Calibri" .Cells.Font.Size = "10" End With Range("1:1").Select Selection.Font.Bold = True Range("A1").Select 'Save data ActiveWorkbook.Saved = True Sheets("Reference").Select ActiveCell.Offset(1, 0).Select SheetName = ActiveCell.Value Else Sheets("Reference").Select ActiveCell.Offset(1, 0).Select SheetName = ActiveCell.Value End If Loop Sheets("UB92Monitor").Select 'Confirmation message ActiveWorkbook.Save EndTime = Format((Now() - StartTime), "HH:MM:SS") Application.StatusBar = False MsgBox "Data scrubbed successfully in " & EndTime, vbOKOnly, "Data Scrubbing Status" End Sub
How to enter data from a form on one sheet onto a log on another sheet
So I'm trying to figure out how I can setup a macro that will take the data that I enter into a form on one sheet then log it into a log in another sheet. It will log it but my big problem is that it needs to go to the next line and I can't quite figure out the code for it. Here is what my code looks like: Sub Appt() ' ' Appt Macro ' ' Range("E4").Select Selection.Copy Sheets("Appointments").Select Range("G7").Select ActiveSheet.Paste Sheets("Data Entry").Select Range("E6").Select Application.CutCopyMode = False Selection.Copy Sheets("Appointments").Select Range("D7").Select ActiveSheet.Paste Sheets("Data Entry").Select Range("E8").Select Application.CutCopyMode = False Selection.Copy Sheets("Appointments").Select Range("E7").Select ActiveSheet.Paste Sheets("Data Entry").Select Range("E10").Select Application.CutCopyMode = False Selection.Copy Sheets("Appointments").Select Range("F7").Select ActiveSheet.Paste Sheets("Data Entry").Select Range("E12").Select Application.CutCopyMode = False Selection.Copy Sheets("Appointments").Select Range("H7").Select ActiveSheet.Paste Sheets("Data Entry").Select Range("E4").Select Application.CutCopyMode = False Selection.ClearContents Range("E6").Select Selection.ClearContents Range("E8").Select Selection.ClearContents Range("E10").Select Selection.ClearContents Range("E12").Select Selection.ClearContents End Sub
To get the next empty row on Sheets("Appointments") you would use this formula to get the row number: tRw = Sheets("Appointments").Range("D" & Rows.count).End(xlUp).Offset(1).Row This assumes that there is nothing in column D below what you are pasting. It is apparent that you used the macro recorder, and this is a great way to learn. But using the .select so much will slow things down and is unneeded. To get around that declare the sheets as variables and then one line for each copy paste is needed. Sub APPT() Dim oWs As Worksheet Dim tWs As Worksheet Dim tRw As Long Set oWs = Sheets("Data Entry") Set tWs = Sheets("Appointments") tRw = tWs.Range("D" & Rows.count).End(xlUp).Offset(1).Row With oWs .Range("E4").copy tWs.Range("G" & tRw) .Range("E6").copy tWs.Range("D" & tRw) .Range("E8").copy tWs.Range("E" & tRw) .Range("E10").copy tWs.Range("F" & tRw) .Range("E12").copy tWs.Range("H" & tRw) .Range("E4").ClearContents .Range("E6").ClearContents .Range("E8").ClearContents .Range("E10").ClearContents .Range("E12").ClearContents End With End Sub For other methods of finding the next row look at Siddharth Rout's answer here. And as BruceWayne stated in his comment, this is a great reference as to why/how to avoid using .select
It's best to avoid the user's clipboard and to assign the values directly: Sub Appt() Dim n&, v v = [transpose(offset('data entry'!e4,{0;2;4;6;8},))] With Sheets("appointments") n = .Range("d" & .Rows.Count).End(xlUp).Row .[g1].Offset(n) = v(1) .[d1].Offset(n) = v(2) .[e1].Offset(n) = v(3) .[f1].Offset(n) = v(4) .[h1].Offset(n) = v(5) End With Sheets("data entry").Range("e4,e6,e8,e10,e12").ClearContents End Sub