There are a few things going wrong here:
First: Declare your variables, it's even best to use Option Explicit
on top of your module to actually make you not forget any. Otherwise VBA will try to make an educated guess which will be a Variant
type of the date type.
Second I would try to avoid ActiveSheet
but instead use a CodeName
. For example Sheet1.Range("...")
. This post on SO can clarify a thing or two on this matter.
Third, UsedRange
is not the most reliable way to return a last used column. Instead I would go with something like:
With Sheet1 'The explicit sheet reference from the first point
lastColTraining = .Cells(1, .Columns.Count).End(xlToLeft).Column
End with
Fourth: You don't really need the column letter to refer to the column. There are other ways, for example using .Cells
within a range. You could use:
With Sheet1 'The explicit sheet reference from the first point
lastColTraining = .Cells(1, .Columns.Count).End(xlToLeft).Column
Set allTraining = .Range(.Cells(3,11),.Cells(lastColTraining,11))`
End with
Fifth: If you have a Range
object, you want to (most likely) Set
it as a Range
object. Otherwise (as per my first point) Excel will make an educated guess and in your case will return an array when you write: allDate = .Range("A2:A" & lastRow)
, instead use: Set allDate = .Range("A2:A" & lastRow)
Sixth: As per @SiddharthRout his comment, you'll recieve an error once your value isn't found. You can test that first trying to Set
a FoundRange
and check if it's not nothing.
Considering all the above, your code would run smoother using:
Option Explicit
Sub SearchDate()
Dim lastColTraining As Long, lastRow As Long, firstRowDate
Dim allTraining As Range, training As Range, allDate As Range, FoundCell As Range
Dim trainingDate As Variant
With Sheet1 'Change according to your sheets CodeName
lastColTraining = .Cells(1, .Columns.Count).End(xlToLeft).Column
Set allTraining = .Range(.Cells(3, 11), .Cells(7, lastColTraining))
For Each training In allTraining.Columns
trainingDate = training.Rows(4)
With Worksheets("B")
lastRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set allDate = .Range("A2:A" & lastRow)
Set FoundCell = allDate.Find(What:=trainingDate, AFter:=.Range("A" & lastRow))
If Not FoundCell Is Nothing Then firstRowDate = FoundCell.Row
End With
Next training
End With
End Sub
I'm just not sure what you want with trainingDate = training.Rows(4)
. If you just interested in the 7th row of each column, then refer to that Range instead. Neither am I sure what your goal is with the code, but hopefully you can get it to work now.