i have a code that has a command button which retrieves its records from an external file.
every time the command button is clicked it will delete all the records and paste again. however it allows the user input for records with "OFM","KH" and "Collar & Cuff" hence it would not delete these rows.
But, my autofilter code is not working properly as it still deletes the rows with "OFM" and "KH""
Rows.Count).CurrentRegion.SpecialCells(xlCellTypeVisible).AutoFilter
field:=1, Criteria1:="<>OFM", Operator:=xlOr, Criteria2:="<>KH"
the code:
Sub July()
Dim arr, c, b(), n&
Application.ScreenUpdating = False
Worksheets("July 2018").Range("A4").AutoFilter
Workbooks.Open "C:\Users\sophia.tan\Desktop\MasterPlanData.xlsx", 0, 1
arr = Sheets("Excel").UsedRange
ActiveWorkbook.Close 0
c = Array(0, 2, 13, 14, 7, 8, 11, 1, 9, 10, 16, 17, 20, 22, 15, 30, 27, 28,
29, 3, 4, 39)
d = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19,
20, 21, 23)
ReDim b(1 To UBound(arr), 1 To 23)
For i = 2 To UBound(arr)
If arr(i, 13) >= DateSerial(Year:=2018, Month:=7, Day:=1) And arr(i, 12) <=
DateSerial(Year:=2018, Month:=7, Day:=31) Then
n = n + 1
For j = 1 To UBound(c)
b(n, d(j)) = arr(i, c(j))
Next
End If
Next
With Worksheets("July 2018")
.Range("A4:W" &
Rows.Count).CurrentRegion.SpecialCells(xlCellTypeVisible).AutoFilter
field:=13, Criteria1:="<>Collar & Cuff"
.Range("A4:W" &
Rows.Count).CurrentRegion.SpecialCells(xlCellTypeVisible).AutoFilter
field:=1, Criteria1:="<>OFM", Operator:=xlOr, Criteria2:="<>KH"
.Range("A4:W" & Rows.Count).CurrentRegion.Offset(1,
0).SpecialCells(xlCellTypeVisible).ClearContents
.Range("A4:W" & Rows.Count).Resize(UBound(b, 1), UBound(b, 2)) = b
.AutoFilter.ShowAllData
.Range("A4").CurrentRegion.Sort key1:=Range("G3"), order1:=xlAscending,
Header:=xlYes
.Range("A4").Select
End With
Call Fabrication
Application.ScreenUpdating = 1
End Sub
Your two-criteria-for-one-field AutoFilter logic is flawed. When something is not KH it can be OFM and when something is not OFM it can be KH. I believe you want to filter for not KH and not OFM.
tldr;
You need xlAnd, not xlOr.
'...
With Worksheets("July 2018")
If .AutoFilterMode Then .AutoFilterMode = False
With .Range("A4").CurrentRegion
.AutoFilter Field:=13, Criteria1:="<>Collar & Cuff"
.AutoFilter Field:=1, Criteria1:="<>OFM", Operator:=xlAnd, Criteria2:="<>KH" '<~~ THIS RIGHT HERE
With .Resize(.Rows.Count - 1, .Columns.Count).Offset(1, 0)
If CBool(Application.Subtotal(103, .Cells)) Then
.SpecialCells(xlCellTypeVisible).ClearContents
End If
End With
.Cells.Sort key1:=.Columns("G"), Order1:=xlAscending, Header:=xlYes
End With
'...
.AutoFilter.ShowAllData
.Range("A4").Select
End With
Related
I have a spreadsheet like this, and I would like to have a function that returns the list of row numbers non-empty cells in column B. In this case, it should return "2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 22, 23, 25, 26)
How do I do this in VBA?
Function GetEmptyCount()
Dim arr(), x&, cell
With Range("B1:B" & Cells(Rows.Count - 1, "B").End(xlUp).Row)
For Each cell In .SpecialCells(xlCellTypeBlanks).Cells
x = x + 1
ReDim Preserve arr(1 To x)
arr(x) = cell.Row
Next
End With
GetEmptyCount = arr
End Function
Sub Test()
Dim x, c
x = GetEmptyCount()
For Each c In x: MsgBox c: Next
End Sub
You can check the length of the cell value something like
IF(Length(Cell) > 0 THEN
// Include the row
ELSE
// skip the row
there I have an excel VBA code that retrieves its records from an external file by month and set it according to the column heading.
However, i have an error in of application-defined or object-defined error in of the line .Range("A6").Resize(n, 23) = b
does anyone know why
code:
Sub zz()
Dim arr, c, b(), n&
Application.ScreenUpdating = False
Worksheets("Sheet2").Range("A6").AutoFilter
Workbooks.Open "C:\Users\sophia.tan\Desktop\MasterPlanData.xlsx", 0, 1
arr = Sheets("Excel").UsedRange
ActiveWorkbook.Close 0
c = Array(0, 2, 13, 14, 7, 8, 11, 1, 9, 10, 16, 17, 20, 22, 15, 30, 27, 28, 29, 3, 4, 30)
d = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23)
ReDim b(1 To UBound(arr), 1 To 23)
For i = 2 To UBound(arr)
If arr(i, 12) >= DateSerial(Year:=2017, Month:=11, Day:=1) And arr(i, 12) <= DateSerial(Year:=2017, Month:=11, Day:=31) Then
n = n + 1
For j = 1 To UBound(c)
b(n, d(j)) = arr(i, c(j))
Next
End If
Next
With Worksheets("Sheet2")
.Range("A6:T" & Rows.Count).CurrentRegion.AutoFilter field:=1, Criteria1:="<>OFM"
.Range("A6:T" & Rows.Count).CurrentRegion.SpecialCells(xlCellTypeVisible).AutoFilter field:=13, Criteria1:="<>Collar & Cuff"
.Range("A6:T" & Rows.Count).CurrentRegion.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.Range("A6").Resize(n, 23) = b
.Range("A6").CurrentRegion.Sort key1:=Range("G6"), order1:=xlAscending, Header:=xlYes
.Range("A6").Select
End With
Application.ScreenUpdating = 1
End Sub
Your determination on n is subjective to the If statement. However, any unfilled values in the 'rows' of b will be vbnullstrings and will produce truly blank cells.
.Range("A6").Resize(ubound(b, 1), ubound(b, 2)) = b
Alternately,
For i = 2 To UBound(arr)
If arr(i, 12) >= DateSerial(Year:=2017, Month:=11, Day:=1) And arr(i, 12) <= DateSerial(Year:=2017, Month:=11, Day:=31) Then
n = n + 1
For j = 1 To UBound(c)
b(n, d(j)) = arr(i, c(j))
Next
End If
Next
b = application.transpose(b)
redim preserve b(lbound(b, 1) to ubound(b, 1), lbound(b, 2) to n)
b = application.transpose(b)
.Range("A6").Resize(n, 23) = b
You can only adjust the last rank of an array with ReDim when using the preserve parameter.
Try
.Range("A6").Resize(n, 23).Value = b
I have an Excel VBA code that retrieves data from an external workbook into a worksheet by month.
I would like to retrieve the month of November but I can't seem to type the date to be #30/11/2017#. The date would automatically change to #11/30/2017#.
The date has to be in dd/mm/yyyy as that is the format of date in the external workbook.
Sub zz()
Dim arr, c, b(), n&
Application.ScreenUpdating = False
Worksheets("Sheet2").Range("A6").AutoFilter
Workbooks.Open "C:\Users\sophia.tan\Desktop\excel masterplan\External
workbook.xlsx", 0, 1
arr = Sheets("MaximMainTable").UsedRange
ActiveWorkbook.Close 0
c = Array(0, 2, 12, 13, 6, 7, 10, 1, 8, 9, 15, 16, 18, 19, 14, 27, 24, 25,
26, 3, 4, 36)
d = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19,
20, 21, 23)
ReDim b(1 To UBound(arr), 1 To 23)
Selection.NumberFormat = "dd/mm/yyyy"
For i = 2 To UBound(arr)
If arr(i, 12) >= (#1/11/2017#) And arr(i, 12) <= Format(#11/30/2017#) Then
n = n + 1
For j = 1 To UBound(c)
b(n, d(j)) = arr(i, c(j))
Next
End If
Next
Dim startRow As Long, lastRow2 As Long
startRow = 6
lastRow = Cells(Cells.Rows.Count, 1).End(xlUp).Row
For i = startRow To lastRow
If Range("A" & i) Like "MX*" Then
If Range("J" & i) Like "*Rib*" Then
Range("M" & i) = "Rib"
ElseIf Range("J" & i) Like "*Spandex*Pique*" Then
Range("M" & i) = "Spandex Pique"
ElseIf ("J" & i) Like "*Pique*" Then
Range("M" & i) = "Pique"
ElseIf ("J" & i) Like "*Spandex*Jersey*" Then
Range("M" & i) = "Spandex Jersey"
ElseIf Range("J" & i) Like "*Jersey*" Then
Range("M" & i) = "Jersey"
ElseIf ("J" & i) Like "*Interlock*" Then
Range("M" & i) = "Interlock"
ElseIf ("J" & i) Like "*French*Terry*" Then
Range("M" & i) = "Fleece"
ElseIf ("J" & i) Like "*Fleece*" Then
Range("M" & i) = "Fleece"
Else
Range("M" & i) = "Collar & Cuff"
End If
End If
Next
With Worksheets("Sheet2")
.Range("A6:T" & Rows.Count).CurrentRegion.AutoFilter field:=1, Criteria1:="
<>OFM"
.Range("A6:T" &
Rows.Count).CurrentRegion.SpecialCells(xlCellTypeVisible).AutoFilter
field:=13, Criteria1:="<>Collar & Cuff"
.Range("A6:T" & Rows.Count).CurrentRegion.Offset(1,
0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.Range("A6").Resize(n, 23) = b
.Range("A5").CurrentRegion.Sort key1:=Range("G5"), order1:=xlAscending,
Header:=xlYes
End With
Application.ScreenUpdating = 1
End Sub
When you use #date# notation directly, VBA expects it in mm/DD/yyyy format.
To test if a date on your worksheet is in the month of November 2017:
If arr(i, 12) >= #11/1/2017# And arr(i, 12) <= #11/30/2017# Then
'do whatever
End If
So long as the dates in Excel are "real dates", the format of the date in the worksheet cell is irrelevant.
If the dates in Excel are text, you will need to convert them to real dates before you do the comparison. Whether you do that on the worksheet, or in your code, is irrelevant.
For the date literal in your code, you can substitute other variables that resolve to a VBA Date data type. Note that if you convert a String, the String must be in an unambiguous format (one that can only be interpreted one way).
DateSerial(2017, 11, 1)
CDate("2017-11-01")
CDate("1 Nov 2017")
Hi all I hope you can help. I have a piece of code see below.
What I am trying to achieve is that a user opens up an Excel sheet that contains a command button and instructions.
Once the command button is clicked a dialog box opens up which then allows the user to select another excel sheet, once that excel sheet is selected another piece of code (should) fire and duplicates are consolidated and start dates and end dates are amended, and the sheet is left open in its desired state free of duplicates and dates correct.
The piece of code
Public Sub ConsolidateDupes()
works perfectly when it is run by itself, on the original sheet but when I try to call it with the command button , its is not working correctly. No error appears it just does not remove all the possible duplicates and does not work the dates to the earliest start and latest end date
I have added pictures to make explanation easier
Pic 1
Excel sheet with Command Button
Pic 2 the Sheet to be selected in its original state with Duplicates and multiple start and end dates
The selected sheet after code has been run by itslef on that sheet
The selected sheet when it is called when command button is used
As you can hopefully see the Duplicates are left and the dates are not worked to the earliest start date and latest end date
As i said the code works perfectly when run on the sheet by itself but when it is called it leaves duplicates and is not working the start and end dates
Here is my code any help is as always greatly appreciated.
CODE
Sub Open_Workbook_Dialog()
Dim my_FileName As Variant
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
my_FileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
If my_FileName <> False Then
Workbooks.Open Filename:=my_FileName
Call ConsolidateDupes '<--|Calls the Filter Code and executes
End If
End Sub
Public Sub ConsolidateDupes()
Dim wks As Worksheet
Dim lastRow As Long
Dim r As Long
Set wks = Sheet1
lastRow = wks.UsedRange.Rows.Count
For r = lastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If wks.Cells(r, 8) < wks.Cells(r - 1, 8) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If wks.Cells(r, 9) > wks.Cells(r - 1, 9) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
Can you delete this:
Rows(r).Delete
And write this instead:
wks.Rows(r).Delete
Edit:
Try this:
(very dirty solution, but it should work)
Sub Open_Workbook_Dialog()
Dim strFileName As string
dim wkb as workbook
Dim wks As Worksheet
Dim lastRow As Long
Dim r As Long
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
strFileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
set wkb = Application.Workbooks.Open(strFileName)
Set wks = wkb.Sheet1
lastRow = wks.UsedRange.Rows.Count
For r = lastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If wks.Cells(r, 8) < wks.Cells(r - 1, 8) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If wks.Cells(r, 9) > wks.Cells(r - 1, 9) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
However, the problem is that it did not work, because you did not pass the my_FileName to the ConsolidateDupes procedure. Thus, the procedure was executing in the file with the button, and it was a bit meaningless there.
Hi so some changes were need to get this to work and the code that works is below I hope it helps a fellow VBA'r out :-)
Sub Open_Workbook_Dialog()
Dim strFileName As String
Dim wkb As Workbook
Dim wks As Worksheet
Dim LastRow As Long
Dim r As Long
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
strFileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
Set wkb = Application.Workbooks.Open(strFileName)
Set wks = ActiveWorkbook.Sheets(1)
LastRow = wks.UsedRange.Rows.Count
' Sort the B Column Alphabetically
With ActiveWorkbook.Sheets(1)
Dim LastRow2 As Long
LastRow2 = .Cells(Rows.Count, 1).End(xlUp).Row
Dim LastCol As Long
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SortFields.Clear
.SortFields.Add Key:=Range(Cells(2, 2), Cells(LastRow, 2)), _
SortOn:=xlSortOnValues, _
Order:=xlAscending, _
DataOption:=xlSortNormal
.SetRange Range(Cells(2, 1), Cells(LastRow, LastCol))
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
For r = LastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If CDate(wks.Cells(r, 8)) < CDate(wks.Cells(r - 1, 8)) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If CDate(wks.Cells(r, 9)) > CDate(wks.Cells(r - 1, 9)) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
Basically, I am trying to pull the data from an Excel file to this worksheet (Auto_Update Sub) and the code is described below:
Sub Auto_Update()
Dim filename As String
Dim r As Integer
Dim i As Double
Dim t As Integer
Dim DPR As Object
Dim new_DPR As Object
Dim well As Object
Dim x As Integer
If IsEmpty(ThisWorkbook.Sheets("SD-28P").Cells(1, 35)) = True Then
ThisWorkbook.Sheets("SD-28P").Cells(1, 35) = Date - 2
End If
Excel.Application.Visible = False
For i = Date - ThisWorkbook.Sheets("SD-28P").Cells(1, 35) To 1 Step -1
filename = "Z:\DPR\DPR_" + Format(Date - i, "yyyymmdd") + ".xls"
Set DPR = Excel.Application.Workbooks.Open(filename)
Set new_DPR = DPR.Worksheets("Daily Production Report")
For x = 247 To 272 Step 1
If Trim(new_DPR.Cells(x, 2).Value) = "SD-01PST" Then t = x
Exit For
For r = t To t + 35 Step 1
Set well = ThisWorkbook.Worksheets(Trim(new_DPR.Cells(r, 2).Value))
f = First_Empty(well, 4)
If new_DPR.Cells(r, 6).Value = Date - i Then
new_DPR.Cells(r, 6).Copy
well.Cells(f, 1).PasteSpecial (xlPasteValues)
new_DPR.Cells(r, 8).Copy
well.Cells(f, 3).PasteSpecial (xlPasteValues)
new_DPR.Cells(r, 10).Copy
well.Cells(f, 4).PasteSpecial (xlPasteValues)
new_DPR.Range(new_DPR.Cells(r, 12), new_DPR.Cells(r, 17)).Copy
well.Range(well.Cells(f, 5), well.Cells(f, 10)).PasteSpecial (xlPasteValues)
new_DPR.Range(new_DPR.Cells(r, 20), new_DPR.Cells(r, 26)).Copy
well.Range(well.Cells(f, 11), well.Cells(f, 17)).PasteSpecial (xlPasteValues)
new_DPR.Range(new_DPR.Cells(r, 28), new_DPR.Cells(r, 30)).Copy
well.Range(well.Cells(f, 18), well.Cells(f, 20)).PasteSpecial (xlPasteValues)
well.Range(well.Cells(f - 1, 2), well.Cells(f - 1, 22)).Copy
well.Range(well.Cells(f, 2), well.Cells(f, 22)).PasteSpecial (xlPasteFormats)
well.Cells(f - 1, 1).Copy
well.Cells(f, 1).PasteSpecial (xlPasteFormulasAndNumberFormats)
End If
Next r
Excel.Application.CutCopyMode = False
DPR.Saved = True
DPR.Close
ThisWorkbook.Application.CutCopyMode = False
Next i
ThisWorkbook.Sheets("SD-28P").Cells(1, 35) = Date
ThisWorkbook.Save
Excel.Application.Visible = True
ThisWorkbook.Sheets(4).Activate
But then, the code returns an error at the line: Next i (Invalid Next Control Variable Reference). I double checked the variable and the syntacx of the For ... Next loop, however, I couldn't not find any possible error. Please kindly help! Thank you very much in advance.
You never close the loop that starts with
For x = 247 To 272 Step 1
If Trim(new_DPR.Cells(x, 2).Value) = "SD-01PST" Then t = x
Exit For
You need a next x somewhere before you can use a next i.