Excel 在其他工作表中查找日期

Excel 在其他工作表中查找日期,excel,vba,Excel,Vba,我从表“a”中提取一个日期,在表“B”中查找 我在每张表中都有相同类型的日期(类型7),并且该日期存在 使用下面的代码,我有 错误91:对象变量或具有未定义的块变量 我浏览了许多论坛,尝试了不同的解决方案,但没有找到答案。这里有一些问题: 首先:声明您的变量,最好在模块顶部使用Option Explicit,使您不会忘记任何变量。否则,VBA将尝试做出有根据的猜测,这将是日期类型的变体 Second我会尽量避免使用ActiveSheet,而是使用CodeName。例如Sheet1.Range(

我从表“a”中提取一个日期,在表“B”中查找

我在每张表中都有相同类型的日期(类型7),并且该日期存在

使用下面的代码,我有

错误91:对象变量或具有未定义的块变量


我浏览了许多论坛,尝试了不同的解决方案,但没有找到答案。

这里有一些问题:


首先:声明您的变量,最好在模块顶部使用
Option Explicit
,使您不会忘记任何变量。否则,VBA将尝试做出有根据的猜测,这将是日期类型的
变体

Second我会尽量避免使用
ActiveSheet
,而是使用
CodeName
。例如
Sheet1.Range(“…”)
。张贴在上面,这样可以澄清这件事上的一两件事

Third
UsedRange
不是返回上次使用的列的最可靠方法。相反,我会选择以下内容:

With Sheet1 'The explicit sheet reference from the first point
    lastColTraining = .Cells(1, .Columns.Count).End(xlToLeft).Column
End with
Fourth:您并不需要列字母来表示该列。还有其他方法,例如在一定范围内使用
.Cells
。您可以使用:

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:如果您有一个
范围
对象,您很可能希望
将它设置为
范围
对象。否则(根据我的第一点),Excel将进行有根据的猜测,并且在您编写时将返回一个数组:
allDate=.Range(“A2:A”&lastRow)
,而使用:
Set allDate=.Range(“A2:A”&lastRow)

Sixth:根据@SiddharthRout的评论,一旦找不到您的值,您将收到一个错误。您可以首先尝试
设置
a
FoundRange
来测试它,并检查它是否为空

考虑到以上所有因素,您的代码将通过以下方式运行得更流畅:

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

我只是不知道你想要什么
trainingDate=training.Rows(4)
。如果您只对每列的第7行感兴趣,请参考该范围。我也不确定您的代码目标是什么,但希望您现在就可以开始工作。

这里有一些问题:


首先:声明您的变量,最好在模块顶部使用
Option Explicit
,使您不会忘记任何变量。否则,VBA将尝试做出有根据的猜测,这将是日期类型的
变体

Second我会尽量避免使用
ActiveSheet
,而是使用
CodeName
。例如
Sheet1.Range(“…”)
。张贴在上面,这样可以澄清这件事上的一两件事

Third
UsedRange
不是返回上次使用的列的最可靠方法。相反,我会选择以下内容:

With Sheet1 'The explicit sheet reference from the first point
    lastColTraining = .Cells(1, .Columns.Count).End(xlToLeft).Column
End with
Fourth:您并不需要列字母来表示该列。还有其他方法,例如在一定范围内使用
.Cells
。您可以使用:

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:如果您有一个
范围
对象,您很可能希望
将它设置为
范围
对象。否则(根据我的第一点),Excel将进行有根据的猜测,并且在您编写时将返回一个数组:
allDate=.Range(“A2:A”&lastRow)
,而使用:
Set allDate=.Range(“A2:A”&lastRow)

Sixth:根据@SiddharthRout的评论,一旦找不到您的值,您将收到一个错误。您可以首先尝试
设置
a
FoundRange
来测试它,并检查它是否为空

考虑到以上所有因素,您的代码将通过以下方式运行得更流畅:

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

我只是不知道你想要什么
trainingDate=training.Rows(4)
。如果您只对每列的第7行感兴趣,请参考该范围。我也不确定您对代码的目标是什么,但希望您现在就可以开始工作。

如果我理解您的回答,我必须向trainingDate=training.Rows(4)”添加.value?哪行错误?您可能找不到搜索词。
allDate=.Range(“A2:A”&lastRow)
应该是
Set allDate=.Range(“A2:A”)“&lastRow)
实际上,错误位于firstRowDate=。。。。然而,由于找不到相关单元格,因此表“B”中显示了所需日期。在使用
FoundCell.row
之前,您需要检查
.Find
在使用
FoundCell.row
查找行之前是否成功。您可能需要查看我是否理解您的响应,我必须将.value添加到trainingDate=training.Rows(4)“?哪一行错误?您可能找不到搜索项。
allDate=.Range(“A2:A”&lastRow)
应该是
Set allDate=.Range(“A2:A”&lastRow)
实际上,错误位于firstRowDate=。。。。然而,由于找不到相关单元格,因此表“B”中显示了所需日期。在使用
FoundCell.row
之前,您需要先检查
.Find
是否成功,然后才能使用
查找行。您可能希望看到详细的解释。还有一件事
firstRowDate=allDate.Find(What:=trainingDate,After:=.Range(“A”&lastRow))。如果
.Find
没有返回Range objectGood addition@SiddharthRout,行
将给出错误。一开始没想到,因为OP说他的查找值肯定是100%。但它很可能不是(在表单/数据类型中),他希望它能感谢您的所有建议。我只是申请了,但问题还没有解决。解释得很好。还有一件事
firstRowDate=allDate.Find(What:=trainingDate,After:=.Range(“A”&lastRow))。如果
.Find
没有返回Range objectGood addition@SiddharthRout,行
将给出错误。在第一场比赛中没有想到这一点