excel vba read date as dd/mm/yyy - vba

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")

Related

Excel VBA - Selecting random rows based on multiple criteria

I have the below code set which takes a list of ticket data, and randomly selected three rows based on the username in Col D.
However, with a recent change in our ticketing system, I now need to update it to not select certain tickets. Specifically, I need only INC and SCTASK tickets to be selected, and not RITM tickets.
I am not quite sure how to add the filter so that tickets with RITM in the ticket number (ticket numbers are in Col A) are not included in this search.
Sub DailyTicketAudit()
'Set parameters and variables
Const sDataSheet As String = "Page 1"
Const sUserCol As String = "D"
Const lHeaderRow As Long = 1
Const lShowRowsPerUser As Long = 3
Const bSortDataByUser As Boolean = False
Dim wb As Workbook, ws As Worksheet
Dim rData As Range, rShow As Range
Dim aData() As Variant, aUserRows() As Variant
Dim i As Long, j As Long, k As Long, lRandIndex As Long, lTotalUnqUsers As Long, lMaxUserRows As Long
Set wb = Workbooks.Open("D:\Users\stefan.bagnato\Desktop\Raw Data Files\Audit Tickets Created")
Set ws = ActiveWorkbook.Sheets(sDataSheet)
Sheets("Page 1").name = "Audit Tickets"
'Work with the data range set by parameters
With ws.Range(sUserCol & lHeaderRow + 1, ws.Cells(ws.Rows.Count, sUserCol).End(xlUp))
If .Row < lHeaderRow + 1 Then
MsgBox "No data found in [" & sDataSheet & "]" & Chr(10) & _
"Verify column containing users is Column [" & sUserCol & "] or correct sUserCol in code." & Chr(10) & _
"Verify header row is Row [" & lHeaderRow & "] or correct lHeaderRow in code." & Chr(10) & _
"Once corrections have been made and data is available, try again."
Exit Sub
End If
lTotalUnqUsers = Evaluate("SUMPRODUCT((" & .Address(external:=True) & "<>"""")/COUNTIF(" & .Address(external:=True) & "," & .Address(external:=True) & "&""""))")
lMaxUserRows = Evaluate("max(countif(" & .Address(external:=True) & "," & .Address(external:=True) & "))")
If bSortDataByUser Then .Sort .Cells, xlAscending, Header:=xlNo
Set rData = .Cells
aData = .Value
ReDim aUserRows(1 To lTotalUnqUsers, 1 To 3, 1 To lMaxUserRows)
End With
'Load all available rows into the results array, grouped by the user
For i = LBound(aData, 1) To UBound(aData, 1)
For j = LBound(aUserRows, 1) To UBound(aUserRows, 1)
If IsEmpty(aUserRows(j, 1, 1)) Or aUserRows(j, 1, 1) = aData(i, 1) Then
If IsEmpty(aUserRows(j, 1, 1)) Then aUserRows(j, 1, 1) = aData(i, 1)
k = aUserRows(j, 2, 1) + 1
aUserRows(j, 2, 1) = k
aUserRows(j, 3, k) = i + lHeaderRow
Exit For
End If
Next j
Next i
'Select random rows up to lShowRowsPerUser for each user from the grouped results array
For j = LBound(aUserRows, 1) To UBound(aUserRows, 1)
Do
Randomize
lRandIndex = Int(Rnd() * aUserRows(j, 2, 1)) + 1
If Not rShow Is Nothing Then
Set rShow = Union(rShow, ws.Cells(aUserRows(j, 3, lRandIndex), sUserCol))
Else
Set rShow = ws.Cells(aUserRows(j, 3, lRandIndex), sUserCol)
End If
Loop While rShow.Cells.Count < j * Application.Min(lShowRowsPerUser, aUserRows(j, 2, 1))
Next j
rData.EntireRow.Hidden = True
rShow.EntireRow.Hidden = False
'Format table
'Sort by Opened By
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
Worksheets("Audit Tickets").Sort.SortFields.Add Key:=Range("D1"), SortOn:=xlSortOnValues, Order:=xlAscending
With Worksheets("Audit Tickets").Sort
.SetRange Range("A2:G" & LastRow)
.Orientation = xlTopToBottom
.Apply
End With
'Widen columns
Range("A:B,G:G").ColumnWidth = 15
Columns("C:D").ColumnWidth = 18
Columns("E:E").ColumnWidth = 50
Columns("F:F").ColumnWidth = 22
'Wrap text
Range("E1:E" & LastRow).WrapText = True
End Sub
Far more efficient, assuming aData holds all the data and the first column is tickets, is to simply process only the two of interest with the following.
Change 1 in aData(i, 1) to whichever column holds the items of interest in the array.
For i = LBound(aData, 1) To UBound(aData, 1)
If aData(i, 1) = "INC" Or aData(i, 1) = "SCTASK" Then
For j = LBound(aUserRows, 1) To UBound(aUserRows, 1)
''other code
End If
Next i
You could use advanced filter:
Sheets("Emps").Range("A1:D8").AdvancedFilter Action:=xlFilterCopy, _
CriteriaRange:=Sheets("Emps").Range("F5:F6"), CopyToRange:=Range("A1:B1"), _
Unique:=False
Data to selectively copy:
Data copied:
Reference this short YouTube video; You can record a marco to help yourself with the code also:
https://www.youtube.com/watch?v=bGUKjXmEi2E
A more thorough tutorial is found here:
http://www.contextures.com/xladvfilter01.html
This tutorial shows how to get the source data from outside Excel:
https://www.extendoffice.com/documents/excel/4189-excel-dynamic-filter-to-new-sheet.html
This tutorial shows how to split data values based on a column to different sheets (Fruit column; Apple sheet, Pear sheet, etc.):
https://www.extendoffice.com/documents/excel/2884-excel-save-filtered-data-new-sheet-workbook.html

VBA Excel Sum of Decimal

Source code:
Dim TH As Double
Lr = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
'starting point
sRow = 2
'Loop in all cells
For i = sRow To Lr
'check if cell value are not same
If Cells(i, 1).Value <> Cells(i + 1, 1) Then
'if not same then merge all the above cells
Range("I" & sRow, "I" & i).Resize(, 7).Select
TH = Application.WorksheetFunction.Sum(Selection)
**If TH <> 40 Then**
Range("A" & sRow, "A" & i).Interior.Color = RGB(255, 0, 0)
End If
In this Code:
If TH <> 40 Then condition not working when ever the TH is Calculated on Decimal Numbers.
Such as 3.60,0.80,4.60 Sum is coming as 40 when use SUM Function but If Condition is not getting fulfilled.
Please Help
I have tried this, putting decimals all over and it works:
Sub TestMe()
Dim lr As Long
Dim TH As Double
Dim i As Long
lr = 10
For i = 1 To lr
If Cells(i, 1).Value <> Cells(i + 1, 1) Then
Range("I" & 6, "I" & i).Resize(, 7).Select
TH = Application.WorksheetFunction.Sum(Selection)
If TH <> 40 Then
Range("A" & 6, "A" & i).Interior.Color = RGB(255, 0, 0)
End If
End If
Next
End Sub
Thus, probably the problem is the way you put the decimals. In some systems (German or French), the decimal separator is ,, while in English systems it is a point - .. Thus, you might be using the wrong one.

Repeating an IF statement with multiple variables

I have a macro that adds 1 to a cell in Column 53 (Column BA) if the row below it has a cell that contains a bracketed number "(2)" and another cell that contains the word "Adult".
It goes like this:
Sub BUBFindAdults2()
lastRow = Sheets("Sheet1").Range("C" & Rows.Count).End(xlUp).Row
For x = 3 To lastRow
If InStr(1, Sheets("Sheet1").Cells(x, 3), "(2)") <> 0 _
And InStr(1, Sheets("Sheet1").Cells(x, 31), "Adult") <> 0 Then
Sheets("Sheet1").Cells(x - 1, 53).Value = _
Sheets("Sheet1").Cells(x - 1, 53).Value + 1
End If
Next x
End Sub
However, I also need it to add 1 to the same cell if two rows below contains "(3)" and "Adult". And if three rows below contains "(4)" and "Adult". And so on. You see the pattern!
So far, I've got around this by just repeating the same code as follows:
Sub BUBFindAdults2()
lastRow = Sheets("Sheet1").Range("C" & Rows.Count).End(xlUp).Row
For x = 3 To lastRow
If InStr(1, Sheets("Sheet1").Cells(x, 3), "(2)") <> 0 _
And InStr(1, Sheets("Sheet1").Cells(x, 31), "Adult") <> 0 Then
Sheets("Sheet1").Cells(x - 1, 53).Value = _
Sheets("Sheet1").Cells(x - 1, 53).Value + 1
End If
If InStr(1, Sheets("Sheet1").Cells(x, 3), "(3)") <> 0 _
And InStr(1, Sheets("Sheet1").Cells(x, 31), "Adult") <> 0 Then
Sheets("Sheet1").Cells(x - 2, 53).Value = _
Sheets("Sheet1").Cells(x - 2, 53).Value + 1
End If
If InStr(1, Sheets("Sheet1").Cells(x, 3), "(4)") <> 0 _
And InStr(1, Sheets("Sheet1").Cells(x, 31), "Adult") <> 0 Then
Sheets("Sheet1").Cells(x - 3, 53).Value = _
Sheets("Sheet1").Cells(x - 3, 53).Value + 1
End If
Next x
End Sub
You can probably tell that this starts to get a bit silly when I'm dealing with 10+ repetitions! I know one of the main rules of writing VBA is avoiding repeated code. I've looked at a few other examples of people looping their code but I haven't had any luck applying the methods to my own.
Any help would be much appreciated.
You can first use a filter on the column 31 to have only the rows where "Adult" appears. After that it becomes somehow simpler, and surely faster.
Sub BUBFindAdults2()
With Sheets("Sheet1").UsedRange
.AutoFilter 31, "*Adult*"
Dim r As Range, i As Integer
For Each r In .SpecialCells(xlCellTypeVisible).EntireRow
For i = 2 To 4
If r.Cells(3) Like "*(" & i & ")*" Then
With r.Offset(1 - i).Cells(53)
.Value = .Value + 1
End With
End If
Next
Next
.Parent.AutoFilterMode = False
End With
End Sub
I can't get your code to run, but this can easily be achieved using a nested for loop. See the below code, which will execute 10 repetitions, based on the code you provided in the question:
Sub BUBFindAdults2()
lastRow = Sheets("Sheet1").Range("C" & Rows.Count).End(xlUp).Row
For x = 3 To lastRow
If InStr(1, Sheets("Sheet1").Cells(x, 31), "Adult") <> 0 Then
For i = 1 To 10
If InStr(1, Sheets("Sheet1").Cells(x, 3), "(" & (i+1) & ")") <> 0 Then
Sheets("Sheet1").Cells(x - i, 53).Value = _
Sheets("Sheet1").Cells(x - i, 53).Value + 1
End If
Next i
End If
Next x
End Sub

Why my VBA code exits immediately depending on the active sheet?

I think this is more of an issue with excel options and stuff but I'm not sure. A description of my code: It takes time series data written in the first 8-9 tabs in a worksheet (each tab is a different indicator), and displays it in a row so that instead of data being written like in a time series format (1-1-2000 to 1-1-2015 for each indicator) all indicators (with three lags as well as 7 forward lags for the GGR tab) are written for a given date in a row Here is my code:
Sub stuff()
Dim rng1 As Range, rng2 As Range, rng3 As Range, rng4 As Range, rng5 As Range, rng6 As Range, rng7 As Range, rng8 As Range
Dim datenum As Long, Row As Integer, sorteddate As Variant, loc As Integer
Row = 2
For j = 2 To 53
For i = 8 To 275
If Not (IsEmpty(Cells(i, j).Value)) Then
Sheets("Sheet1").Cells(Row, 8) = Sheets("GGR").Cells(i - 1, j).Value
Sheets("Sheet1").Cells(Row, 9) = Sheets("GGR").Cells(i - 2, j).Value
Sheets("Sheet1").Cells(Row, 10) = Sheets("GGR").Cells(i - 3, j).Value
Sheets("Sheet1").Cells(Row, 29) = Sheets("GGR").Cells(i, j).Value
Sheets("Sheet1").Cells(Row, 30) = Sheets("GGR").Cells(i + 1, j).Value
Sheets("Sheet1").Cells(Row, 31) = Sheets("GGR").Cells(i + 2, j).Value
Sheets("Sheet1").Cells(Row, 32) = Sheets("GGR").Cells(i + 3, j).Value
Sheets("Sheet1").Cells(Row, 33) = Sheets("GGR").Cells(i + 4, j).Value
Sheets("Sheet1").Cells(Row, 34) = Sheets("GGR").Cells(i + 5, j).Value
Sheets("Sheet1").Cells(Row, 35) = Sheets("GGR").Cells(i + 6, j).Value
Sheets("Sheet1").Cells(Row, 36) = Sheets("GGR").Cells(i + 7, j).Value
datenum = Sheets("GGR").Cells(i, 1).Value
Sheets("Sheet1").Cells(Row, 1).Value = datenum
Set rng1 = Sheets("CPIC").Range("A1:A408")
sorteddate = rng1.Value
loc = BinarySearch(rng1, datenum)
Sheets("Sheet1").Cells(Row, 2) = Sheets("CPIC").Cells(loc, j).Value
Sheets("Sheet1").Cells(Row, 3) = Sheets("CPIC").Cells(loc - 1, j).Value
Sheets("Sheet1").Cells(Row, 4) = Sheets("CPIC").Cells(loc - 2, j).Value
Set rng2 = Sheets("GBGT").Range("A1:A71")
sorteddate = rng2.Value
loc = BinarySearch(rng2, datenum)
Sheets("Sheet1").Cells(Row, 5) = Sheets("GBGT").Cells(loc, j).Value
Sheets("Sheet1").Cells(Row, 6) = Sheets("GBGT").Cells(loc - 1, j).Value
Sheets("Sheet1").Cells(Row, 7) = Sheets("GBGT").Cells(loc - 2, j).Value
Set rng3 = Sheets("GFCF").Range("A5:A264")
sorteddate = rng3.Value
loc = BinarySearch(rng3, datenum)
Sheets("Sheet1").Cells(Row, 11) = Sheets("GFCF").Cells(loc, j).Value
Sheets("testsheet").Cells(1, 1).Value = loc
Sheets("Sheet1").Cells(Row, 12).Value = Sheets("GFCF").Cells(loc - 1, j).Value
Sheets("Sheet1").Cells(Row, 13).Value = Sheets("GFCF").Cells(loc - 2, j).Value
Set rng4 = Sheets("M1").Range("A1:A700")
sorteddate = rng4.Value
loc = BinarySearch(rng4, datenum)
Sheets("Sheet1").Cells(Row, 14) = Sheets("M1").Cells(loc, j).Value
Sheets("Sheet1").Cells(Row, 15) = Sheets("M1").Cells(loc - 1, j).Value
Sheets("Sheet1").Cells(Row, 16) = Sheets("M1").Cells(loc - 2, j).Value
Set rng5 = Sheets("M2").Range("A1:A676")
sorteddate = rng5.Value
loc = BinarySearch(rng5, datenum)
Sheets("Sheet1").Cells(Row, 17) = Sheets("M2").Cells(loc, j).Value
Sheets("Sheet1").Cells(Row, 18) = Sheets("M2").Cells(loc - 1, j).Value
Sheets("Sheet1").Cells(Row, 19) = Sheets("M2").Cells(loc - 2, j).Value
Set rng6 = Sheets("CSP").Range("A1:A264")
sorteddate = rng6.Value
loc = BinarySearch(rng6, datenum)
Sheets("Sheet1").Cells(Row, 20) = Sheets("CSP").Cells(loc, j).Value
Sheets("Sheet1").Cells(Row, 21) = Sheets("CSP").Cells(loc - 1, j).Value
Sheets("Sheet1").Cells(Row, 22) = Sheets("CSP").Cells(loc - 2, j).Value
Set rng7 = Sheets("UNR").Range("A1:A272")
sorteddate = rng7.Value
loc = BinarySearch(rng7, datenum)
Sheets("Sheet1").Cells(Row, 23) = Sheets("UNR").Cells(loc, j).Value
Sheets("Sheet1").Cells(Row, 24) = Sheets("UNR").Cells(loc - 1, j).Value
Sheets("Sheet1").Cells(Row, 25) = Sheets("UNR").Cells(loc - 2, j).Value
Set rng8 = Sheets("MKT").Range("A1:A223")
sorteddate = rng8.Value
loc = BinarySearch(rng8, datenum)
Sheets("Sheet1").Cells(Row, 26) = Sheets("MKT").Cells(loc, j).Value
Sheets("Sheet1").Cells(Row, 27) = Sheets("MKT").Cells(loc - 1, j).Value
Sheets("Sheet1").Cells(Row, 28) = Sheets("MKT").Cells(loc - 2, j).Value
Row = Row + 1
End If
Next i
Next j
End Sub
Function BinarySearch(rng As Range, searchValue As Long) As Integer
'dimension these as long to avoid possible integer
'overflow errors for large lists
Dim curIndex As Long
Dim firstIndex As Integer
Dim lastIndex As Integer
Dim nextMiddle As Long
Dim strValue As Long
Dim MyCell As Variant
Dim i As Integer
i = 0
For Each MyCell In rng
If MyCell < searchValue Then
i = i + 1
End If
Next MyCell
BinarySearch = i
End Function
I understand my code is not the most efficient, I was coding quickly and am not the most knowledgeable in VBA. I also tried binary search instead of linear search but I kept on getting bugs so I just used linear search as speed wasn't an issue. Anyway, when I try to run my code, once in a while (ie every 20 tries) it runs and gives an error. The error isn't what I'm concerned about. However when I usually run it it doesn't run. It takes me about 30 minutes to get the debugger to show me a runtime error. When I press the run button on VBA, usually it just exits. I tried step through, and it highlights the first line (sub stuff()) and then the code exits without going through the rest of the code. I already tried allowing macros in excel. I have run other code simple 1 line print statements and that works. I also tried copy and pasting it into a different excel and that made no difference.
I would agree with Jeeped on this line:
If Not (IsEmpty(Cells(i, j).Value)) Then
You should reference the sheet the Cells reference in referring to. Otherwise Excel defaults to the active sheet so if you toggle between sheets the reference won't work as intended.
Yes I figured it out or at least figured a workaround. For some reason my code won't run when the active sheet is "Sheet1". When I make the active sheet "MKT" it works for some reason. Now there are still bugs with linear search returning zero as someone mentioned, although it shouldn't because the values it is searching through all are dates and I buffered all the initial strings with zeros, but that is a bug I can deal with. Thanks for everyone's help,
Cameron

Exclude copying duplicate values (Excel VBA)

I'm automating copying a certain HTML table to Excel then the duplicates must be deleted or be excluded in being copied. The code below, copy the values from html table to a certain cells then transpose/copy it again to another cells. But I cannot figure out the way on how to exclude duplicate values from being paste to the final cells.
There is a button wherein the copied value will be paste to excel. There are 10 rows in every html table.
code:
Option Explicit
Private Sub hand_over_Click()
Application.ScreenUpdating = False
Dim e, m, a As Integer, k As Variant
Range("XET1").Select
ActiveSheet.PasteSpecial Format:="HTML", Link:=False, DisplayAsIcon:= _
False, NoHTMLFormatting:=True
Columns("E").NumberFormat = "MMM DD YYYY H:MM:SS AM/PM"
Columns("I").NumberFormat = "DDD"
e = 6
m = 1
While Not Range("C" & e) = ""
e = e + 1
Wend
For a = 5 To 1000
If ActiveSheet.Cells(a, 5).Value <> "" Then
If Range("XEV" & m) <> "" Then
Range("C" & e).Value = Range("XEU" & m).Value
Range("F" & e).Value = Range("XFD" & m).Value
k = Split(Split(Split(Range("XEV" & m).Value2, ") :")(1), "):")(0), " Req(")
Range("E" & e) = DateValue(Mid(k(1), 5, 7) & Right(k(1), 4)) + TimeValue(Mid(k(1), 12, 8))
Range("D" & e) = k(0)
Range("I" & e).Value = Date
e = e + 1
m = m + 1
End If
End If
Next a
ActiveSheet.Range("XET1:XFD50").Clear
Application.ScreenUpdating = True
End Sub
How about RemoveDuplicates before transpose/copy it..
Range("XET1:XFD50").Select
ActiveSheet.Range("XET1:XFD50").RemoveDuplicates Columns:=Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), Header:=xlY