今天我的.Find功能出现了新问题。我正在尝试。通过一个工作表,其中包含从另一个工作表链接的单元格。 我有ws1,其中包含来自ws2的链接日期的标题行。举个例子: ws1 A1单元格公式为= ws2!$ A $ 1,ws1 B1公式为= ws2!$ A $ 2。 ws2在A列中包含日期。
我在ws1中使用.Find来查找用户表单(即ComboBox1.Value)上ComboBox1中显示的值。 ComboBox1源直接链接到ws2 A列,更新时的值更改为dd-mmm-yy格式。
以下是代码:
Private Sub TestSub()
Dim colRng As Range
With Worksheets("ws1").Range("A1:FZ200")
Set colRng = .Find(CDate(ComboBox1.Value))
End With
MsgBox "colRng is: " + colRng.Address
End Sub
这给了我运行时错误91:对象或With Block变量未设置。在Debug上,colRng的值是Nothing而不是Range。
我唯一能想到的是链接的单元格正在弄乱格式,但我不知道如何解决这个问题。有什么想法吗?
更新:我在语句中测试了.Find函数,其中包含一个可以正常工作的字符串。
With Worksheets("ws1").Range("A1:FZ200")
Set colRng = .Find(ComboBox1.Value)
End With
MsgBox "colRng is: " + colRng.Address
如果它是从另一张纸链接的,我不知道怎样去查找单元格中的值。有什么建议吗?
答案 0 :(得分:1)
嗯,.Find()
没找到任何东西,这就是原因。
你知道你在找什么吗?如果你写CDate(ComboBox1.Value)
它会得到预期值吗?
一般情况下,为了避免在.Find()
找不到任何内容时出现此错误,这就是解决方法:
If Not colRng Is Nothing Then
MsgBox "colRng is: " + colRng.Address
End If
答案 1 :(得分:1)
所以日期在Excel中难以处理,因为它们可以被解释为整数或字符串(并使用不同的时区进行格式化)
为了便于修复,以下代码应允许取消注释一行以查找相应的日期或字符串
Private Sub TestSub()
Dim colRng As Range
With Worksheets("ws1")
sFind = ComboBox1.Value
'Set colRng = .Range("A1:FZ200").Find(CDate(sFind), LookIn:=xlValues)
'Set colRng = .Range("A1:FZ200").Find(Format(CDate(sFind), "dd/mm/yyyy"), LookIn:=xlValues)
End With
If Not colRng Is Nothing Then Debug.Print "colRng is: " + colRng.Address
End Sub
作为更完整的答案,您可以使用以下通用FindAll函数...
Private Sub FindAllDates()
Dim Rng1 As Range, Rng2 As Range, AllRng As Range, sFind As String
With Worksheets("ws1")
sFind = ComboBox1.Value
Set Rng1 = FindAll(CDate(sFind), .Range("A1:FZ200"), LookIn:=xlValues)
Set Rng2 = FindAll(Format(CDate(sFind), "dd/mm/yyyy"), .Range("A1:FZ200"), LookIn:=xlValues)
End With
Set AllRng = CombineRange(Rng1, Rng2)
If Not AllRng Is Nothing Then Debug.Print "AllRng is: " + AllRng.Address
End Sub
Function CombineRange(R1 As Range, R2 As Range) As Range
On Error Resume Next
Set CombineRange = R1
If Not R2 Is Nothing Then Set CombineRange = Application.Union(R1, R2)
If CombineRange Is Nothing Then Set CombineRange = R2
End Function
Function FindAll(What, _
Optional SearchWhat As Variant, _
Optional LookIn, _
Optional LookAt, _
Optional SearchOrder, _
Optional SearchDirection As XlSearchDirection = xlNext, _
Optional MatchCase As Boolean = False, _
Optional MatchByte, _
Optional SearchFormat) As Range
'LookIn can be xlValues or xlFormulas, _
LookAt can be xlWhole or xlPart, _
SearchOrder can be xlByRows or xlByColumns, _
SearchDirection can be xlNext, xlPrevious, _
MatchCase, MatchByte, and SearchFormat can be True or False. _
Before using SearchFormat = True, specify the appropriate settings for the Application.FindFormat _
object; e.g. Application.FindFormat.NumberFormat = "General;-General;""-"""
Dim SrcRange As Range
If IsMissing(SearchWhat) Then
Set SrcRange = ActiveSheet.UsedRange
ElseIf TypeOf SearchWhat Is Range Then
Set SrcRange = IIf(SearchWhat.Cells.Count = 1, SearchWhat.Parent.UsedRange, SearchWhat)
ElseIf TypeOf SearchWhat Is Worksheet Then
Set SrcRange = SearchWhat.UsedRange
Else: SrcRange = ActiveSheet.UsedRange
End If
If SrcRange Is Nothing Then Exit Function
'get the first matching cell in the range first
With SrcRange.Areas(SrcRange.Areas.Count)
Dim FirstCell As Range: Set FirstCell = .Cells(.Cells.Count)
End With
Dim CurrRange As Range: Set CurrRange = SrcRange.Find(What:=What, After:=FirstCell, LookIn:=LookIn, LookAt:=LookAt, _
SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
If Not CurrRange Is Nothing Then
Set FindAll = CurrRange
Do
Set CurrRange = SrcRange.Find(What:=What, After:=CurrRange, LookIn:=LookIn, LookAt:=LookAt, _
SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
If CurrRange Is Nothing Then Exit Do
If Application.Intersect(FindAll, CurrRange) Is Nothing Then
Set FindAll = Application.Union(FindAll, CurrRange)
Else: Exit Do
End If
Loop
End If
End Function