首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Find和FindNext for Excel VBA

Find和FindNext for Excel VBA
EN

Stack Overflow用户
提问于 2015-05-22 01:25:06
回答 5查看 52.8K关注 0票数 3

我一直在试图弄清楚如何处理它,但基本上我想要一种打印B列中的值的方法,给定一个与A列匹配的特定值。例如:

代码语言:javascript
运行
复制
Column A    Column B
1           ABC
2           DEF
3           GHI
1           JKL

我想在使用find/findnext或其他任何命令后,打印出这个字符串:

代码语言:javascript
运行
复制
ABC JKL

我试着用

代码语言:javascript
运行
复制
Set cellFound = ActiveWorkbook.Worksheets("sheet1").Range("F1:F1000000").Find("1")
string = cellFound.Offset(0, 1).value

我有一个循环来遍历处理所有行所需的时间。但是使用find时,它总是返回相同的第一个字符串(" ABC "),字符串以ABC结尾,而不是ABC JKL。

我尝试使用FindNext而不是find,但我得到的是1004错误。所以我真的不确定我在哪里做错了。有谁知道吗?

EN

回答 5

Stack Overflow用户

发布于 2015-05-22 02:02:48

如果您在前一个Find之后启动每个Find,则不需要使用Find

代码语言:javascript
运行
复制
Sub qwerty()
   Dim rFirst As Range, r As Range
   Dim A As Range
   Set A = Range("A:A")
   Do
      If rFirst Is Nothing Then
         Set rFirst = A.Find(What:=1, After:=A(1))
         Set r = rFirst
      Else
         Set r = A.Find(What:=1, After:=r)
         If r.Address = rFirst.Address Then Exit Do
      End If
         MyString = MyString & " " & r.Offset(0, 1)
   Loop

   MsgBox MyString
End Sub

票数 11
EN

Stack Overflow用户

发布于 2015-05-22 02:16:27

您需要调用Find一次,然后连续调用FindNext

代码语言:javascript
运行
复制
Dim rng As Excel.Range
Set rng = ActiveWorkbook.Worksheets("sheet1").Range("F1:F1000000")
Set cellFound = rng.Find("1")
Do While Not cellFound Is Nothing
    Set cellFound = rng.FindNext
Loop

参考资料:

票数 6
EN

Stack Overflow用户

发布于 2018-07-11 23:36:17

当使用Range.FindNext方法时,只需要包含一些对初始查找位置的引用。例如,我使用excel录制了这个宏;虽然我不喜欢使用选择和激活,但我认为这有助于理解该方法是如何工作的:

代码语言:javascript
运行
复制
Sub Using_Find()
    Selection.Find(What:="my search string here", After:=ActiveCell _
        , LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
        SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
    Selection.FindNext(After:=ActiveCell).Activate
    Selection.FindNext(After:=ActiveCell).Activate
    Selection.FindNext(After:=ActiveCell).Activate
    Selection.FindNext(After:=ActiveCell).Activate
    Selection.FindNext(After:=ActiveCell).Activate
    Selection.FindNext(After:=ActiveCell).Activate
End Sub

要生成此子例程,我在excel中使用了record >宏,然后选择Home > Find & Select > Find。

我认为这个子例程的工作方式是:

步骤1:找到字符串的第一个位置,激活它;

步骤#2: FindNext查看我们刚刚激活的活动单元格,找到字符串的下一个位置,然后激活它;

等。因此,这里的观察结果是,.FindNext方法需要对先前的find单元格进行一些引用(第一个答案通过手动将其标识为唯一引用来完成)。我不会对这个答案说任何话,它同样有效。我的目标是帮助您深入了解Range.FindNext方法。

值得一提的是:

Range.FindNext将返回一个Range对象。(Microsoft)

After参数的描述如下:

要搜索的单元格。这与从用户界面执行搜索时活动单元格的位置相对应。请注意,after必须是区域中的单个单元格。请记住,搜索是在此单元格之后开始的;直到方法返回到此单元格时,才会搜索指定的单元格。如果未指定此参数,则在区域左上角的单元格之后开始搜索。(Microsoft)

...and

备注部分,微软指出,“搜索将绕到范围的开头。”他们建议保存第一个地址,并针对每个后续.FindNext对其进行检查。这样,一旦该方法确实回绕,它将对照第一个地址检查地址,并结束检查。

因此,为了对微软提供的Range.FindNext方法进行建模,我编写了这个介绍性的子例程以供回顾:

代码语言:javascript
运行
复制
Sub USING_FIND()
'this line sets the range to our used range on the active sheet
    With ActiveSheet.UsedRange
'setting c variable to .Find method, where the first value is what we're looking for,
'i.e. "1"; LookIn:= can be changed to our needs but set currently to xlValues
        Set c = .Find(1, LookIn:=xlValues)
'begin first conditional; this conditional checks c (our .Find method) to see if it has
'some reference, then sets the address to a constant 'firstAddress' so we can check it
'against the .FindNext returns later to prevent endless loop
        If Not c Is Nothing Then
            firstAddress = c.Address
'Do...is where we place our "work"; this can be a redirect to another function/sub, etc
'for now I've just tossed a msgbox as a placeholder that returns the offset 1 column over
            Do
                MsgBox c.Offset(0, 1)
'Now we set c to the .FindNext method, using the original .Find method as the 'after'
        Set c = .FindNext(c)
'Another empty reference check/exit as a conditional
    If c Is Nothing Then
        GoTo DoneFinding
'ends the empty reference conditional
    End If
'using our .FindNext method that we replaced 'c' with earlier, we can now loop through
'the remainder of the value returns.  The Loop While 'c.Address <> firstAddress' sentence
'is checking that each subsequent .FindNext address IS NOT the first address;
'-our loop will return to the 'Do' sentence to repeat the loop, starting on the
'MsgBox c.Offset(0,1) sentence with the next string occurence
'-the characters '<>' means 'does not equal'; i.e. the opposite of '='
    Loop While c.Address <> firstAddress
'this ends the address check loop
    End If
DoneFinding:
    End With
End Sub

要根据您的特定需求调整此代码,我们可以更改Do行后面的句子:'MsgBox c.Offset(0,1)‘以满足我们的特定需求。

根据您的输出需求的复杂程度,您可以将所有匹配项添加到一个数组中,然后让数组按照您希望的方式输出值。这可以通过redim数组来完成,并保留每个返回值。.Find循环完成后,使用Workbooks.Open方法打开一个新工作簿,然后运行一个快速循环,该循环获取每个数组值并将其按您喜欢的顺序放置。

另一种选择是“打印”到.txt。作为#1打开一个新的.txt,然后相应地‘打印’。这也可以通过前面建议的数组选项作为第二个子例程来完成。

希望这有助于为您最初关于.FindNext方法的问题添加一些上下文,并为未来的方向/实现提供一些想法。祝好运!

关于Range.FindNext方法的微软页面:https://msdn.microsoft.com/en-us/VBA/Excel-VBA/articles/range-findnext-method-excel

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30380490

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档