Related
I am quite inexperienced with vba and I am trying to make a code.
I am running it and it works fine but it is too slow when I have many rows. And with slow I mean that it could be running for minutes. I didnt waited till the end yet.
I would be very grateful for some help
Sub importart_lv()
Application.ScreenUpdating = False
Dim CL As Range
Dim rng As Range: Set rng = ActiveSheet.Range("A1:A2500")
For Each Cell In rng.Cells
If Cell.Value = "Position" Then
Cell.Offset(0, 6).Select
Worksheets("Bausteine").Activate
Range("G9:U9").Select
Selection.Copy
Worksheets("LV-Importieren").Activate
Selection.Insert
FindReplace
End If
'Cell.Offset(0, 11).Value = IIf(InStr(1, Cell, "Position"), "True", "")
Next
Application.CutCopyMode = False
ActiveSheet.Range("J1").Select
Worksheets("Bausteine").Activate
Range("G8:U8").Select
Selection.Copy
Worksheets("LV-Importieren").Activate
Selection.Insert
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
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
I am creating a inventory control workbook and I am looking to have a column with the words "Order Placed" once I have clicked on the button to place order. I want to make sure that it is based on the right criteria. Currently in I am using a formula to place that text but once I clear the order form that goes away because its using an index match function within an if statement.
This is my current Order Placed Sub
Sub orderPlaced()
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Application.ScreenUpdating = False
Dim startCell As range, lastRow As Long, lastCol As Long, ws As Worksheet
Set ws = Sheets("Re-Order List")
'This part Copies the requested information
Sheets("Re-Order List").Select
range("A1").Select
Application.CutCopyMode = False
Selection.Copy
'This part Pastes the requested information in the history
Sheets("Order History").Select
Selection.End(xlDown).Select
range("A65536").Select
Selection.End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteAllExceptBorders, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'This part Copies the requested information
Sheets("Re-Order List").Select
Set startCell = range("A3")
lastRow = ws.Cells(ws.Rows.Count, startCell.Column).End(xlUp).Row
lastCol = ws.Cells(startCell.Row, ws.Columns.Count).End(xlToLeft).Column
ws.range(startCell, ws.Cells(lastRow, lastCol)).Select
Application.CutCopyMode = False
Selection.Copy
'This part Pastes the requested information in the history
Sheets("Order History").Select
Selection.End(xlDown).Select
range("A65536").Select
Selection.End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'This part adds orderplaced below order form
Sheets("Order History").Select
range("A65536").Select
Selection.End(xlUp).Offset(2, 0).Select
With Selection
.Value = "Order Placed :"
.HorizontalAlignment = xlRight
End With
'This part adds the date
Sheets("Order History").Select
range("B65536").Select
Selection.End(xlUp).Offset(2, 0).Select
With Selection
.Value = Date
.NumberFormat = "dd/mmm/yyyy"
.HorizontalAlignment = xlLeft
End With
'this will set the comment in inventory to ordered
'*************************
'NEEDED CODE WILL GO HERE
'*************************
Sheets("Inventory").Select
range("K6:K400").ClearContents
'This part Clears the order form
Sheets("Re-Order List").Select
range("A4:D5000").ClearContents
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
This is my Add to Order Sub
Sub add2Order()
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Application.ScreenUpdating = False
Dim C As range, rng As range, D As range, Rng1 As range, mnrng As range, acrng As range
Sheets("Inventory").Select
Set rng = range("K6:K400")
For Each C In rng
If InStr(1, C, "X") > 0 Then
'first select material number and name
Set mnrng = range(C.Offset(0, -9), C.Offset(0, -8))
Application.CutCopyMode = False
mnrng.Copy
'paste in reorder sheet
Sheets("Re-Order List").Select
Selection.End(xlDown).Select
range("A400").Select
Selection.End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = True
End If
Next
Sheets("Inventory").Select
Set Rng1 = range("K6:K400")
For Each D In Rng1
If InStr(1, D, "X") > 0 Then
'Second select amount and cost
Set acrng = range(D.Offset(0, -2), D.Offset(0, -1))
Application.CutCopyMode = False
acrng.Copy
'paste in reorder sheet
Sheets("Re-Order List").Select
Selection.End(xlDown).Select
range("C400").Select
Selection.End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = True
End If
Next
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Code that is close is as follows
Sub test()
'
Dim w1 As Worksheet, w2 As Worksheet
Dim C As range, a As range
Set w1 = Sheets("Inventory")
Set w2 = Sheets("Re-Order List")
With w1
For Each C In .range("$A$6:$A$400")
Set a = w2.Columns(1).Find(C.Value, LookAt:=xlWhole)
If Not a Is Nothing Then
If IsEmpty(.Cells(C.Row, 1)) And .Cells(C.Row, 1).Value = w2.Cells(a.Row, 1) Then
w1.Cells(C.Row, 12).Value = "Order Placed"
End If
End If
Next C
End With
End Sub
This is the last piece to this puzzle to get it how I want it to work, I know for sure I will only have less than 400 materials to manage and if that grows I can update then but any help would be fantastic.
This is the drive link for the actual sheet
This isn't an answer until you tell us exactly where do you want to place the information
I refactored your code so you don't use select and added some pseudo code that may give you a hint
Public Sub orderPlaced()
' Turn off stuff to speed up process
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Application.ScreenUpdating = False
'This part Copies the requested information
Dim reorderListSheet As Worksheet
Set reorderListSheet = ThisWorkbook.Worksheets("Re-Order List")
reorderListSheet.Range("A1").Copy
'This part Pastes the requested information in the history
Dim orderHistorySheet As Worksheet
Set orderHistorySheet = ThisWorkbook.Worksheets("Order History")
orderHistorySheet.Cells(orderHistorySheet.Rows.Count, "A").End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteAllExceptBorders, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
' Find last row in reorder sheet
Dim reorderLastRow As Long
reorderLastRow = reorderListSheet.Cells(reorderListSheet.Rows.Count, "A").End(xlUp).Row
' Find last column in reorder sheet
Dim reorderLastColumn As Long
reorderLastColumn = reorderListSheet.Cells(3, reorderListSheet.Columns.Count).End(xlToLeft).Column
'This part Copies the requested information
Dim reorderStartCell As Range
Set reorderStartCell = reorderListSheet.Range("A3")
reorderListSheet.Range(reorderStartCell, reorderListSheet.Cells(reorderLastRow, reorderLastColumn)).Copy
'This part Pastes the requested information in the history
Dim orderHistoryLastRow As Long
orderHistoryLastRow = orderHistorySheet.Cells(orderHistorySheet.Rows.Count, "A").End(xlUp).Row
orderHistorySheet.Range("A" & orderHistoryLastRow).Offset(1, 0).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
'This part adds orderplaced below order form
With orderHistorySheet.Range("A" & orderHistoryLastRow).Offset(3, 0)
.Value = "Order Placed :"
.HorizontalAlignment = xlRight
End With
'This part adds the date
With orderHistorySheet.Range("B" & orderHistoryLastRow).Offset(3, 0)
.Value = Date
.NumberFormat = "dd/mmm/yyyy"
.HorizontalAlignment = xlLeft
End With
'this will set the comment in inventory to ordered
'*************************
' THIS NEXT IS PSEUDO CODE BECAUSE I COULDN'T UNDERSTAND YOUR REQUIREMENT
Dim targetCell As Range
Set targetCell = orderHistorySheet.Range("A1").Value = "=IFERROR(IF(INDEX(Table2[Material Number],MATCH(C6,Table2[Name],0)) = [#[Material Number]],""Order Placed"",""""),"""")"
' turn that into a value
targetCell.Value = targetCell.Value
'*************************
' Clear inventory sheet
Dim inventorySheet As Worksheet
Set inventorySheet = ThisWorkbook.Worksheets("Inventory")
inventorySheet.Range("K6:K400").ClearContents
'This part Clears the order form
reorderListSheet.Range("A4:D5000").ClearContents
' Turn on stuff again
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
I FIGURED IT OUT!!!!!!!!
'this will set the comment in inventory to ordered
'*************************
Dim r1 As range
Dim r2 As range
Dim cell As range
Set r1 = Sheets("Inventory").range("B6:B400")
Set r2 = Sheets("Re-Order List").range("A4:A400")
For Each cell In r1
If IsError(Application.Match(cell, r2, 0)) Then
cell.Offset(, 12) = ""
Else
cell.Offset(, 12) = "Order Placed"
' If found I need the value from Sheet2 that is in Col B of the matching row.
End If
Next cell
'*************************
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.
I have 5 worksheets in my workbook(Table 1, Table 2, Table 3, Table 4 and Combined). The main Worksheet is the one I am trying to combine the other 4 into and place the data on the next blank line.
I have been googling different code solutions for weeks to no avail.
When I step through the macro and use the loop (do while, for and Each), it is only looping through Table 1 perfectly. But I cannot get it to loop through Sheets 2-4.
I think I know where my issue is, but in my weeks of googling, I still can't find the solution. I think the issue is on the line where it reads "Sheets("Table 1").Select". Because the code seems to work till it gets to that line. Then it "of course" goes back to Table 1.
This is a test group for a much larger project. I have to pull information from 500 documents that are all set up in the exact same position, but I have to get these 4 to work first.
'I have tried this:
Dim iSheet As Object
For Each iSheet In ThisWorkbook.Sheets
MsgBox iSheet.Name
Next iSheet
'And I tried this:
Dim useWorkSheet As Worksheet
Dim totalWorkSheet As Worksheet
Dim tableAsNumeric As Integer
Dim startingTable As Integer
'For Each Current In Worksheets
'Table Name = Table in Worksheets
startingTable = 1
Set totalWorkSheet = ActiveWorkbook.Sheets("Table 1")
For Each useWorkSheet In ActiveWorkbook.Worksheets
tableAsNumeric = Val(useWorkSheet.Name)
'If tableAsNumeric >= startingTable Then
'Do While I >= Worksheet("Table 1")
'I = I + 1
'I have also tried a for loop and as many others as there are out on the net... Nothing works...
This is the code I need help with:
Sub TFRdataExtract()
'
' TFRdataExtract Macro
' Extract Data from Individual TFR files to the combined file.
'
' Keyboard Shortcut: Ctrl+e
'
Dim iSheet As Object
For Each iSheet In ThisWorkbook.Sheets
MsgBox iSheet.Name
Sheets("Table 1").Select
Range("AB1").Select
ActiveCell.FormulaR1C1 = "=MID(RC[-27], 7,100)"
Range("AC1").Select
ActiveCell.FormulaR1C1 = "=MID(RC[-24], 14,100)"
Range("AD1").Select
ActiveCell.FormulaR1C1 = "=MID(RC[-19],23,100)"
Range("AE1").Select
ActiveCell.FormulaR1C1 = "=MID(RC[-10],22,100)"
Range("AF1").Select
ActiveCell.FormulaR1C1 = "=MID(R[1]C[-31], 23,100)"
Range("AG1").Select
ActiveCell.FormulaR1C1 = "=MID(R[1]C[-16], 10,100)"
Range("AH1").Select
ActiveCell.FormulaR1C1 = "=MID(R[1]C[-13],13,100)"
Range("AI1").Select
ActiveCell.FormulaR1C1 = "=MID(R[2]C[-34],22,100)"
Range("AJ1").Select
ActiveCell.FormulaR1C1 = "=MID(R[2]C[-25],18,100)"
Range("AK1").Select
ActiveCell.FormulaR1C1 = "=MID(R[2]C[-16],21,100)"
Range("AL1").Select
ActiveCell.FormulaR1C1 = "=MID(R[3]C[-37],21,100)"
Range("AM1").Select
ActiveCell.FormulaR1C1 = "=MID(R[3]C[-28],17, 100)"
Range("AN1").Select
ActiveCell.FormulaR1C1 = "=MID(R[3]C[-21],34,100)"
Range("AO1").Select
ActiveCell.FormulaR1C1 = "=MID(R[4]C[-40],28,100)"
Range("AP1").Select
ActiveCell.FormulaR1C1 = "=MID(R[4]C[-35], 7,100)"
Range("AQ1").Select
ActiveCell.FormulaR1C1 = "=MID(R[4]C[-34],10,100)"
Range("AR1").Select
ActiveCell.FormulaR1C1 = "=MID(R[4]C[-29],10,100)"
Range("AS1").Select
ActiveCell.FormulaR1C1 = "=MID(R[4]C[-21],22,100)"
Range("AT1").Select
ActiveCell.FormulaR1C1 = "=MID(R[5]C[-45],26,100)"
Range("AU1").Select
ActiveCell.FormulaR1C1 = "=MID(R[6]C[-46],18,100)"
Range("AV1").Select
ActiveCell.FormulaR1C1 = "=MID(R[6]C[-37],55,100)"
Range("AW1").Select
ActiveCell.FormulaR1C1 = "=MID(R[7]C[-48],36,100)"
Range("AX1").Select
ActiveCell.FormulaR1C1 = "=MID(R[7]C[-39],30,100)"
Range("AY1").Select
ActiveCell.FormulaR1C1 = "=MID(R[7]C[-28],12,100)"
Range("AZ1").Select
ActiveCell.FormulaR1C1 = "=MID(R[8]C[-51],20,100)"
Range("BA1").Select
ActiveCell.FormulaR1C1 = "=MID(R[8]C[-35],12,100)"
Range("BB1").Select
ActiveCell.FormulaR1C1 = "=MID(R[8]C[-31],20,100)"
Range("BC1").Select
ActiveCell.FormulaR1C1 = "=MID(R[9]C[-54],25,100)"
Range("BD1").Select
ActiveCell.FormulaR1C1 = "=MID(R[9]C[-45],15,100)"
Range("BE1").Select
ActiveCell.FormulaR1C1 = "=MID(R[9]C[-39],23,100)"
Range("BF1").Select
ActiveCell.FormulaR1C1 = "=MID(R[10]C[-57],17,100)"
Range("BG1").Select
ActiveCell.FormulaR1C1 = "=MID(R[10]C[-56],17,100)"
Range("BH1").Select
ActiveCell.FormulaR1C1 = "=MID(R[10]C[-52],13,100)"
Range("BI1").Select
ActiveCell.FormulaR1C1 = "=MID(R[10]C[-42],14,100)"
Range("BJ1").Select
ActiveCell.FormulaR1C1 = "=MID(R[10]C[-38],15,100)"
Range("BK1").Select
ActiveCell.FormulaR1C1 = "=MID(R[12]C[-62],11,100)"
Range("BL1").Select
ActiveCell.FormulaR1C1 = "=MID(R[12]C[-62],12,100)"
Range("BM1").Select
ActiveCell.FormulaR1C1 = "=MID(R[12]C[-59],10,100)"
Range("BN1").Select
ActiveCell.FormulaR1C1 = "=MID(R[12]C[-57], 7,100)"
Range("BO1").Select
ActiveCell.FormulaR1C1 = "=MID(R[12]C[-55],7,100)"
Range("BP1").Select
ActiveCell.FormulaR1C1 = "=MID(R[12]C[-55],11,100)"
Range("BQ1").Select
ActiveCell.FormulaR1C1 = "=MID(R[12]C[-53],12,100)"
Range("BR1").Select
ActiveCell.FormulaR1C1 = "=MID(R[12]C[-50],8,100)"
Range("BS1").Select
ActiveCell.FormulaR1C1 = "=MID(R[12]C[-47],12,100)"
Range("BT1").Select
ActiveCell.FormulaR1C1 = "=MID(R[13]C[-71],10,100)"
Range("BU1").Select
ActiveCell.FormulaR1C1 = "=MID(R[13]C[-71],20,100)"
Range("BV1").Select
ActiveCell.FormulaR1C1 = "=MID(R[13]C[-66],10,100)"
Range("BW1").Select
ActiveCell.FormulaR1C1 = "=MID(R[13]C[-63],10,100)"
Range("BX1").Select
ActiveCell.FormulaR1C1 = "=MID(R[13]C[-62],8,100)"
Range("BY1").Select
ActiveCell.FormulaR1C1 = "=MID(R[13]C[-61],7,100)"
Range("BZ1").Select
ActiveCell.FormulaR1C1 = "=MID(R[13]C[-59],9,100)"
Range("CA1").Select
ActiveCell.FormulaR1C1 = "=MID(R[13]C[-57],10,100)"
Range("CB1").Select
ActiveCell.FormulaR1C1 = "=MID(R[13]C[-55],13,100)"
Range("CC1").Select
ActiveCell.FormulaR1C1 = "=MID(R[14]C[-80],12,100)"
Range("CD1").Select
ActiveCell.FormulaR1C1 = "=MID(R[14]C[-80],13,100)"
Range("CE1").Select
ActiveCell.FormulaR1C1 = ""
Range("CE1").Select
ActiveCell.FormulaR1C1 = "=MID(R[14]C[-77],15,100)"
Range("CF1").Select
ActiveCell.FormulaR1C1 = "=MID(R[14]C[-72],7,100)"
Range("CG1").Select
ActiveCell.FormulaR1C1 = "=MID(R[14]C[-71],13,100)"
Range("CH1").Select
ActiveCell.FormulaR1C1 = "=MID(R[14]C[-67],14,100)"
Range("CI1").Select
ActiveCell.FormulaR1C1 = "=MID(R[14]C[-62],7,100)"
Range("CJ1").Select
ActiveCell.FormulaR1C1 = "=MID(R[15]C[-87],13,100)"
Range("CK1").Select
ActiveCell.FormulaR1C1 = "=MID(R[15]C[-85],15,100)"
Range("CL1").Select
ActiveCell.FormulaR1C1 = "=MID(R[15]C[-82],11,100)"
Range("CM1").Select
ActiveCell.FormulaR1C1 = "L16,11,100)"
Range("CN1").Select
ActiveCell.FormulaR1C1 = "=MID(R[15]C[-73],15,100)"
Range("CO1").Select
ActiveCell.FormulaR1C1 = "=MID(R[15]C[-68],8,100)"
Range("CP1").Select
ActiveCell.FormulaR1C1 = "=MID(R[17]C[-93],19,100)"
Range("CQ1").Select
ActiveCell.FormulaR1C1 = "=MID(R[17]C[-80],22,100)"
Range("CR1").Select
ActiveCell.FormulaR1C1 = "=MID(R[18]C[-95],27,100)"
Range("CS1").Select
ActiveCell.FormulaR1C1 = "=MID(R[18]C[-82],18,100)"
Range("CT1").Select
ActiveCell.FormulaR1C1 = "=MID(R[19]C[-97],45,100)"
Range("CU1").Select
ActiveCell.FormulaR1C1 = "=MID(R[19]C[-89],22,100)"
Range("CV1").Select
ActiveCell.FormulaR1C1 = "=MID(R[19]C[-81],49,100)"
Range("CW1").Select
ActiveCell.FormulaR1C1 = "=MID(R[20]C[-91],21,100)"
Range("CX1").Select
ActiveCell.FormulaR1C1 = "=MID(R[21]C[-101],16,100)"
Range("CY1").Select
ActiveCell.FormulaR1C1 = "=MID(22,27,100)"
Range("CZ1").Select
ActiveWindow.SmallScroll Down:=-3
Range("CY1").Select
ActiveWindow.SmallScroll ToRight:=-50
Range("AB1:CY1").Select
Range("CY1").Activate
Selection.Copy
Sheets("Combined").Select
Rows("2:2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Next iSheet
End Sub
I need to loop through all 4 Worksheets and paste data onto the Combined file into the next blank line.
try this:
For sht = 1 To Sheets.Count
Debug.Print sht
'your code here
Sheets(sht).Activate'or
Sheets(Sheets(sht).Name).Activate
Next
Perhaps this will help. Commented to help understand what is going on.
'// Modify as desired, like to empty rows/columns.
Private Function GetRangeToCopy(zWorksheet As Worksheet) As Range
Set GetRangeToCopy= zWorksheet.UsedRange
End Function
'// Modify to add spacing or whatnot.
Private Function GetDestinationRange(zDestinationWorksheet As Worksheet, zRowCount As Long, zColumnCount As Long) As Range
Dim zReturnRange As Range
Dim zNewRowIndex As Long
Let zNewRowIndex = zDestinationWorksheet.UsedRange.End.Row + 3 '// Increase to add more rows between inserts.
Set zReturnRange = zDestinationWorksheet.
Set GetDestinationRange = zReturnRange
End Function
'// Copies a range to the destination range.
Private Sub CopyRange(zSourceRange As Range, zDestinationRange As Range)
'// This is where copying styles and such would be done.
'// We will just call copy for simplicity.
'// Clear.
Call zDestinationRange.Clear
'// Copy.
Call zSourceRange.Copy(zDestinationRange)
End Sub
'// Copy worksheets to a destination worksheet.
'// Destination worksheet can be a worksheet loaded into a different workbook altogether.
Public Sub CopyWorksheetsTo(zDestinationWorksheet As Worksheet, zClearDestinationWorksheet As Boolean = False _
zPopupCurrentWorksheet As Boolean = True)
Dim zCurrentWorksheet As Worksheet
Dim zCurrentWorksheet_Var As Variant
Dim zRangeToCopy As Range
Dim zDestinationRange As Range
'// Clear destination.
If (zClearDestinationWorksheet) Then
Call zDestinationWorksheet.UsedRange.Clear
End If
'// Cycle through each worksheet in the workbook.
ForEach zCurrentWorksheet_Var in Worksheets
'// this allow us the Intellisense while coding.
Set zCurrentWorksheet = zCurrentWorksheet_Var
'// Make sure this isn't the destination worksheet.
If (zCurrentWorksheet.Name <> zDestinationWorksheet.Name) Then
'// Popup worksheet name.
If (zPopupCurrentWorksheet) Then
Call MsgBox(zCurrentWorksheet.Name)
End If
'// Get range to be copied.
Set zRangeToCopy = GetRangeToCopy(zCurrentWorksheet)
'// Get destination range.
Set zDestinationRange = GetDestinationRange(zDestinationWorksheet)
'// Copy range.
Call CopyRange(zRangeToCopy, zDestinationRange)
End If
Next xCurrentWorksheet_Var
End Sub
To loop on all Worksheets
Example
Option Explicit
Public Sub Example()
' // Declare your Variables
Dim Sht As Worksheet
With Application
.ScreenUpdating = False
.EnableEvents = False
.DisplayAlerts = False
End With
'// loop on all sheets
For Each Sht In Worksheets
Debug.Print Sht.Name
'Do something
Next
With Application
.ScreenUpdating = True
.EnableEvents = True
.DisplayAlerts = True
End With
End Sub
Try this code snippet. I am already using this in a macro.
Sub Combine()
' ensure you have placed the "combined" worksheet as the first sheet
'variable declaration
Dim J As Integer
'copying header row from second sheet
Sheets(2).Activate
Range("A1").EntireRow.Select
Selection.Copy Destination:=ThisWorkbook.Sheets("combined").Range("A1")
'copying data from other sheets
For J = 2 To 4
Sheets(J).Activate
Range("A1").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=ThisWorkbook.Sheets("combined").Range("A65536")_
.End(xlUp) (2)
Next
ThisWorkbook.Worksheets("combined").Columns.AutoFit
End Sub
In my opinion you should try to avoid .Select. Try:
Option Explicit
Sub test()
Dim ws As Worksheet
With ThisWorkbook
For Each ws In .Worksheets
If ws.Name = "Table 1" Then
With ws
.Range("AB1").FormulaR1C1 = "=MID(RC[-27], 7,100)"
.Range("AC1").FormulaR1C1 = "=MID(RC[-24], 14,100)"
.Range("AD1").FormulaR1C1 = "=MID(RC[-19],23,100)"
.Range("AE1").FormulaR1C1 = "=MID(RC[-10],22,100)"
.Range("AF1").FormulaR1C1 = "=MID(R[1]C[-31], 23,100)"
'....... Add more formulas
.Range("AB1:CY1").Copy
End With
With .Worksheets("Combined").Range("A2")
.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End With
End If
Next ws
End With
End Sub
This should work:
Sub TFRdataExtract()
Dim iSheet As Worksheet, rngCopy As Range
For Each iSheet In ThisWorkbook.WorkSheets
If iSheet.Name Like "Table*" Then
With iSheet '<< no need to activate!
.Range("AB1").FormulaR1C1 = "=MID(RC[-27], 7,100)" '<< no need to select!
.Range("AC1").FormulaR1C1 = "=MID(RC[-24], 14,100)"
.Range("AD1").FormulaR1C1 = "=MID(RC[-19],23,100)"
'etc etc
Set rngCopy = .Range("AB1:CY1")
End with
'assign values directly
With ThisWorkbook.Sheets("Combined").Range("A2")
.Resize(rngCopy.Rows.Count, _
rngCopy.Columns.Count).Value = rngCopy.Value
End with
End If 'EDIT - added
Next iSheet
End Sub