How to fix 2nd errHandler - excel

I need to filer two different columns and each time delete the visible rows. However, there may not be any rows to delete and as such I've included errHandlers. In the current workbook, there are no rows to be deleted either time. This first instance works fine but the second on throws the runtime error 1004.
Below is a portion of my code which contains bother errHandlers:
Range("T1").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 10498160
.TintAndShade = 0
.PatternTintAndShade = 0
End With
With Selection.Font
.Color = -16711681
.TintAndShade = 0
End With
With Selection
.HorizontalAlignment = xlGeneral
.VerticalAlignment = xlBottom
.WrapText = True
.Orientation = 0
.AddIndent = False
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
ActiveCell.FormulaR1C1 = "OK or DELETE"
Rows("1:1").Select
Selection.AutoFilter
Range("T2").Select
ActiveCell.FormulaR1C1 = _
"=IF(AND(RC[-19]<>R[-1]C[-19],RC[-10]<>R[-1]C[-10]),""OK"",IF(AND(RC[-19]=R[-1]C[-19],RC[-10]<>R[-1]C[-10]),""OK"",IF(AND(RC[-19]=R[-1]C[-19],RC[-10]=R[-1]C[-10],RC[-7]=""T""),""OK"",""DELETE"")))"
Selection.AutoFill Destination:=Range("T2:T" & Cells(Rows.Count, 1).End(xlUp).Row)
Range("T2:T" & Cells(Rows.Count, 1).End(xlUp).Row).Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
ActiveSheet.Range("$A$1:$T" & Cells(Rows.Count, 1).End(xlUp).Row).AutoFilter Field:=20, Criteria1:="DELETE"
On Error GoTo errHandler:
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.EntireRow.Delete
errHandler:
ActiveSheet.Range("$A$1:$T" & Cells(Rows.Count, 1).End(xlUp).Row).AutoFilter Field:=20
Columns("E:G").Select
Selection.ColumnWidth = 11
Range("G2").Select
ActiveCell.FormulaR1C1 = _
"=IF(RC[6]=""T"",""DELETE"",IF(AND(RC[-6]=R[1]C[-6],RC[3]=R[1]C[3],R[1]C[6]=""T""),R[1]C[-1],IF(RC[-6]=R[1]C[-6],R[1]C[-1]-1,VALUE(""06/30/2017""))))"
Selection.AutoFill Destination:=Range("G2:G" & Cells(Rows.Count, 1).End(xlUp).Row)
Range("G2:G" & Cells(Rows.Count, 1).End(xlUp).Row).Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
ActiveSheet.Range("$A$1:$T" & Cells(Rows.Count, 1).End(xlUp).Row).AutoFilter Field:=7, Criteria1:="DELETE"
On Error GoTo errHandler2:
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.EntireRow.Delete
errHandler2:
ActiveSheet.Range("$A$1:$T" & Cells(Rows.Count, 1).End(xlUp).Row).AutoFilter Field:=7
Range("D2").Select
ActiveWorkbook.Save
End Sub
Any help would be greatly appreciated.

You've entered Spaghetti Lane, and you want to get out of there before you dig yourself any deeper.
Your procedure is doing too many things. Doing too many things is the single reason for ever needing more than a single error-handling subroutine in a procedure scope. Break. Things. Down.
An On Error statement has no effect whatsoever if it's executed while VBA is already in an error state - thus, no error-handling subroutine should ever have any On Error statements.
Start by pulling that "delete all visible rows" code into its own procedure scope:
Private Sub DeleteVisibleRows(ByVal source As Range)
On Error Resume Next
source.SpecialCells(xlCellTypeVisible).EntireRow.Delete
On Error GoTo 0
End Sub
Note how Selection is irrelevant in that code, and how no Range needs to be Selected.
Second, an error-handling subroutine should only ever run while VBA is in an error state; not doing that causes the "happy execution path" and the "error execution path" to get intertwined, and that never ends well.
Starting at On Error GoTo errHandler:, your code should look like this:
DeleteVisibleRows Selection 'TODO: work out what Range object this is, use it instead
Dim entireTable As Range
Set entireTable = ActiveSheet.Range("$A$1:$T" & ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row)
entireTable.AutoFilter Field:=20
ActiveSheet.Columns("E:G").ColumnWidth = 11
Dim columnG As Range 'TODO: use meaningful name
Set columnG = ActiveSheet.Range("G2:G" & ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row)
'NOTE: no need to AutoFill if we write the whole column at once..
columnG.FormulaR1C1 = "=IF(RC[6]=""T"",""DELETE"",IF(...))"
'NOTE: no clipboard gets involved
columnG.Value = columnG.Value ' overwrites formulas with their values
entireTable.AutoFilter Field:=7, Criteria1:="DELETE"
DeleteVisibleRows entireTable
ActiveSheet.Range("D2").Select ' <~ this is the only legit use of Range.Select!!
ActiveWorkbook.Save

Related

MS Excel - VBA - Issues with searching a #, then returning relevant cells to different worksheet

I've got a workbook in Excel that I can add orders at my work and it stores into a database. I have another sheet that you can type in an order number (ECO number in the code) and I want it to display the # plus any relevant part numbers. I am having issue getting it to select only the range that I need.
Here is what I have in VBA so far:
Sub PlayMacro()
Dim Prompt As String
Dim RetValue As String
Dim Rng As Range
Dim RowCrnt As Long
Prompt = ""
With Sheets("ECO Database")
Do While True
RetValue = InputBox(Prompt & "Type in ECO#")
If RetValue = "" Then
Exit Do
End If
Set Rng = .Columns("A:A").Find(What:=RetValue, After:=.Range("A1"), _
LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Rng Is Nothing Then
Prompt = "ECO""" & RetValue & """Not Found"
Else
Sheets("ECO Updates").Select
ActiveCell.Offset(1, 0).Range("A1").Select
ActiveWindow.SmallScroll Down:=3
ActiveCell.Range("A1:T49").Select
Selection.Delete Shift:=xlToLeft
Sheets("ECO Database").Select
ActiveCell.Offset(-2, 0).Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
ActiveCell.Range("A:U").Select
Selection.Copy
Sheets("ECO Updates").Select
ActiveCell.Select
ActiveSheet.Paste
End If
Prompt = Prompt & vbLf
Loop
End With
End Sub
I have gotten it to pop up with a dialog box and ask for the number I want. I type it in, and I get errors due to my programming mistakes, or it selects everything in the sheet (All cells) and memory issues arise. I used the macro recorder so you can see that I'm very much a novice.
I have in column A the ECO number that I'm searching for. In Columns B through U I have the data I want. When I add the ECO orders into the database, I've left one blank row between all of them. I thought it would be easier to find where they end, but obviously I'm having difficulty. The reason I want to copy/eventually cut the data is so that any ECO can be adjusted and then "Saved" (Copy/Cut back to the database). Any suggestions would be hugely appreciated!
PS I'm not allowed to add images yet it says, otherwise I would show you what the format is.
Here is what I got as a solution after more time working on this! I have updated my entire sheet with some extras also. This achieves the result I want! Now I'm just struggling getting it to display a msg box with an error rather than a compiling error when I search for something that isn't found. You'll have to ignore the comments behind the ' as that is me trying to get this damn thing to say Not Found. It is coming up with that message when I search for something that DOES exist. A different problem for a different day.
Sub ECO_SEARCH()
Dim val As String
'Dim Rng As Range
'Is B1 empty?
If IsEmpty(Range("B1").value) = True Then
MsgBox "Please enter an ECO#"
Range("A3:T150").Select
Selection.ClearContents
GoTo LastLine
End If
Sheets("ECO Updates").Select
Range("A3:T150").Select
Selection.Delete Shift:=xlToLeft
ActiveWindow.SmallScroll Down:=-21
Range("B1").Select
val = Range("B1").value
'ActiveCell.FormulaR1C1 = "B1"""
Sheets("ECO Database").Select
Range("A3").Select
Cells.Find(What:=val, After:=ActiveCell, LookIn:=xlFormulas2, LookAt _
:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase _
:=False, SearchFormat:=False).Activate
'If Not Rng Is Nothing Then
' MsgBox "ECO# Not Found!"
' GoTo LastLine
'End If
ActiveCell.Offset(0, 1).Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight).Offset(0, 18)).Select
Selection.Copy
Sheets("ECO Updates").Select
Range("A3").Select
ActiveSheet.Paste
Range("A3:T150").HorizontalAlignment = xlCenter
Range("A3:T150").Font.Size = 10
Range("A3:T150").Font.Bold = False
Range("A3:T150").Borders(xlEdgeBottom).Weight = xlThin
Range("A3:T150").Borders(xlEdgeTop).Weight = xlThin
Range("A3:T150").Borders(xlEdgeLeft).Weight = xlThin
Range("A3:T150").Borders(xlEdgeRight).Weight = xlThin
Range("A3:T150").Borders(xlInsideHorizontal).Weight = xlThin
Range("A3:T150").Borders(xlInsideVertical).Weight = xlThin
Range("A3:T150").Borders(xlEdgeBottom).LineStyle = xlContinuous
Range("A3:T150").Borders(xlEdgeTop).LineStyle = xlContinuous
Range("A3:T150").Borders(xlEdgeLeft).LineStyle = xlContinuous
Range("A3:T150").Borders(xlEdgeRight).LineStyle = xlContinuous
Range("A3:T150").Borders(xlInsideHorizontal).LineStyle = xlContinous
Range("A3:T150").Borders(xlInsideVertical).LineStyle = xlContinous
Range("A3:T150").Borders(xlEdgeBottom).Color = vbBlack
Range("A3:T150").Borders(xlEdgeTop).Color = vbBlack
Range("A3:T150").Borders(xlEdgeLeft).Color = vbBlack
Range("A3:T150").Borders(xlEdgeRight).Color = vbBlack
Range("A3:T150").Borders(xlInsideHorizontal).Color = vbBlack
Range("A3:T150").Borders(xlInsideVertical).Color = vbBlack
Range("A3:T150").HorizontalAlignment = xlCenter
Range("A3:T150").VerticalAlignment = xlCenter
LastLine:
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.

VBA dynamic range

Fairly new to VBA. I have a macro that I'd like to change to be able to work on however many rows containing data are in the worksheet rather than the hardcoded value (46).
Sub test1calc()
'
' test1calc Macro
'
'
'1 - UNSTRESSED POSTED PRODUCT LEVEL BREAKDOWN SUMMED AT NETTING SET
Columns("AS:AS").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range("AS1").Select
Selection.Interior.Pattern = xlSolid
Selection.Interior.PatternColorIndex = 2
Selection.Interior.Color = 65535
ActiveCell.FormulaR1C1 = "Unstressed Posted Total"
Range("AS2").Select
ActiveCell.FormulaR1C1 = "=SUM(RC[-30]:RC[-1])"
Range("AS2").Select
Selection.AutoFill Destination:=Range("AS2:AS46")
Range("AS2:AS46").Select
ActiveSheet.Calculate
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
End Sub
I'm assuming you want to fill the rows where there is existing data to the left, not the millions of rows that exist in your worksheet.
If so, I believe your code can be simplified to the following:
Sub test1calc()
'1 - UNSTRESSED POSTED PRODUCT LEVEL BREAKDOWN SUMMED AT NETTING SET
Columns("AS:AS").Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
With Range("AS1")
.Interior.Pattern = xlSolid
.Interior.PatternColorIndex = 2
.Interior.Color = 65535
.Value = "Unstressed Posted Total"
End With
With Range("AS2:AS" & Range("O" & Rows.Count).End(xlUp).Row)
.FormulaR1C1 = "=SUM(RC[-30]:RC[-1])"
.Value = .Value
End With
End Sub

autofilter to exclude dates with "or" operator coming up with incomplete result

Sub DOBdateRange()
Dim Bfordate As Date
Dim Afterdate As Date
Bfordate = Worksheets("error").Range("i5").Value
Afterdate = Worksheets("error").Range("j5").Value
Application.ScreenUpdating = False
'çhange data formate to Date
Worksheets("data").Select
Worksheets("data").Range("a2", Range("a" & Rows.count).End(xlUp)).Offset(, 3).Select
Selection.Name = "DOB"
Selection.NumberFormat = "d/mm/yyyy"
'filter and copy how many records match (exclude) date criteria,
Worksheets("Data").Select
Range("bq1").Select
Range(Selection, Selection.End(xlToLeft)).Select
Selection.AutoFilter
ActiveSheet.Range(Selection, Selection.End(xlDown)).AutoFilter _
**Field:=4, _
Criteria1:="<" & Bfordate, _
Operator:=xlOr, _
Criteria2:=">" & Afterdate**
Range("a1").Select
Range("bq1").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToLeft)).Select
Selection.Copy Set NewSheet = Sheets.Add(After:=Worksheets("error"))
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
On Error GoTo duplicatesheet3
NewSheet.Name = "DOBdateRange"
On Error GoTo 0
NewSheet.Range("A1").Select
Application.CutCopyMode = False
Worksheets("dobdaterange").Range("d:d").Select
Selection.NumberFormat = "d/mm/yyyy"
Application.CutCopyMode = False
Worksheets("dobdaterange").Range("a1").Select
Range(Selection, Selection.End(xlToRight)).EntireColumn.AutoFit
With ActiveSheet.UsedRange.Borders
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
Worksheets("Data").Select
Worksheets("Data").Range("A1").Select
Selection.AutoFilter 'Remove auto filter
Sheets("DOBdateRange").Select
Exit Sub
Previously I was using range. Value to refer to date criteria since it wasn't working I thought its not picking up date format so I declared the dates as date, still its not filtering all the data, its generating incomplete result, after much searching and trying different things i decided to post it for direction. any help pointing to right direction will be highly appreciated. Thank you

Extract data from Excel workbook with specific procedure to report sheet

Here is the problem in my situation:
My workbook counts from the first of the month till the 15th. (sheet 1-15)
Sometimes it happens that there are 3 weeks-counts in half a month.
The weeks are counted from Monday till Sunday in de excell cels.
NOTE: I have hidden some rows and columns due to work with dates.
Now what I should establish with VB is a monthly report that shows me on how many jobs each employeé has done due to make a calculation of workspeed/ job.
All the jobs are variable and can be selected in each day of de workbook (see listed jobs sheets(1).thisworkbook.
It is possible that I have to give weekly evaluations, so it is nessecery that VB wil still use the same wbnew and expand the input of the daily workhours.
I already made a 'partial' code to start with but I can not handle to the rest.
The code should look for how many employees there are. (this I fill in in sheet(“1”) of workbook).
It should look in each workday sheet (“1”) –sheet(“15) for:
• Does the employee exist?
• Wat day of sheet we are
• Which jobs it has done (jobdescription + code job required in listing)
• If job already exist just fill in in the same row, but in the right Colum of date, if the job is not done, don't show the jobname, don't show the jobcode
• How many time spend on the job
• To control if the counting is correct you can see the total of hours in column (AA) in sheet (“15”) of workbook and cel (“S15”) of montly reportsheet
(in this case both have 15hours displayed = ok).
I have a workbook and a example of reportsheet posted.
In the workbook you will find also my attemt to start with a code (see remarks)
Hopefully someone can help me out.
dowloadlink Workbooks klick here first
here is my attemps but it is far from what I really need to do
Sub Macro1()
'
' Macro1 Macro
'
Dim wbNew As Workbook
'I need here VBA to look for if the file "per 1-15 exists and don't create a new file but just exand the data
'I need something like for each ws of thisworkbook
'also the rest of the required formula is too difficult for me
'Does the employee exist?
'Wat day of sheet we are
'Which jobs it has done (jobdescription + code job required in listing)
'If job already exist just fill in in the same row, but in the right Colum of date, if the job is not done, don't show the jobname, don't show the jobcode
'How many time spend on the job
'To control if the counting is correct you can see the total of hours in column (AA) in sheet (“15”) of workbook and cel (“S15”) of montly reportsheet (in this case both have 15hours displayed = ok).
'you can have a look at my example reportsheet
ThisWorkbook.Sheets(1).Activate
Range("A1:S53").Select
Range("S53").Activate
Selection.Copy
Set wbNew = Workbooks.Add
wbNew.Sheets(1).Activate
Range("A1:S53").Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
wbNew.Sheets(1).Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Range("A1").Select
ActiveSheet.Paste
ThisWorkbook.Sheets(1).Activate
Range("C12").Select
Application.CutCopyMode = False
Selection.Copy
wbNew.Sheets(1).Activate
Range("C12").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ThisWorkbook.Sheets("1").Activate
Sheets("1").Select
Range("B8").Select
Application.CutCopyMode = False
Selection.Copy
wbNew.Sheets(1).Activate
Range("M5").Select
wbNew.Sheets(1).Paste
Range("L7:Q7").Select
Selection.FormatConditions.Delete
Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlEqual, _
Formula1:="=$C$12"
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
Range("R7:S7").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Selection.NumberFormat = "0"
With Selection.FormatConditions(1).Font
.Bold = True
.Italic = False
.TintAndShade = 0
End With
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
Range("A1:S53").Select
Application.CutCopyMode = False
ActiveSheet.PageSetup.PrintArea = "$A$1:$S$53"
Application.PrintCommunication = False
Application.PrintCommunication = True
ActiveSheet.PageSetup.PrintArea = "$A$1:$S$53"
Application.PrintCommunication = False
With ActiveSheet.PageSetup
.PrintHeadings = False
.PrintGridlines = False
.PrintComments = xlPrintNoComments
.PrintQuality = 600
.CenterHorizontally = False
.CenterVertically = False
.Orientation = xlPortrait
.Draft = False
.PaperSize = xlPaperA4
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = False
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 1
.PrintErrors = xlPrintErrorsDisplayed
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.ScaleWithDocHeaderFooter = True
.AlignMarginsHeaderFooter = True
End With
Application.PrintCommunication = True
' I also should hide row 13 , but it gives strage vieuws at the moment
Sheets(1).Name = Range("M5").Value
Sheets.Add After:=ActiveSheet
ThisWorkbook.Sheets(1).Activate
Range("A1:S53").Select
Range("S53").Activate
Selection.Copy
wbNew.Sheets(2).Activate
Range("A1:S53").Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
wbNew.Sheets(2).Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Range("A1").Select
ActiveSheet.Paste
ThisWorkbook.Sheets(1).Activate
Range("C12").Select
Application.CutCopyMode = False
Selection.Copy
wbNew.Sheets(1).Activate
Range("C12").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ThisWorkbook.Sheets("1").Activate
Sheets("1").Select
Range("B9").Select
Application.CutCopyMode = False
Selection.Copy
wbNew.Sheets(2).Activate
Range("M5").Select
wbNew.Sheets(2).Paste
Range("L7:Q7").Select
Selection.FormatConditions.Delete
Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlEqual, _
Formula1:="=$C$12"
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
Range("R7:S7").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Selection.NumberFormat = "0"
With Selection.FormatConditions(1).Font
.Bold = True
.Italic = False
.TintAndShade = 0
End With
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
Range("A1:S53").Select
Application.CutCopyMode = False
ActiveSheet.PageSetup.PrintArea = "$A$1:$S$53"
Application.PrintCommunication = False
Application.PrintCommunication = True
ActiveSheet.PageSetup.PrintArea = "$A$1:$S$53"
Application.PrintCommunication = False
With ActiveSheet.PageSetup
.PrintHeadings = False
.PrintGridlines = False
.PrintComments = xlPrintNoComments
.PrintQuality = 600
.CenterHorizontally = False
.CenterVertically = False
.Orientation = xlPortrait
.Draft = False
.PaperSize = xlPaperA4
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = False
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 1
.PrintErrors = xlPrintErrorsDisplayed
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.ScaleWithDocHeaderFooter = True
.AlignMarginsHeaderFooter = True
End With
Application.PrintCommunication = True
' I also should hide row 13 , but it gives strage vieuws at the moment
Sheets(2).Name = Range("M5").Value
' instead of writing "per 1-15" down here, I should refer to Range("R7").Value, but it is not working
' in Cel R7 there is written "per 1-15" as value now(I believe)
ActiveWorkbook.SaveAs Filename:= _
"C:\Path\" & "per 1-15" & " " & Format(Range("C12"), "mmm") & ".xlsx"
FileFormat = xlOpenXMLWorkbook
Range("A15").Select
ActiveWindow.Close
End Sub
in order to start somewhere with a constructive way you can find a second attemt below
'in order to start with a creation of a new workbook I should do some handlings first
'I want to create a workbook where the names of the employees are shown , with in the sheetnames the names of the employees
'in thisworkbook.sheet "1" there is a list of 30 names listed Column B8:B37, that I shoud copy into a new workbook
Dim i As Long
Dim StartRow As Long
Dim LastRow As Long
Dim wbnew As Workbook
Dim wsNew As Worksheet
'STARTING FROM THIS WORKBOOK
'Set Start Row thisworkbook
StartRow = 8
'Set Last Row thisworkbook
LastRow = .Range("B" & .Rows.Count).End(xlUp).Row
For i = StartRow To LastRow
'copy the name into a cel "M5" of wbnew (see below)
If .Range("B" & i).Value <> "NAME" Then
' if cel is empty do nothing
If .Range("B" & i).Value <> "" Then
On Error Resume Next
'create new workbook
Set wbnew = Workbooks.Add
' launch here the sheet routine below
'wbnew sheet routine Handling---------------------------------------------------------
'when in this specific cells there is written "Name" , that Cell should not be copied to a new sheet wbnew
'when in cels B8:B37 there is written a name ,the code should make a new workbook (wbnew) with following procedures
'this selection is always a copy from this specific sheet
ThisWorkbook.Sheets(1).Activate
Range("A1:S53").Select
Range("S53").Activate
Selection.Copy
'here I need to write activate always the new sheet wbnew
wbnew.Sheets(2).Activate
Range("A1:S53").Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
'here I need to write select always the new sheetwbnew
wbnew.Sheets(2).Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Range("A1").Select
ActiveSheet.Paste
' this has to stay like this
ThisWorkbook.Sheets(1).Activate
Range("C13").Select
Application.CutCopyMode = False
Selection.Copy
'here I need to write select always the new sheet wbnew
wbnew.Sheets(2).Activate
Range("C13").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ThisWorkbook.Sheets("1").Activate
' this has to stay like this
Sheets("1").Select
Range("B9").Select
Application.CutCopyMode = False
Selection.Copy
'here I need to write activate always the new sheet wbnew
wbnew.Sheets(2).Activate
Range("M5").Select
wbnew.Sheets(2).Paste
Range("L7:Q7").Select
Selection.FormatConditions.delete
Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlEqual, _
Formula1:="=$C$13"
Selection.FormatConditions (Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Font
.Bold = True
.Italic = False
.TintAndShade = 0
End With
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
Range("A1:S53").Select
Application.CutCopyMode = False
ActiveSheet.PageSetup.PrintArea = "$A$1:$S$53"
Application.PrintCommunication = False
With ActiveSheet.PageSetup
.PrintTitleRows = ""
.PrintTitleColumns = ""
End With
Application.PrintCommunication = True
ActiveSheet.PageSetup.PrintArea = "$A$1:$S$53"
Application.PrintCommunication = False
With ActiveSheet.PageSetup
.LeftHeader = ""
.CenterHeader = ""
.RightHeader = ""
.LeftFooter = ""
.CenterFooter = ""
.RightFooter = ""
.LeftMargin = Application.InchesToPoints(0.708661417322835)
.RightMargin = Application.InchesToPoints(0.708661417322835)
.TopMargin = Application.InchesToPoints(0.748031496062992)
.BottomMargin = Application.InchesToPoints(0.748031496062992)
.HeaderMargin = Application.InchesToPoints(0.31496062992126)
.FooterMargin = Application.InchesToPoints(0.31496062992126)
.PrintHeadings = False
.PrintGridlines = False
.PrintComments = xlPrintNoComments
.PrintQuality = 600
.CenterHorizontally = False
.CenterVertically = False
.Orientation = xlPortrait
.Draft = False
.PaperSize = xlPaperA4
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = False
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 1
.PrintErrors = xlPrintErrorsDisplayed
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.ScaleWithDocHeaderFooter = True
.AlignMarginsHeaderFooter = True
.EvenPage.LeftHeader.Text = ""
.EvenPage.CenterHeader.Text = ""
.EvenPage.RightHeader.Text = ""
.EvenPage.LeftFooter.Text = ""
.EvenPage.CenterFooter.Text = ""
.EvenPage.RightFooter.Text = ""
.FirstPage.LeftHeader.Text = ""
.FirstPage.CenterHeader.Text = ""
.FirstPage.RightHeader.Text = ""
.FirstPage.LeftFooter.Text = ""
.FirstPage.CenterFooter.Text = ""
.FirstPage.RightFooter.Text = ""
End With
Range("R7:S7").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Selection.NumberFormat = "0"
Range("A4:H9").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Rows("10:10").Select
Selection.EntireRow.Hidden = True
Application.PrintCommunication = True
'the new sheet should be named to this specific cel value (this is the name we copied form sheet(1) from thisworkbook
'now it is referring to a specific sheet of wbnew, but that is not ok, should be changed
Sheets(2).Name = Range("M5").Value
Range("A15").Select
'later I have to Call here an other Sub in order to do aditional extractions
Call sub_followlater
wbnew.Activate
'create a new sheet here
set wsNew = wbNew.Sheets.Add After:=ActiveSheet
'save the new workbook wbnew
wbnew.SaveAs Filename:= _
"C:\Path\" & "per 1-15" & " " & Format(Range("C13"), "mmmm") & " " & Format(Range("C13"), "YYYY") & ".xlsx"
FileFormat = xlOpenXMLWorkbook
ActiveWindow.Close
Hopefully someone is feeling challanged enouhg to help me out with this.
thanks in advance...
One solution is to write a macro that will copy the rows with data to another sheet, so you get all the entries for all jobs, all dates on one page. This will streamline the code because you will not be looking at blank rows for your report preparation.
Once you have the data all transferred to a single worksheet you can loop through the rows in a second macro that copies the data to separate pages based on the persons name.
This involves a good amount of skill in VBA using loops to evaluate and copy the rows from many tabs to one in the first pass, then from the one worksheet to many in the second pass. You will not be able to complete this with just the macro recorder. If you are up to the challenge but lacking in knowledge of the VBA language and the Excel object model I suggest getting one of John Walkenbach's books on Excel Power Programming with VBA.
Good luck.

Resources