What causes this VBA Code to take so long to run? - excel

I am new using VBA and I've run into something that has been puzzling me: when I run a pivot on the following line of code it takes a really long time for it to finish when in reality it should not take that long. If anyone knows what the problem with it is or if you have some ways to make my code run more efficiently please let me know.
Sub Macro1()
'
' Macro1 Macro
'
' Keyboard Shortcut: Ctrl+q
'
Dim ws1 As Worksheet
Dim wb1 As Workbook
Dim ws2 As Worksheet
Dim wb2 As Workbook
Dim ws3 As Worksheet
Dim ws4 As Worksheet
Dim ws5 As Worksheet
Dim ws6 As Worksheet
Dim ws7 As Worksheet
Dim ws8 As Worksheet
Dim ws9 As Worksheet
Dim ws10 As Worksheet
Dim LastRow As Long
Dim LastRow1 As Long
Dim LastCol1 As Long
Dim PTable1 As PivotTable
Dim PCache1 As PivotCache
Dim PRange1 As Range
Set wb1 = ActiveWorkbook
Set ws1 = Sheets(1)
Set ws2 = Sheets.Add(After:=ActiveSheet)
Set ws3 = Sheets.Add(After:=ActiveSheet)
Set ws4 = Sheets.Add(After:=ActiveSheet)
Set ws5 = Sheets.Add(After:=ActiveSheet)
Set ws6 = Sheets.Add(After:=ActiveSheet)
Set ws7 = Sheets.Add(After:=ActiveSheet)
Set ws8 = Sheets.Add(After:=ActiveSheet)
Set ws9 = Sheets.Add(After:=ActiveSheet)
Set ws10 = Sheets.Add(After:=ActiveSheet)
ws2.Name = "Total"
ws3.Name = "01"
ws4.Name = "IM"
ws5.Name = "AMA"
ws6.Name = "TD"
ws7.Name = "PUP"
ws8.Name = "POS"
ws9.Name = "STG"
ws10.Name = "07"
With ActiveWindow
If .FreezePanes Then .FreezePanes = False
.SplitColumn = 0
.SplitRow = 1
.FreezePanes = True
End With
With ws1
.Cells(1, 24) = "Bin"
.Cells(1, 25) = "UN"
.Range("A:Y").AutoFilter _
Field:=13, _
Criteria1:=">=1"
LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
.Range("E1:M" & LastRow).Copy ws2.Range("A1")
.Range("A:Y").AutoFilter _
Field:=21, _
Criteria1:="=1", _
Operator:=xlOr, Criteria2:="=01DIST"
.Range("E1:M" & LastRow).Copy ws3.Range("A1")
.Range("A:Y").AutoFilter _
Field:=21, _
Criteria1:=Array("10", "20", "40", "80")
.Range("E1:M" & LastRow).Copy ws4.Range("A1")
.Range("A:Y").AutoFilter _
Field:=21, _
Criteria1:="=AMA"
.Range("E1:M" & LastRow).Copy ws5.Range("A1")
.Range("A:Y").AutoFilter _
Field:=21, _
Criteria1:="=TD"
.Range("E1:M" & LastRow).Copy ws6.Range("A1")
.Range("A:Y").AutoFilter _
Field:=21, _
Criteria1:="=STG"
.Range("E1:M" & LastRow).Copy ws9.Range("A1")
.Range("A:Y").AutoFilter _
Field:=21, _
Criteria1:="7"
.Range("E1:M" & LastRow).Copy ws10.Range("A1")
End With
LastRow1 = ws2.Cells(Rows.Count, 1).End(xlUp).Row
LastCol1 = ws2.Cells(1, Columns.Count).End(xlToLeft).Column
Set PRange1 = ws2.Range("A1").CurrentRegion
Set PCache1 = ActiveWorkbook.PivotCaches.Create(xlDatabase, PRange1)
Set PTable1 = PCache1.CreatePivotTable(ws2.Cells(1, 10), "PivotTable1")
With PTable1.PivotFields("Part Number")
.Orientation = xlRowField
.Position = 1
End With
With PTable1.PivotFields("Inventory Value")
.Orientation = xlColumnField
.Position = 1
End With
With PTable1.PivotFields("Qty OH")
.Orientation = xlColumnField
.Position = 2
End With
PTable1.AddDataField ws2.PivotTables _
("PivotTable1").PivotFields("Qty OH"), "Sum of Qty OH", xlSum
PTable1.AddDataField ws2.PivotTables _
("PivotTable1").PivotFields("Inventory Value"), "Sum of Inventory Value", xlSum
End Sub

So I was able to find a way to make my pivot table run faster than before. I think it has something to do with the PTable1.PivotFields section of my previous code, my new code, which is longer now that I figured it out works like a charm.
Sub LiveERP_Test()
'
' LiveERP_Test Macro
'
' Keyboard Shortcut: Ctrl+q
'
With ActiveWindow
.SplitColumn = 0
.SplitRow = 1
End With
ActiveWindow.FreezePanes = True
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Dim ws4 As Worksheet
Dim ws5 As Worksheet
Dim ws6 As Worksheet
Dim ws7 As Worksheet
Dim ws8 As Worksheet
Dim ws9 As Worksheet
Dim ws10 As Worksheet
Dim LastRow As Long
Dim LastRow1 As Long
Dim LastCol1 As Long
Dim LastRow2 As Long
Dim LastCol2 As Long
Dim LastRow3 As Long
Dim LastCol3 As Long
Dim LastRow4 As Long
Dim LastCol4 As Long
Dim LastRow5 As Long
Dim LastCol5 As Long
Dim LastRow6 As Long
Dim LastCol6 As Long
Dim PTable1 As PivotTable
Dim PCache1 As PivotCache
Dim PRange1 As Range
Dim PTable2 As PivotTable
Dim PCache2 As PivotCache
Dim PRange2 As Range
Dim PTable3 As PivotTable
Dim PCache3 As PivotCache
Dim PRange3 As Range
Dim PTable4 As PivotTable
Dim PCache4 As PivotCache
Dim PRange4 As Range
Dim PTable5 As PivotTable
Dim PCache5 As PivotCache
Dim PRange5 As Range
Dim PTable6 As PivotTable
Dim PCache6 As PivotCache
Dim PRange6 As Range
Set ws1 = Sheets(1)
Set ws2 = Sheets.Add(After:=ActiveSheet)
Set ws3 = Sheets.Add(After:=ActiveSheet)
Set ws4 = Sheets.Add(After:=ActiveSheet)
Set ws5 = Sheets.Add(After:=ActiveSheet)
Set ws6 = Sheets.Add(After:=ActiveSheet)
Set ws7 = Sheets.Add(After:=ActiveSheet)
Set ws8 = Sheets.Add(After:=ActiveSheet)
Set ws9 = Sheets.Add(After:=ActiveSheet)
Set ws10 = Sheets.Add(After:=ActiveSheet)
ws2.Name = "Total"
ws3.Name = "01"
ws4.Name = "IM"
ws5.Name = "AMA"
ws6.Name = "TD"
ws7.Name = "PUP"
ws8.Name = "POS"
ws9.Name = "STG"
ws10.Name = "07"
With ws1
.Columns("W:W").EntireColumn.AutoFit
.Cells("1,24") = "Bin"
.Cells("1,25") = "UN"
.Range("A:Y").AutoFilter _
Field:=13, _
Criteria1:=">=1"
LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
.Range("E1:M" & LastRow).Copy ws2.Range("A1")
.Range("A:Y").AutoFilter _
Field:=21, _
Criteria1:="=1", _
Operator:=xlOr, Criteria2:="=01DIST"
.Range("E1:M" & LastRow).Copy ws3.Range("A1")
.Range("A:Y").AutoFilter _
Field:=21, _
Criteria1:=Array("10", "20", "40", "80")
.Range("E1:M" & LastRow).Copy ws4.Range("A1")
.Range("A:Y").AutoFilter _
Field:=21, _
Criteria1:="=AMA"
.Range("E1:M" & LastRow).Copy ws5.Range("A1")
.Range("A:Y").AutoFilter _
Field:=21, _
Criteria1:="=TD"
.Range("E1:M" & LastRow).Copy ws6.Range("A1")
.Range("A:Y").AutoFilter _
Field:=21, _
Criteria1:="=STG"
.Range("E1:M" & LastRow).Copy ws9.Range("A1")
.Range("A:Y").AutoFilter _
Field:=21, _
Criteria1:="7"
.Range("E1:M" & LastRow).Copy ws10.Range("A1")
.Range("U1:V" & LastRow).Copy ws10.Range("J1")
End With
LastRow1 = ws2.Cells(Rows.Count, 1).End(xlUp).Row
LastCol1 = ws2.Cells(1, Columns.Count).End(xlToLeft).Column
Set PRange1 = ws2.Range("A1").CurrentRegion
Set PCache1 = ActiveWorkbook.PivotCaches.Create(xlDatabase, PRange1)
Set PTable1 = PCache1.CreatePivotTable(ws2.Cells(1, 10), "PivotTable1")
With ws2.PivotTables("PivotTable1")
.ColumnGrand = True
.HasAutoFormat = True
.DisplayErrorString = False
.DisplayNullString = True
.EnableDrilldown = True
.ErrorString = ""
.MergeLabels = False
.NullString = ""
.PageFieldOrder = 2
.PageFieldWrapCount = 0
.PreserveFormatting = True
.RowGrand = True
.SaveData = True
.PrintTitles = False
.RepeatItemsOnEachPrintedPage = True
.TotalsAnnotation = False
.CompactRowIndent = 1
.InGridDropZones = False
.DisplayFieldCaptions = True
.DisplayMemberPropertyTooltips = False
.DisplayContextTooltips = True
.ShowDrillIndicators = True
.PrintDrillIndicators = False
.AllowMultipleFilters = False
.SortUsingCustomLists = True
.FieldListSortAscending = False
.ShowValuesRow = False
.CalculatedMembersInFilters = False
.RowAxisLayout xlCompactRow
End With
With ws2.PivotTables("PivotTable1").PivotCache
.RefreshOnFileOpen = False
.MissingItemsLimit = xlMissingItemsDefault
End With
With ws2.PivotTables("PivotTable1").PivotFields("Part Number")
.Orientation = xlRowField
.Position = 1
End With
PTable1.AddDataField ws2.PivotTables _
("PivotTable1").PivotFields("Qty OH"), "Sum of Qty OH", xlSum
PTable1.AddDataField ws2.PivotTables _
("PivotTable1").PivotFields("Inventory Value"), "Sum of Inventory Value", xlSum

Related

Filter Pivot table with VBA

I cant quite figure out how to filter my created pivot table with vba. The filter syntax I'm trying to use is the last line. I'm currently creating a pivot table from a raw data tab then trying to filter out the (blank) items.
I've tried (blank), 0, "" for the criteria
Sub Test()
'Pivot Table
Dim PSheet As Worksheet
Dim DSheet As Worksheet
Dim PCache As PivotCache
Dim PTable As PivotTable
Dim PRange As Range
Dim LastRow As Long
Dim LastCol As Long
Dim copyRng As Range
Dim destRng As Range
On Error Resume Next
Application.DisplayAlerts = False
Worksheets("PivotTable").Delete
Sheets.Add Before:=ActiveSheet
ActiveSheet.Name = "PivotTable"
Application.DisplayAlerts = True
Set PSheet = Worksheets("PivotTable")
Set DSheet = Worksheets("START")
'Define Data Range
LastRow = DSheet.Cells(Rows.Count, 1).End(xlUp).row
LastCol = DSheet.Cells(7, Columns.Count).End(xlToLeft).Column
Set PRange = DSheet.Cells(7, 1).Resize(LastRow, LastCol)
'Define Pivot Cache
Set PCache = ActiveWorkbook.PivotCaches.Create _
(SourceType:=xlDatabase, SourceData:=PRange). _
CreatePivotTable(TableDestination:=PSheet.Cells(1, 1), _
TableName:="PivotTable")
'Insert Blank Pivot Table
Set PTable = PCache.CreatePivotTable _
(TableDestination:=PSheet.Cells(1, 1), TableName:="PivotTable")
'Insert Row Fields
With ActiveSheet.PivotTables("PivotTable").PivotFields("EmpID")
.Orientation = xlRowField
.Position = 1
End With
'Insert Data Field
With ActiveSheet.PivotTables("PivotTable").PivotFields("DistinctCount")
.Orientation = xlDataField
.Position = 2
.Function = xlSum
.NumberFormat = "#,##0"
.Name = "DistinctReferenceCount"
End With
'Format Pivot
TableActiveSheet.PivotTables("PivotTable").ShowTableStyleRowStripes = TrueActiveSheet.PivotTables("PivotTable").TableStyle2 = "PivotStyleMedium9"
ActiveSheet.PivotTables("PivotTable").RowAxisLayout xlOutlineRow
ActiveSheet.PivotTables("PivotTable").RepeatAllLabels xlRepeatLabels
Worksheets("PivotTable").Range("A1").AutoFilter Field:=3, Criteria1:="<>(blank)"
End Sub
Some improvements to your code, study them
Option Explicit
Sub Test()
On Error GoTo Err_Control
'Pivot Table
Dim PSheet As Worksheet
Dim DSheet As Worksheet
Dim PCache As PivotCache
Dim PTable As PivotTable
Dim PRange As Range
Dim LastRow As Long
Dim LastCol As Long
Dim copyRng As Range
Dim destRng As Range
'Application.DisplayAlerts = False
'Worksheets("PivotTable").Delete
'Sheets.Add Before:=ActiveSheet
'ActiveSheet.Name = "PivotTable"
'----To Recreat your sheet....
Dim wrk As ThisWorkbook
Dim sht As Worksheet
Set wrk = ThisWorkbook
Dim trg As Worksheet
Dim Existe As Byte
For Each sht In wrk.Worksheets
If sht.Name = "PivotTable" Then
Application.DisplayAlerts = False
ThisWorkbook.Sheets("PivotTable").Delete
Application.DisplayAlerts = True
End If
Next sht
Application.ScreenUpdating = False
Existe = 0
For Each sht In wrk.Worksheets
If sht.Name = "PivotTable" Then
Existe = 1
End If
Next sht
If Existe = 0 Then
Set trg = wrk.Worksheets.Add(After:=wrk.Worksheets(wrk.Worksheets.Count))
trg.Name = "PivotTable"
End If
'-----------------------------------------
Application.DisplayAlerts = True
Set PSheet = Worksheets("PivotTable")
Set DSheet = Worksheets("START")
'Define Data Range
LastRow = DSheet.Cells(Rows.Count, 1).End(xlUp).Row
LastCol = DSheet.Cells(7, Columns.Count).End(xlToLeft).Column
Set PRange = DSheet.Cells(7, 1).Resize(LastRow, LastCol)
'Define Pivot Cache
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=PRange, Version:=6). _
CreatePivotTable TableDestination:=PSheet.Cells(1, 1), TableName:="PivotTable", DefaultVersion:=6
'Insert Blank Pivot Table ' Don't need that, lines over create pivot table
'Set PTable = PCache.CreatePivotTable(TableDestination:=PSheet.Cells(1, 1), TableName:="PivotTable")
'Insert Row Fields
With ActiveSheet.PivotTables("PivotTable").PivotFields("EmpID")
.Orientation = xlRowField
.Position = 1
End With
'Insert Data Field
With ActiveSheet.PivotTables("PivotTable").PivotFields("DistinctCount")
.Orientation = xlDataField
'.Position = 2 'Don't need that, generates error
.Function = xlSum
.NumberFormat = "#,##0"
.Name = "DistinctReferenceCount"
End With
'Format Pivot Table
ActiveSheet.PivotTables("PivotTable").ShowTableStyleRowStripes = True
ActiveSheet.PivotTables("PivotTable").TableStyle2 = "PivotStyleMedium9"
ActiveSheet.PivotTables("PivotTable").RowAxisLayout xlOutlineRow
ActiveSheet.PivotTables("PivotTable").RepeatAllLabels xlRepeatLabels
ActiveSheet.PivotTables("PivotTable").PivotFields("DistinctCount").PivotItems("(blank)").Visible = False
Err_Control:
If Err.Number <> 0 Then
MsgBox Err.Description
'here you handle the errors, if an error appears,
'press Ctrl + Pause Break that you can go to the error location using
'resume next
'below this msgbox err.description
End If
End Sub

Replace Values in Range

I've tried to do this replacement in two different ways (first attempt commented below), but it ends up replacing everything on the sheet, instead:
Sub NoNullSaveCSV()
Dim WB As Workbook
Dim WS As Worksheet
Dim find1 As Variant
Dim rplc1 As Variant
Dim find2 As Variant
Dim rplc2 As Variant
Dim Rng As Range
Application.Workbooks.Add xlWBATWorksheet
Set WB = ActiveWorkbook
Set WS = ActiveSheet
With ThisWorkbook.Worksheets("PedidosTratados")
.Range("A3:DW1000").Copy
WS.Range("A1").PasteSpecial xlPasteValues
End With
WS.Range("A1").Value = "FilterCol"
WS.Columns.AutoFilter Field:=1, Criteria1:=""
WS.UsedRange.SpecialCells(xlCellTypeVisible).EntireRow.Delete
WS.AutoFilterMode = False
ReplaceCount = ReplaceCount + Application.WorksheetFunction.CountIf(WS.Cells, "*" & fnd1 & "*")
'+ Application.WorksheetFunction.CountIf(WS.Cells, "*" & fnd2 & "*")
fnd1 = "7.9000"
rplc1 = "7.900"
fnd2 = "9.9000"
rplc2 = "9.900"
With WS
.Range("AT2:DW1000").Replace fnd1, rplc1
.Range("AT2:DW1000").Replace fnd2, rplc2
'.Cells.Replace what:=fnd1, Replacement:=rplc1, _
'LookAt:=xlPart, SearchOrder:=xlByColumns, MatchCase:=False, _
'SearchFormat:=False, ReplaceFormat:=False
'.Cells.Replace what:=fnd2, Replacement:=rplc2, _
'LookAt:=xlPart, SearchOrder:=xlByColumns, MatchCase:=False, _
'SearchFormat:=False, ReplaceFormat:=False
End With
WB.SaveAs fileName:=ThisWorkbook.Path & "\Pedidos.csv", FileFormat:=xlCSV
WB.Close False
MsgBox "Após a pesquisa, foram feitas " & ReplaceCount & " substituições."
End Sub
Could you anyone tell me why this is not restraining replacement to the specified range?
Thank you!

How to compare two column values incrementally and copy entire row if the cells in those columns meet a condition

I am trying to compare two columns in one workbook and based on a certain condition copy the row where that condition is met to another workbook.
This is for a "database" I am working on. I have a Master sheet and then several versions of sub-masters that are catered specifically to certain individuals.
I have tried to some success by creating two different With statements and using a delete function on the sub-sheet but it is clunky and I'm not a fan of it. Please see the example code below.
Public Sub Workbook_Open()
Dim wb1 As Workbook, wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim copyFrom As Range
Dim lRow As Long
Dim strSearch As String
Dim vrtSelectedItem As Variant
Set wb1 = Application.Workbooks.Open("C:\Users\myfolder\Desktop\Excel Master Test\ROLE BASED TRACKER DRAFT.xlsx")
Set ws1 = wb1.Worksheets("Master")
Set wb2 = ThisWorkbook
Set ws2 = wb2.Worksheets("Sheet1")
'~~> Specifies which resources info. you are retrieving
strSearch = "117"
ws2.Cells.Clear
'~~> Copying the header information and formatting.
ws1.Range("1:1").Copy
ws2.Range("1:1").PasteSpecial
With ws1
'~~> Remove any filters
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("L1:L" & lRow)
.AutoFilter Field:=1, Criteria1:=strSearch
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End With
'~~> Destination File
With ws2
If Application.WorksheetFunction.CountA(.Rows) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
Else
lRow = .Range("A" & Rows.Count).End(xlUp).Row
End If
copyFrom.Copy .Rows(lRow)
End With
With ws2
'~~> Remove any filters
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("AD1:AD" & lRow)
.AutoFilter Field:=1, Criteria1:=strSearch
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
.AutoFilterMode = False
End With
With ws1
'~~> Remove any filters
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("AD1:AD" & lRow)
.AutoFilter Field:=1, Criteria1:=strSearch
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End With
'~~> Destination File
With ws2
If Application.WorksheetFunction.CountA(.Rows) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
Else
lRow = .Range("A" & Rows.Count).End(xlUp).Row
End If
copyFrom.Copy .Rows(lRow)
End With
With ws2.Sort
.SetRange Range("A2:A12000")
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
wb1.Save
wb1.Close
wb2.Save
End Sub
This is the code that I am trying to get work. I keep getting a Type Mismatch error on my cell comparison lines. '' If ws1.Range("AD1:AD" & lRow) <> ws1.Range("L1:L" & lRow) Then ''
Public Sub Workbook_Open()
Dim wb1 As Workbook, wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim copyFrom As Range
Dim lRow As Long
Dim strSearch As String
Dim vrtSelectedItem As Variant
Set wb1 = Application.Workbooks.Open("C:\Users\myfolder\Desktop\Excel Master Test\ROLE BASED TRACKER DRAFT.xlsx")
Set ws1 = wb1.Worksheets("Master")
Set wb2 = ThisWorkbook
Set ws2 = wb2.Worksheets("Sheet1")
'~~> Specifies which resources info. you are retrieving
strSearch = "117"
ws2.Cells.Clear
'~~> Copying the header information and formatting.
ws1.Range("1:1").Copy
ws2.Range("1:1").PasteSpecial
With ws1
'~~> Remove any filters
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
If ws1.Range("AD1:AD" & lRow) <> ws1.Range("L1:L" & lRow) Then
With .Range("AD1:AD" & lRow)
.AutoFilter Field:=1, Criteria1:=strSearch
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End If
End With
'~~> Destination File
With ws2
If Application.WorksheetFunction.CountA(.Rows) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
Else
lRow = .Range("A" & Rows.Count).End(xlUp).Row
End If
copyFrom.Copy .Rows(lRow)
End With
With ws1
'~~> Remove any filters
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
If ws1.Range("AD1:AD" & lRow) = ws1.Range("L1:L" & lRow) Then
With .Range("L1:L" & lRow)
.AutoFilter Field:=1, Criteria1:=strSearch
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End If
End With
'~~> Destination File
With ws2
If Application.WorksheetFunction.CountA(.Rows) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
Else
lRow = .Range("A" & Rows.Count).End(xlUp).Row
End If
copyFrom.Copy .Rows(lRow)
End With
With ws2.Sort
.SetRange Range("A2:A12000")
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
wb1.Save
wb1.Close
' wb2.Save
End Sub
I just wanted to thank everyone who helped. I am going to just stick with my initial solution of filter, copy, paste, filter, delete, filter, copy, paste, sort.
See my first code block for what I am talking about. Cheers.

If statement skipping outcome action

I've got a problem that I'm struggling to make sense of and I'm hoping you guys can assist.
My if statement is not executing the action for a true result and I'm not sure why. I have used a similar condition earlier in the code and there were no issues.
here's the section of the code that I'm struggling with:
Option Explicit
Option Base 1
Function binsearch(ByRef strArray() As String, ByRef strSearch As String) As Long
Dim lngIndex As Long
Dim lngFirst As Long
Dim lngLast As Long
Dim lngMiddle As Long
Dim bolInverseOrder As Boolean
lngFirst = LBound(strArray)
lngLast = UBound(strArray)
bolInverseOrder = (strArray(lngFirst) > strArray(lngLast))
binsearch = lngFirst - 1
Do
lngMiddle = (lngFirst + lngLast) \ 2
If strArray(lngMiddle) = strSearch Then
binsearch = lngMiddle
strSearch = strArray(lngMiddle)
Exit Do
ElseIf ((strArray(lngMiddle) < strSearch) Xor bolInverseOrder) Then
lngFirst = lngMiddle + 1
Else
lngLast = lngMiddle - 1
End If
Loop Until lngFirst > lngLast
End Function
Public Sub RE()
Dim MasterData As Variant, toFind As Variant, toFound As Variant
Dim WS As Worksheet, WS1 As Worksheet, WS2 As Worksheet, WS3 As Worksheet
Dim st_date As Date, end_date As Date, Tran_date As Date
Dim lastrow As Long, lastrow1 As Long, lastrow2 As Long, lastcol As Long, erow As Long, erow1 As Long, ecol As Long, Low As Long, Mid As Long, high As Long
Dim st_cell As Range, mydata As Range, DDT As Range, DDT1 As Range, DDT2 As Range
Dim Sheetname As String, Descr1 As String, Descr2() As String, Descr3() As String
Dim mydata1 As Variant, mydata2 As Variant, mydata3 As Variant
Dim amount1 As Currency, amount2 As Currency, amount3 As Currency
Dim i As Long
Application.ScreenUpdating = True
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;C:\Users\mpofa\Downloads\transactionHistory (1).csv", Destination:= _
Range("$A$1"))
.Name = "transactionHistory (1)_1"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(5, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
ActiveWorkbook.Sheets(ActiveSheet.Name).Name = "Main page"
Set WS = Sheets("main page")
Set st_cell = Sheets("main page").Range("A2")
lastrow = WS.Cells(WS.Rows.Count, st_cell.Column).End(xlUp).row
lastcol = WS.Cells(st_cell.row, WS.Columns.Count).End(xlToLeft).Column
Columns("A:A").Select
ActiveWorkbook.Worksheets("main page").sort.SortFields.Clear
ActiveWorkbook.Worksheets("main page").sort.SortFields.Add Key:=Range("A1"), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("main page").sort
.SetRange Range("A:D")
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Dim x As Long
For x = 0 To -2 Step -1
end_date = Sheets("main page").Range("A2").Value
st_date = DateAdd("m", x, end_date)
Worksheets.Add after:=Sheets("main page")
Dim p As Long, q As Long, y As Long
p = Worksheets.Count
For q = 1 To p
With Worksheets(q)
Sheetname = Format(st_date, "yyyy-mmm")
ActiveSheet.Name = Sheetname
End With
Sheets("Main page").Select
Range("A1:C1").Select
Selection.Copy
Sheets(Sheetname).Select
Range("A1").Select
ActiveSheet.Paste
Columns("A:A").Select
Selection.NumberFormat = "yyyy/mm/dd"
Columns("C:C").Select
Selection.NumberFormat = "R#,##0.00_);(R#,##0.00)"
Worksheets("main page").Activate
Columns("A:A").Select
Selection.NumberFormat = "yyyy/mm/dd"
Range("A2").Select
For i = 2 To lastrow
Tran_date = WS.Cells(i, 1)
If Month(Tran_date) = Month(st_date) Then
erow = Sheets(Sheetname).Cells(1, 1).CurrentRegion.Rows.Count + 1
Sheets(Sheetname).Cells(erow, 1) = WS.Cells(i, "a")
Sheets(Sheetname).Cells(erow, 2) = WS.Cells(i, "b")
Sheets(Sheetname).Cells(erow, 3) = WS.Cells(i, "c")
ecol = Sheets(Sheetname).Cells(2, Columns.Count).End(xlToLeft).Offset(0, 1).Column
End If
Sheets(Sheetname).Select
Columns("A:A").Select
Columns("A:A").EntireColumn.AutoFit
Columns("B:B").Select
Columns("B:B").EntireColumn.AutoFit
Columns("C:C").Select
Columns("C:C").EntireColumn.AutoFit
Next i
Next q
Next x
Sheets.Add after:=Sheets(Sheets.Count)
Sheets(ActiveSheet.Name).Name = "Report"
Sheets("Report").Range("A1") = "Description"
Sheets("Report").Range("B1") = "Amount"
erow1 = Sheets("report").Cells(1, 1).CurrentRegion.Rows.Count + 1
Set WS1 = ThisWorkbook.Sheets(2)
Set WS2 = ThisWorkbook.Sheets(3)
Set WS3 = ThisWorkbook.Sheets(4)
With WS1.Range("B:B")
.sort key1:=WS1.Range("B1"), Header:=xlYes
Set mydata1 = Range(.Cells(2, 2), .Cells(.Rows.Count, 1).End(xlUp))
End With
MasterData = mydata1.Value
Set DDT = WS1.Range("B2")
lastrow = WS1.Cells(WS1.Rows.Count, DDT.Column).End(xlUp).row
With WS2.Range("B:B")
.sort key1:=WS2.Range("B1"), Header:=xlYes
End With
Set DDT1 = WS2.Range("B2")
lastrow1 = WS2.Cells(WS2.Rows.Count, DDT1.Column).End(xlUp).row
With WS3.Range("B:B")
.sort key1:=WS3.Range("B1"), Header:=xlYes
End With
Set DDT2 = WS3.Range("B2")
lastrow2 = WS3.Cells(WS3.Rows.Count, DDT2.Column).End(xlUp).row
For Each WS In ThisWorkbook.Sheets
Do While WS.Name <> "main page"
For i = 2 To lastrow
Descr1 = WS1.Cells(i, 2).Text
' Set mydata2 = Range(.Cells(2, 2), .Cells(.Rows.Count, 1).End(xlUp))
For p = 2 To lastrow1
ReDim Descr2(p)
Descr2(p) = WS2.Cells(p, 2).Text
ReDim Preserve Descr2(p)
Call binsearch(Descr2(), Descr1)
' Set mydata3 = Range(.Cells(2, 2), .Cells(.Rows.Count, 1).End(xlUp))
For q = 2 To lastrow2
ReDim Descr3(q)
Descr3(q) = WS3.Cells(q, 2).Text
ReDim Preserve Descr3(q)
Call binsearch(Descr3(), Descr1)
If binsearch(Descr3(), Descr1) = 1 Then
Descr1 = Trim(Descr3(q))
Else
End If
If binsearch(Descr3(), Descr1) = 1 Then
Descr1 = Trim(Descr3(q))
Else
End If
If Descr1 = Trim(Descr3(q)) & Descr1 = Trim(Descr2(p)) Then
Sheets("report").Cells(erow1, 1) = WS1.Cells(i, "b")
Sheets("report").Cells(erow1, 2) = WS1.Cells(i, "c")
End If
Next q
Next p
Next i
Loop
Next WS
Sheets("Report").Select
Columns("A:A").Select
Columns("A:A").EntireColumn.AutoFit
Columns("B:B").Select
Columns("B:B").EntireColumn.AutoFit
End Sub
I'm getting a true condition but the cells information is not coming through into the intended sheet. I'm really stunned, please help.
Thanks in advance.
The answer is that this code is incomplete and could not run: you have not defined the loops. Please try "Debug --> Compile VBAProject"; when you get no errors there and still not the performance you look for then ask again.

Macro creating a new workbork instead of adding a sheet

The following Macro was intended to get specific data for a date range. While it does this, I wanted it displayed within the same workbook on another sheet, instead a new workbook is created. Any idea on how I can fix this?
Public Sub PromptUserForInputDates()
Dim strStart As String, strEnd As String, strPromptMessage As String
strStart = InputBox("Please enter the start date")
If Not IsDate(strStart) Then
strPromptMessage = "Not Valid Date"
MsgBox strPromptMessage
Exit Sub
End If
strEnd = InputBox("Please enter the end date")
If Not IsDate(strStart) Then
strPromptMessage = "Not Valid Date"
MsgBox strPromptMessage
Exit Sub
End If
Call CreateSubsetWorkbook(strStart, strEnd)
End Sub
Public Sub CreateSubsetWorkbook(StartDate As String, EndDate As String)
Dim wbkOutput As Workbook
Dim wksOutput As Worksheet, wks As Worksheet
Dim lngLastRow As Long, lngLastCol As Long, lngDateCol As Long
Dim rngFull As Range, rngResult As Range, rngTarget As Range
lngDateCol = 4
Set wbkOutput = Workbooks.Add
For Each wks In ThisWorkbook.Worksheets
With wks
Set wksOutput = wbkOutput.Sheets.Add
wksOutput.Name = wks.Name
Set rngTarget = wksOutput.Cells(1, 1)
lngLastRow = .Cells.Find(What:="*", LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious).Row
lngLastCol = .Cells.Find(What:="*", LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious).Column
Set rngFull = .Range(.Cells(1, 1), .Cells(lngLastRow, lngLastCol))
With rngFull
.AutoFilter Field:=lngDateCol, _
Criteria1:=">=" & StartDate, _
Criteria2:="<=" & EndDate
Set rngResult = rngFull.SpecialCells(xlCellTypeVisible)
rngResult.Copy Destination:=rngTarget
End With
.AutoFilterMode = False
If .FilterMode = True Then
.ShowAllData
End If
End With
Next wks
MsgBox "Data Transferred!"
End Sub
You're defining Set wbkOutput = Workbooks.Add which will always create a new workbook. Instead, Set wbkOutput = the workbook where you want the output to be.
Note that your assignment of wksOutput.Name = wks.Name will fail (two worksheets cannot have same name), so I've commented it out for now and you can revise that statement as needed.
Replace all references to wbkOutput with ThisWorkbook
Public Sub CreateSubsetWorkbook(StartDate As String, EndDate As String)
Dim wksOutput As Worksheet, wks As Worksheet
Dim lngLastRow As Long, lngLastCol As Long, lngDateCol As Long
Dim rngFull As Range, rngResult As Range, rngTarget As Range
lngDateCol = 4
For Each wks In ThisWorkbook.Worksheets
With wks
Set wksOutput = ThisWorkbook.Sheets.Add
' This is not allowed, you can make some change to the name but it cannot be the same name worksheet
' >>> wksOutput.Name = wks.Name
Set rngTarget = wksOutput.Cells(1, 1)
lngLastRow = .Cells.Find(What:="*", LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious).Row
lngLastCol = .Cells.Find(What:="*", LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious).Column
Set rngFull = .Range(.Cells(1, 1), .Cells(lngLastRow, lngLastCol))
With rngFull
.AutoFilter Field:=lngDateCol, _
Criteria1:=">=" & StartDate, _
Criteria2:="<=" & EndDate
Set rngResult = rngFull.SpecialCells(xlCellTypeVisible)
rngResult.Copy Destination:=rngTarget
End With
.AutoFilterMode = False
If .FilterMode = True Then
.ShowAllData
End If
End With
Next wks
End Sub

Resources