VBA: Call a Macro with a Variable - excel

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

Related

Trying to Copy rows selected with checkboxes to another workbook

I am a bit stuck: I have the below code for a spreadsheet which copies rows, selected with a checkbox, into a second sheet.
I now need to amend this code so that the copied rows are pasted into another workbook on a specific sheet.
I have tried Workbooks("").Worksheets("") and also using the whole C drive path but always get a run-time 9, subscript out of range error. I haven't had any luck in finding a solution online.
Both workbooks are saved on my desktop currently for ease:
Sub CopyRows()
For Each chkbx In ActiveSheet.CheckBoxes
If chkbx.Value = 1 Then
For r = 1 To Rows.Count
If Cells(r, 1).Top = chkbx.Top Then
With Worksheets("Sheet2")
LRow = .Range("A" & Rows.Count).End(xlUp).Row + 1
.Range("A" & LRow & ":R" & LRow) = _
Worksheets("Sheet1").Range("A" & r & ":R" & r).Value
End With
Exit For
End If
Next r
End If
Next
End Sub
This recorded macro takes the data to where it needs to go:
Sub Transfer()
'
' Transfer Macro
'
'
Range("K2").Select
Selection.Copy
Windows("Destination.xls").Activate
Range("E7:E8").Select
ActiveSheet.Paste
Windows("WIP - Live.xlsm").Activate
Range("B2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Destination.xls").Activate
Range("E9").Select
ActiveSheet.Paste
Windows("WIP - Live.xlsm").Activate
Range("M2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Destination.xls").Activate
Range("E10").Select
ActiveSheet.Paste
Windows("WIP - Live.xlsm").Activate
Range("G2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Destination.xls").Activate
Range("E11").Select
ActiveSheet.Paste
Windows("WIP - Live.xlsm").Activate
Range("N2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Destination.xls").Activate
Range("E12").Select
ActiveSheet.Paste
Windows("WIP - Live.xlsm").Activate
Range("E2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Destination.xls").Activate
Range("E13").Select
ActiveSheet.Paste
Windows("WIP - Live.xlsm").Activate
Range("A2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Destination.xls").Activate
Range("E14").Select
ActiveSheet.Paste
Windows("WIP - Live.xlsm").Activate
Range("S2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Destination.xls").Activate
Range("E15").Select
ActiveSheet.Paste
Windows("WIP - Live.xlsm").Activate
Range("J2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Destination.xls").Activate
Range("E16").Select
ActiveSheet.Paste
Windows("WIP - Live.xlsm").Activate
Range("I2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Destination.xls").Activate
Range("E17").Select
ActiveSheet.Paste
Windows("WIP - Live.xlsm").Activate
Range("C2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Destination.xls").Activate
Range("E20").Select
ActiveSheet.Paste
Windows("WIP - Live.xlsm").Activate
Range("D2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Destination.xls").Activate
Range("E21").Select
ActiveSheet.Paste
Windows("WIP - Live.xlsm").Activate
End Sub
Code with error at destination workbook:
Sub CopyRows()
For Each chkbx In ActiveSheet.CheckBoxes
If chkbx.Value = 1 Then
For r = 1 To Rows.Count
If Cells(r, 1).Top = chkbx.Top Then
With Workbooks("Destination").Sheets("Sheet2")
LRow = .Range("A" & Rows.Count).End(xlUp).Row + 1
.Range("A" & LRow & ":R" & LRow) = _
Worksheets("Sheet1").Range("A" & r & ":R" & r).Value
End With
Exit For
End If
Next r
End If
Next
End Sub
Solved: I have managed to get it working with the below code:
Sub CopyRows()
For Each chkbx In ActiveSheet.CheckBoxes
If chkbx.Value = 1 Then
For r = 1 To Rows.Count
If Cells(r, 1).Top = chkbx.Top Then
With Workbooks("Destination.xlsm").Sheets("Details")
LRow = .Range("A" & Rows.Count).End(xlUp).Row + 1
.Range("A" & LRow & ":U" & LRow) = _
Worksheets("Sheet2").Range("A" & r & ":U" & r).Value
End With
Exit For
End If
Next r
End If
Next
End Sub
The error was being caused by the Sheet 2 name in the destination workbook. I had to amend the name to details and it started working. Frustratingly simple for how long I spent on it!
Many Thanks to ed2 and norie for the replies and help. It is much appreciated.
Try this:
First:
Change
Worksheets("Sheet1").Range("A" & r & ":R" & r).Value
to
Workbooks("WIP - Live.xlsm").Sheets("Sheet1").Range("A" & r & ":R" & r).Value
Then:
Change
With Worksheets("Sheet2")
to
Workbooks("Destination.xls").Sheets("Sheet2")
This assumes that both workbooks are already open when the macro is run. If not, you will need code to open one or both of them.

Excel Macro Automating Cells and Columns editing

Hi I am trying to automate insertion of columns and moving of data within a certain part of a spreadsheet.
Currently What the Macro is
Sub Macro1()
'
' Macro1 Macro
'
'
Rows("6:9").Select
Selection.Insert Shift:=xlDown
Range("F5").Select
Selection.Cut
Range("E6").Select
ActiveSheet.Paste
Range("G5").Select
Selection.Cut
Range("E7").Select
ActiveSheet.Paste
Range("H5").Select
Selection.Cut
Range("E8").Select
ActiveSheet.Paste
Range("I5").Select
Selection.Cut
Range("E9").Select
ActiveSheet.Paste
Range("A5").Select
Selection.Copy
Range("D6:D9").Select
ActiveSheet.Paste
Range("C6").Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "10000"
Range("C7").Select
ActiveCell.FormulaR1C1 = "20000"
Range("C8").Select
ActiveCell.FormulaR1C1 = "30000"
Range("C9").Select
ActiveCell.FormulaR1C1 = "40000"
Range("C10").Select
End Sub
How do i change it so that it will update dynamically when i select a new set of rows again ?
With the following edited macro you can select any number of rows to be inserted and with inputbox
Option Explicit
Sub Macro1()
Dim newRows As Range, newRowsAddress As String, previousRow As Range
Dim ColumnLetter As String, i As Long, j As Long
On Error Resume Next
Set newRows = Application.InputBox("Select rows to insert", "New Rows", , , , , , 8)
If newRows Is Nothing Then Exit Sub
On Error GoTo 0
Set previousRow = newRows.Offset(-1).Resize(1, Columns.Count)
newRowsAddress = newRows.Address
' Rows("6:9").Select
' Selection.Insert Shift:=xlDown
' Range("F5").Select
' Selection.Cut
' Range("E6").Select
' ActiveSheet.Paste
' Range("G5").Select
' Selection.Cut
' Range("E7").Select
' ActiveSheet.Paste
' Range("H5").Select
' Selection.Cut
' Range("E8").Select
' ActiveSheet.Paste
' Range("I5").Select
' Selection.Cut
' Range("E9").Select
' ActiveSheet.Paste
newRows.Insert Shift:=xlDown
Set newRows = Range(newRowsAddress)
ColumnLetter = Split(Cells(1, 5 + newRows.Rows.Count).Address, "$")(1)
newRows.Columns("E:E").Value = Application.Transpose(previousRow.Columns("F:" & ColumnLetter).Value)
' Range("A5").Select
' Selection.Copy
' Range("D6:D9").Select
' ActiveSheet.Paste
newRows.Columns("D:D").Value = Application.Transpose(previousRow.Columns("A:A").Value)
' Range("C6").Select
' Application.CutCopyMode = False
' ActiveCell.FormulaR1C1 = "10000"
' Range("C7").Select
' ActiveCell.FormulaR1C1 = "20000"
' Range("C8").Select
' ActiveCell.FormulaR1C1 = "30000"
' Range("C9").Select
' ActiveCell.FormulaR1C1 = "40000"
' Range("C10").Select
j = 1
For i = newRows.Rows(1).Row To newRows.Rows(newRows.Rows.Count).Row
Range("C" & i) = j * 10000
j = j + 1
Next i
End Sub
Two New Rows
or Seven New Rows
Try using the "Use Relative References" option when recording your macro.

I can't convert data into appropriate format

I created auto-populating offset function to add data into my list. Now I need to convert the inserted data into the same format as cells above. I reckon there is some shorter code to do this. Mine's not working anyway. The data are scattered all over the worksheet.
Option Explicit
Sub data_entry()
Application.ScreenUpdating = False
Dim ItemNumber As String
Dim ItemType As String
Dim Issues As String
Dim InventoryValue As String
ItemNumber = InputBox("Please enter Item Number", "Item Number", "Type here")
ItemType = InputBox("Please enter Item Type", "Item Type", "Type here")
Issues = InputBox("Please enter Number of Issues", "Issues", "Type here")
InventoryValue = InputBox("Please enter Inventory Value", "Inventory Value", "Type here")
Range("A2").Activate
Do
If ActiveCell.Value = "" Then Exit Do
ActiveCell.Offset(1, 0).Activate
Loop
ActiveCell.Value = ItemNumber
'ActiveCell.Offset(-1, 0).Copy
'ActiveCell.Offset(1, 0).PasteSpecial Paste:=xlPasteFormats
ActiveCell.Offset(0, 5).Value = ItemType
'ActiveCell.Offset(-1, 0).Copy
'ActiveCell.Offset(1, 0).PasteSpecial Paste:=xlPasteFormats
ActiveCell.Offset(0, 7).Value = Issues
'ActiveCell.Offset(-1, 7).Copy
'ActiveCell.Offset(1, 0).PasteSpecial Paste:=xlPasteFormats
ActiveCell.Offset(0, 8).Value = InventoryValue
'ActiveCell.Offset(-1, 8).Copy
'ActiveCell.Offset(1, 0).PasteSpecial Paste:=xlPasteFormats
End Sub
I believe the following will achieve your expected results without Activating a cell and without the Do Loop too, both of which will invariably result in reduced performance:
Sub Data_Entry()
Dim ws As Worksheet: Set ws = ThisWorkbook.ActiveSheet 'or you could be more explicit and use: ThisWorkbook.Worksheets("Sheet1")
'declare and set the worksheet being used, amend as required.
Application.ScreenUpdating = False
Dim ItemNumber As String
Dim ItemType As String
Dim Issues As String
Dim InventoryValue As String
ItemNumber = InputBox("Please enter Item Number", "Item Number", "Type here")
ItemType = InputBox("Please enter Item Type", "Item Type", "Type here")
Issues = InputBox("Please enter Number of Issues", "Issues", "Type here")
InventoryValue = InputBox("Please enter Inventory Value", "Inventory Value", "Type here")
NextRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Offset(1, 0).Row
'find the next free row in Column A
ws.Range("A" & NextRow).Value = ItemNumber
'another way to reference a cell would be: ws.Cells(NextRow, 1).Value = ItemNumber
ws.Range("F" & NextRow).Value = ItemType
ws.Range("H" & NextRow).Value = Issues
ws.Range("I" & NextRow).Value = InventoryValue
ws.Range("A" & NextRow - 1 & ":I" & NextRow - 1).Copy
'Copy above row from Columns A to I
ws.Range("A" & NextRow & ":I" & NextRow).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
'paste the formating to new row Columns A to I
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
Give this a try :
Option Explicit
Sub data_entry()
Application.ScreenUpdating = False
Dim ItemNumber As String
Dim ItemType As String
Dim Issues As String
Dim InventoryValue As String
ItemNumber = InputBox("Please enter Item Number", "Item Number", "Type here")
ItemType = InputBox("Please enter Item Type", "Item Type", "Type here")
Issues = InputBox("Please enter Number of Issues", "Issues", "Type here")
InventoryValue = InputBox("Please enter Inventory Value", "Inventory Value", "Type here")
Range("A2").Activate
Do
If ActiveCell.Value = "" Then Exit Do
ActiveCell.Offset(1, 0).Activate
Loop
ActiveCell.Value = ItemNumber
'ActiveCell.Offset(-1, 0).Copy
Range(ActiveCell, ActiveCell.Offset(-1, 0)).Copy
'ActiveCell.Offset(1, 0).PasteSpecial Paste:=xlPasteFormats
Sheets("NameSheet").Range(ActiveCell, ActiveCell.Offset(1, 0)).PasteSpecial xlPasteValuesAndNumberFormats
Sheets("NameSheet").Range(ActiveCell, ActiveCell.Offset(1, 0)).PasteSpecial PasteSpecial xlPasteFormats
ActiveCell.Offset(0, 5).Value = ItemType
'ActiveCell.Offset(0, 5).Copy
Range(ActiveCell, ActiveCell.Offset(-1, 0)).Copy
'ActiveCell.Offset(1, 0).PasteSpecial Paste:=xlPasteFormats
Sheets("NameSheet").Range(ActiveCell, ActiveCell.Offset(1, 0)).PasteSpecial xlPasteValuesAndNumberFormats
Sheets("NameSheet").Range(ActiveCell, ActiveCell.Offset(1, 0)).PasteSpecial PasteSpecial xlPasteFormats
ActiveCell.Offset(0, 7).Value = Issues
'ActiveCell.Offset(-1, 7).Copy
Range(ActiveCell, ActiveCell.Offset(-1, 7)).Copy
'ActiveCell.Offset(1, 0).PasteSpecial Paste:=xlPasteFormats
Sheets("NameSheet").Range(ActiveCell, ActiveCell.Offset(1, 0)).PasteSpecial xlPasteValuesAndNumberFormats
Sheets("NameSheet").Range(ActiveCell, ActiveCell.Offset(1, 0)).PasteSpecial PasteSpecial xlPasteFormats
ActiveCell.Offset(0, 8).Value = InventoryValue
'ActiveCell.Offset(-1, 8).Copy
Range(ActiveCell, ActiveCell.Offset(-1, 8)).Copy
'ActiveCell.Offset(1, 0).PasteSpecial Paste:=xlPasteFormats
Sheets("NameSheet").Range(ActiveCell, ActiveCell.Offset(1, 0)).PasteSpecial xlPasteValuesAndNumberFormats
Sheets("NameSheet").Range(ActiveCell, ActiveCell.Offset(1, 0)).PasteSpecial PasteSpecial xlPasteFormats
End Sub

How to optimize multiple loops in VBA code within 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.

Macro calling a function without being required (VBA)

I made this sub in VBA which copies the contents of a sheet to a new sheet, then format and save this as a .csv. But when I'm debugging this, the sub jumps alone to a function in another module and starts an infinite loop.
Depending on the organization of the commands, it jumps before or after for this function, but always skips.
in the current sub is jumping in the ".move" command.
I have not found the solution because the polls always return something like: "How to do a sub automatically call a function?" But that is precisely what is happening to me without my will.
That is my Sub
Sub TCzor()
'
Dim MData, MStr
Dim ultimalinha As Integer
Dim valorA As String
Dim valorB As String
Dim valorC As String
Dim valorD As String
Dim sUserName As String
MData = Date
MStr = Format(MData, "ddmm")
sUserName = Environ$("username")
'
Windows("MultiTrat.xlsm").Activate
Sheets("MultiTrat").Select
Sheets.Add After:=ActiveSheet
ActiveSheet.Name = "TCzor"
Sheets("MultiTrat").Select
Range("AX3:BF111").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("TCzor").Select
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A1").Select
Application.CutCopyMode = False
Selection.AutoFilter
ActiveSheet.Range("$A$1:$I$109").AutoFilter Field:=1, Criteria1:="="
Rows("2:2").Select
Range(Selection, Rows("1000:1000")).Select
Selection.Delete Shift:=xlUp
Selection.AutoFilter
Columns("A:A").Select
Selection.Delete Shift:=xlToLeft
Columns("B:B").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Columns("G:G").Select
Selection.Cut
Columns("B:B").Select
ActiveSheet.Paste
Columns("D:D").Select
Selection.Delete Shift:=xlToLeft
Columns("E:E").Select
Range(Selection, Columns("XFD:XFD")).Select
Selection.Delete Shift:=xlToLeft
Range("D1").Value = "Valor"
Columns("D:D").Select
Selection.NumberFormat = "0.00"
ultimalinha = Range("A1").End(xlDown).Row
For linha = 2 To ultimalinha
If Cells(linha, 3).Value = "C" Then
Cells(linha, 3).Value = "Créd"
Else
Cells(linha, 3).Value = "Déb"
End If
Next linha
For linha = 1 To ultimalinha
valorA = Cells(linha, 1)
valorB = Cells(linha, 2)
valorC = Cells(linha, 3)
valorD = Cells(linha, 4)
Cells(linha, 1) = valorA & ";" & valorB & ";" & valorC & ";" & valorD
Next linha
Range("B:D").Delete
Sheets("TCzor").Select
Sheets("TCzor").Move
ChDir "C:\Users\" & sUserName & "\Desktop"
ActiveWorkbook.SaveAs Filename:= _
"C:\Users\" & sUserName & "\Desktop\TC" & MStr & ".csv", FileFormat:=xlCSV, _
CreateBackup:=False
ActiveWindow.Close
Windows("tczor_jv.xlsm").Activate
End Sub
And this is the Function that it is calling by itself
Function GetARN(Myrange As Range) As String
Dim regex As New RegExp
Dim strPattern As String
Dim strInput As String
Dim strReplace As String
Dim strOutput As String
strPattern = "[0-9]{23}"
strInput = Myrange.Value
With regex
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
Set matches = regex.Execute(strInput)
For Each Match In matches
GetARN = Match.Value
Next Match

Resources