gpt4 book ai didi

vba - 使用 .Find 函数 VBA - 不返回第一个值

转载 作者:行者123 更新时间:2023-12-03 01:41:05 25 4
gpt4 key购买 nike

我已经为一个更大的程序编写了代码摘录来测试概念验证。 (因此代码量很少。)主代码背后的想法是让用户使用带有复选框的自定义用户表单生成一个数组,然后在数组中搜索所有提及“1”的内容,即当复选框具有被选中。然后使用数组的行号根据选中的复选框加载一系列额外的用户窗体。我想有更简单的方法可以做到这一点,但这是我选择的方法,我的 VBA 编码经验相当有限!

我附上了生成的数组的示例。

An test example of arrey generated by the main code

当我运行代码时,它按预期工作,除了以下情况:单元格 (1,2) = 1

谁能看出这是为什么,我已经为此苦苦挣扎了一段时间了。

Sub Array_Finder()

Dim StartFinder As String
Dim StartFinderZero As String
Dim StartFinderCheck As String

i = 4 : j = 1
StartFinderZero = 0 : StartFinderCheck = i + 2
For StartFinderTest = 1 To i + 1
StartFinder = StartFinderZero + 1
If StartFinderCheck > StartFinder Then
StartFinderZero = Range(Cells(StartFinder, 2), Cells(i + 1, 2)).Find _
(What:="1", after:=Cells(StartFinder, 2), searchdirection:=xlNext).Row
Cells(StartFinderTest, 3) = StartFinderZero
Else
MsgBox ("here")
Exit For
End If
Next StartFinderTest
End Sub

最佳答案

使用您的代码:

Sub ArrayFinder()

Dim StartFinder As Long
Dim StartFinderZero As String
Dim StartFinderCheck As String
i = 4: j = 1
StartFinderZero = 0: StartFinderCheck = i + 2

For StartFinderTest = 1 To i + 1
StartFinder = StartFinderZero + 1
If StartFinderCheck > StartFinder Then
With Range(Cells(StartFinder, 2), Cells(i + 1, 2))
Debug.Print "row" & vbTab & .Cells(.Cells.Count).Row
Debug.Print "address" & vbTab & .Address
Debug.Print "after"; vbTab & .Cells(.Cells.Count).Address
StartFinderZero = .Find(1, after:=.Cells(.Cells.Count)).Row
End With
Cells(StartFinderTest, 3) = StartFinderZero
Else
Debug.Print "here"
Exit For
End If
Next StartFinderTest

End Sub

这是您在立即窗口中看到的内容:

row 5
address $B$1:$B$5
after $B$5
row 5
address $B$2:$B$5
after $B$5

技巧如下(来自 MSDN 的 After 参数):

您希望在其后开始搜索的单元格。这对应于从用户界面进行搜索时事件单元格的位置。请注意,After 必须是区域中的单个单元格。请记住,搜索在此单元格之后开始; 在方法返回到该单元格之前,不会搜索指定的单元格。如果您未指定此参数,则搜索将在范围左上角的单元格之后开始。

因此,您可以将最后一个单元格作为开始。它知道它应该在之后开始。因此,理论上它没有什么更好的事情可做,只是从范围的开头开始。 After 参数的想法是设置要检查的最后一个值。 因此,如果我们只有一个值,则无论 After 参数如何,它总是会正确返回。对于多个值,它返回找到的第一个值。

因此,在上面的代码中,由于使用了 After.Find() 按以下顺序搜索单元格:

B1>B2>B3>B4>B5

如果没有After,则顺序如下:

B2>B3>B4>B5>B1


为了更好地说明它,假设您有两个不同的范围,如下所示:

enter image description here

对于左边的,如果您搜索 1 行,即使不选择 after 参数,也总是没问题,使用以下代码:

Sub TestMe()
Dim myR As Range
Dim myS As Range
Set myS = Range("B1:B5") 'change the range
With myS
Set myR = .Find(1)
Debug.Print myR.Row
Set myR = .Find(1, after:=.Cells(.Cells.Count))
Debug.Print myR.Row
End With
End Sub

右边的范围比较棘手,因为它也有两次1。因此,after 是必须存在的,以便从第一个单元格获取值。如果你尝试它,你会得到 21显示在立即窗口上。

这就是为什么在某些时候我决定使用一种慢速方法,它只是在范围内循环并检查值,而不是内置的 .Find() GitHub link to LastThings .

关于vba - 使用 .Find 函数 VBA - 不返回第一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47938876/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com