excel vba range.find not finding date - excel

I'm trying to establish the minimum date and its associated row for later use in a subroutine.
I'm hitting an error and i've spent the last few hours isolating the issue and searching for the solution to no avail.
I have a spreadsheet where column B contains a range of dates arranged in order. I can find the minimum date (the message box correctly returns 11/14/2015), but when I try use that date value to identify the row number I get error 91. Here is my code:
Sub testing()
ThisWorkbook.Worksheets("Burn Curve Data").Activate
Dim rDateColumn As Range
Dim dMinDate As Date
Set rDateColumn = ActiveSheet.Range("B:B")
dMinDate = Application.WorksheetFunction.Min(rDateColumn)
MsgBox dMinDate
Dim rMinCell As Range
Dim intMinRow As Integer
Set rMinCell = rDateColumn.Find(dMinDate, LookIn:=xlValues, LookAt:=xlWhole)
intMinRow = rMinCell.Row
MsgBox intMinRow
End Sub
I tried inserting an If Not statement after Set rMinCell and determined that range.find is not finding the date. Here is the statement I used to identify the error, but I deleted it to clean up the code for this posting.
If Not rMinCell is Nothing Then
intMinRow = rMinCell.Row
Else
MsgBox "error finding rMinCell"
End If
I also tried re-saving dMinDate into a string then using that string in the range.find but I encountered the same error of not finding the date.
Another nuance that may or may not be relevant is that this data exists within a named range on the worksheet. What am I doing wrong with my range.find line?!?

As discussed in the comments it appears the issue arises when the column is formatted as something other than Date.
To do this via code you can add this line after you set the rDateColumn variable:
rDateColumn.NumberFormat = "m/d/yyyy"
This should format the column as a date and your Find method should work appropriately.
Alternatively you can select the column, click 'Format Cells' and then ensure 'Date' is selected under Category.

Related

Iteration using multiple named ranges

What I'm trying to do is create a journaling spreadsheet that records the time and date of the entry at the time its submitted from a UserForm then updates the calendar on a "Splash" worksheet to change the cell interior and font colors to show that a journal entry has been created for that specific day.
I have a module created to iterate through what has already been imported from older journal entries from earlier this year and I want to change the interior color and text color of a cell in the named ranges named after the months. In the image below, the month names are not in the named ranges, just the list of numbers.
Calendar View
Basically, I want to search the dates, select and change the color of the cell of those dates in the calendar (see above). I can make it through the first month named range just fine but when it becomes a new month, it gives me run-time error 91.
Sub updateCells()
Dim rCell As Range
Dim rRng As Range: Set rRng = Worksheets("Journals").Range("A2:A44")
Dim thisDate, thisMonth, thisDay
Dim thisMonthRange As Range
For Each rCell In rRng.Cells
thisDate = Split(rCell.Text, " ")(0)
thisMonth = MonthName(month(thisDate))
thisDay = day(thisDate)
Range(thisMonth).Find(what:=thisDay).Interior.ColorIndex = 10
Range(thisMonth).Find(what:=thisDay).Font.Color = vbWhite
Next rCell
I'm am relatively new to VBA so I don't understand what would be causing the run-time error.
This takes having named ranges that are the actual names of the month, e.g., "January" list of dates (1-31) are referenced by Range("January").
I would use the following code to highlight the "18" in my Range("May") for today's date (2022-05-18):
Sub markCurrentDate()
Cells.ClearFormats
Dim currentMonth As String
currentMonth = Format(Date, "mmmm")
Dim currentDay As Long
currentDay = Format(Date, "dd")
Dim foundDate As Range
Set foundDate = Range(currentMonth).Find(currentDay)
foundDate.Interior.ColorIndex = 27
End Sub
Since we can't tell what your source cell for the date you're referring is, based on the current post, I used Date rather than a reference to a cell. The reference can be updated through, similar to being able to use With foundDate to add multiple format changes.
I think the problem is likely to be that one of your named ranges does not cover the entire range of days. February surely doesn't, you're missing the 28th!
At any rate, as a consequence (and apparently only on the second turn (a Feb 28?)), you run into the Run-time error '91', because Range(thisMonth).Find(what:=thisDay) is resolving to Nothing instead of an expected Range object once you fail to find thisDay inside the named range.
Evidently, the code cannot execute Nothing.Interior.ColorIndex = 10.
If correct, your solution should be to double-check and fix the incorrect named ranges.
Incidentally, Range(thisMonth).Find(what:=thisDay) is also superfluous. For obvious reasons, each range simply starts at 1 and increments with 1. So we could simply use thisDay as the index. Instead of this:
Range(thisMonth).Find(what:=thisDay).Interior.ColorIndex = 10
Range(thisMonth).Find(what:=thisDay).Font.Color = vbWhite
Simply use this:
With Range(thisMonth).Cells(thisDay)
.Interior.ColorIndex = 10
.Font.Color = vbWhite
End With
Update: come to think of this, if you want to insist on using Range(thisMonth).Find(what:=thisDay), you should at the very least change the snippet to Range(thisMonth).Find(what:=thisDay, LookAt:=xlWhole).
Counterintuitively, Range.Find(...) seems to accept a partial match by default (xlPart) and it actually remembers the settings you used on your last find (in the same Excel 'session'). Also, it will not always start where you expect it to do (see further this documentation and this post: Using the .Find Function VBA - not returning the first value). E.g. a realistic error depending on your settings / active cell position might be that your code (and incidentally, also the code provided by Cyril) will change the formatting for a day 10, when in fact you were trying to change the formatting for a day 1.

best way to select column based on current date (Excel VBA)

I have a small tracker program I am building in Excel VBA. I have a userform that I keep up throughout the day, inputting my tasks/data via an 'Add' button. At the end of the day, I click the 'Post' button, and it saves the data to my worksheets where appropriate.
Thought I had it finished and working correctly, but now apparently my sub to select the correct column based on the day's date is not working, and I'm not sure why, as it had been working perfectly throughout development.
This piece is vital, as my other functions to post the day's data rely on this. I've read a lot of other posts about how to do this (selecting a column based on current date), but none have explained why mine isn't working. Trying to become a better coder, and not just a copy/paste coder, so thought I would try asking here. Copy/Paste usually gets me into these messes, where I'm using tools/functions that work, but I don't know why, and can't troubleshoot/debug on my own.
My total project involves 5 worksheets, but this sub should only involve 2 of them. "Tasks" and "Data Tracker", both of which have a row of dates.
Below is the sub in question.
Public Sub currentDate()
'sub to assign current date to global values
Set rng - Range("H2:HZ2")
Set myDate = rng.Find(What:=Int(Date), LookIn:=xlFormulas)
End Sub
If I step through it, Date is pulling the correct date, and xlFormulas shows a value of -4123 (I don't even know if that matters)..
(UPDATE) so apparently, this morning, it decided to work perfectly. facepalm Any clues?
(UPDATE) so, per usual, I try adding features as I fix something else, so this took a bit more researching to solve, but #Super-Symmetry pointed me in the right direction! As noted in a comment down below, I changed my date headers in the two sheets to be more of a "start date + n" situation. Although his suggestion of using xlValue instead of xlFormula was on the right track, Find. was still having trouble with date vs serial. Ultimately this is what I got to work:
Public Sub currentDate()
'sub to assign current date to global values
'load the date range
Set rng = Worksheets("Tasks").Range("H2:HZ2")
'load the values in the range
dateArray = Range("H2:HZ2").Value
Dim day As Variant 'object to load dateArray
Dim loc As Integer 'matches date with cell location
'converting the date to serial
For Each day In dateArray
day = CLng(day)
loc = loc + 1
If day = Date Then 'we found the right column
Set myDate = rng(loc)
'selects the correct cell
If ActiveSheet.name = "Data Tracker" Then 'adjust the row
Cells(myDate.Row + 3, myDate.Column).Select
Else 'sheet must be Tasks
Cells(myDate.Row + 2, myDate.Column).Select
End If
Exit Sub
End If
Next
End Sub
It's not elegant, but it works.. please feel free to educate me if you have any cleaner ways to do this!
Try changing Int(Date) to CLng(Date)
Public Sub currentDate()
'sub to assign current date to global values
Dim rng As Range, myDate As Range
Set rng = Range("H2:HZ2")
Set myDate = rng.Find(What:=CLng(Date), LookIn:=xlValues)
End Sub

VBA Vlookup not finding values that exist

I am working with two different Worksheets in one workbook. My task is to look up the model# of a product from Sheet1, find that same model# in Sheet2, and get the cost of that product, which is located a few columns away.
So naturally, I tried to use Vlookup, because that function is enough for this query.
I will post my code below, and then explain the problems I am facing. I am new to VBA and have searched many many different Stack posts, and tried the various solutions, to no avail.
Private Sub CommandButton1_Click()
Dim tbdCell As Range
Dim model As Range
Dim cell As Range
Dim PAsheet As Worksheet
Dim DB As Worksheet
Dim target As Variant
Set DB = Worksheets("Database")
Set PAsheet = Sheets("Pricing Agreement")
Set tbdCell = Range("N2:N4700")
On Error GoTo ErrHandler:
For Each cell In tbdCell
Set model = cell.Offset(0, -6)
cell = WorksheetFunction.VLookup((CStr(model)), PAsheet.Range(CStr("C2:D2000")), 6, True)
Next cell
Exit Sub
ErrHandler:
Select Case Err.Number
Case 0
Case 1004
cell = "missing"
Resume Next
Case Else
MsgBox Err.Number & vbNewLine & Err.Description
Exit Sub
End Select
End Sub
So upon debugging and testing, most things work until we get to the line where I use the Vlookup function. I invariably get error 1004, even though the data exists in the other spreadsheet. So the cells that I need to fill will always fill with "missing" as posted above in the Error Handling Code.
I tried using the Application version of the function. I tried using different variables and declaring them as Variant type. I even tried making the table_array range just one row with 2 column coverage, in an attempt to force a match for one particular model #. So far, to avoid a type mismatch, I cast 'model'(the model#) into a String, and I also cast the search range in PAsheet to String. The final thing I tried was to not search for an exact match(last argument was set to true)
So in anticipation of future questions about the data that the Vlookup is based on, I will include necessary information about how both sheets are formatted.
Info that you may need:
We start in column N, where the prices are missing in Sheet1(Database).
I set model to the value in the same row, 6 columns to the left(Column H).
Testing with MsgBox proved this to work for me, and on debug, the model variable displays the correct info, so this isn't the issue.
In PAsheet, the model #s are in column C. Originally I made the search table from C2:C2000 or so, but I was led to believe that you need at least a two column table for Vlookup to work, so I changed C2000 to D2000. Now the search range is a two column table.
In PAsheet, the cost of the product is in Column H, which is 5 away from column C. I need this value, so I put 6 in the column_index argument. It was 5 before, because I thought that you didn't count the first column, but I fixed that.
Finally I mostly tested with "False" as the last argument, but either way it doesn't work.
So after trying more than two dozen variations and strategies, I still get "missing" in the cells that I need to fill.
So, what am I doing wrong here? Thanks in advance.
If you are trying to return the 6th value from Column C your range needs to be updated to `PAsheet.Range("C2:H2000")
cell.Value = WorksheetFunction.VLookup(cell.Offset(, -6), PAsheet.Range("C2:H2000"), 6, False)

Excel VBA Find() with dates issue

I have a set of dates in column B like 06/03/2017 formatted in a custom dd-mmm formatting giving me 06-Mar output.
If I manually do Find/Replace and search for 06-Mar and select Look In: Values, it finds it no problem, however doing the same via VBA isn't working.
Dim Source as Worksheet, Dest as Worksheet
Dim mDate as String, copyRow as Integer
Set Dest = ThisWorkbook.Sheets("Weekly Updates")
Set Source = ActiveWorkbook.Sheets("Weekly Updates")
mDate = Dest.Range("B2").Text
copyRow = Source.Range("B:B").Find(What:=mDate, LookIn:=xlValues).Row
I have tried getting mDate as a value and searching in formulas and values, but nothing seems to work.
The line debugs on copyRow = Source....... however if I open the Find/Replace window manually at this point, it fills out the search bar with "06-Mar", and finds the value in column B no issues.
If I replace mDate with string I know is there, for example Find(What:="W/C"..... it returns copyRow as 1 (because its the header of that column).
Any suggestions what I am missing here?
EDIT
To cover a few of the comments below:
Yes the sheets are named the same, just in different workbooks (master file to pull data from multiple identical sources)
In terms of the formatting, I get the search criteria from a date with a true value of 06/03/2017 formatted as dd-mmm, searching in a range of data as true dates 06/03/2017 formatted also as dd-mmm.
Try to give the variable mDate the same format of your date :
copyRow = Source.Range("B:B").Find(What:=Format(mDate, "dd-mmm"), LookIn:=xlValues).Row

Pivot Table Date Filter Issue (Not a valid date)

I have a requirement to filter an existing pivot table (PivotTable1 in 'Pivot' worksheet) in a workbook based on dates input by the user in another worksheet (Control). I should add that the cells in the control sheet have data validation on them to force dates only in the cells. The code I have so far is this:
Sub FilterPivotfromCell()
Dim Invoice_Start_Date As Date
Dim Invoice_End_Date As Date
Invoice_Start_Date = CDate(Worksheets("Control").Cells(3, "E").Value)
Invoice_End_Date = CDate(Worksheets("Control").Cells(3, "G").Value)
Sheets("Pivot").Select
MsgBox IsDate(Invoice_End_Date)
MsgBox IsDate(Invoice_Start_Date)
ActiveSheet.PivotTables("PivotTable1").PivotCache.Refresh
ActiveSheet.PivotTables("PivotTable1").PivotFields("Date").ClearAllFilters
ActiveSheet.PivotTables("PivotTable1").PivotFields("Date").PivotFilters.Add _
Type:=xlDateBetween, Value1:=Invoice_Start_Date, Value2:=Invoice_End_Date
End Sub
When stepping through the code using F8, and with watches on the variables Invoice_Start_Date and Invoice_End_Date, everything points to the variables being dates (type shows as date in the watch window, and the isdate message boxes come back as 'True' in both instances. However, when running the macro, as soon as it comes to the part where the pivot table is filtered, I get the message 'Run-time error '1004': The date you entered is not a valid date. Please try again.'
I wonder if the issue is something to do with having UK regional settings as I know I've had issues in the past with this.
Also, to clarify, cell contents of E3 is 01/10/2016 and cell contents of G3 is 31/10/2016.
Edit: I've tried following the suggestion here, but it had made no difference. The source of my pivot table does include blank rows also, but I've tried limiting it to just the data and it has made no difference.
Edit 2: Well, wouldn't you know it. A little more googling and came up with the solution here. Basically adding clng format around the dates in the pivot filter has done the trick?
Here is the revised working code, following the answer provided by #MP24 in this question.
Sub FilterPivotfromCell()
Dim Invoice_Start_Date As Date
Dim Invoice_End_Date As Date
Invoice_Start_Date = CDate(Worksheets("Control").Cells(3, "E").Value)
Invoice_End_Date = CDate(Worksheets("Control").Cells(3, "G").Value)
Sheets("Pivot").Select
MsgBox IsDate(Invoice_End_Date)
MsgBox IsDate(Invoice_Start_Date)
ActiveSheet.PivotTables("PivotTable1").PivotCache.Refresh
ActiveSheet.PivotTables("PivotTable1").PivotFields("Date").ClearAllFilters
ActiveSheet.PivotTables("PivotTable1").PivotFields("Date").PivotFilters.Add _
Type:=xlDateBetween, Value1:=CLng(Invoice_Start_Date), Value2:=CLng(Invoice_End_Date)
End Sub
The work around for this problem is we should clear all filters applied to the field before filtering so that all filters are cleared for that field.
like this...
set pf = pt.pivotfields("FilmReleaseDate")
pf.clearallfilters

Resources