在excel用户窗体中使用.find、.findnext(带和不带循环)创建下一步按钮时出现问题

在excel用户窗体中使用.find、.findnext(带和不带循环)创建下一步按钮时出现问题,excel,vba,Excel,Vba,这是我第一次制作Excel用户表单并使用VBA编码。我正在Excel中创建一个用户表单,以便能够根据搜索词(如“作者姓名”、“关键字”、“物种”等)搜索科学论文(论文中的信息输入Excel)。每个搜索词当前都是不同的用户表单,本例基于“作者搜索”用户表单 My userform有一个cmdSearch按钮,允许用户键入作者姓名并查找与该搜索匹配的第一条记录。然后从Excel文件中的该行填充代表作者姓名、标题、摘要等字段的控制框。我正在尝试向表单中添加cmdNext和cmdPrevious按钮,以

这是我第一次制作Excel用户表单并使用VBA编码。我正在Excel中创建一个用户表单,以便能够根据搜索词(如“作者姓名”、“关键字”、“物种”等)搜索科学论文(论文中的信息输入Excel)。每个搜索词当前都是不同的用户表单,本例基于“作者搜索”用户表单

My userform有一个cmdSearch按钮,允许用户键入作者姓名并查找与该搜索匹配的第一条记录。然后从Excel文件中的该行填充代表作者姓名、标题、摘要等字段的控制框。我正在尝试向表单中添加cmdNext和cmdPrevious按钮,以继续向前搜索具有相同作者姓名的每一行,或返回到以前查看的记录。我修改了以前在这个网站和其他网站上找到的代码,遇到了两个问题之一

使用下面的代码,当我单击“下一步”按钮时,在每个匹配的记录处填充控制框,并弹出消息框(“单击下一步”)(它正在查找我的所有记录,太棒了!)。问题是,如果单击消息框上的“确定”,它将直接进入下一条记录和下一个消息框。您不能退出消息框,在记录处停止并检查。(这里的“检查”是指查看记录并单击控制框来读取或复制文本。)这会一直持续,直到它在所有记录中循环(由于记录的数量,可能会有大量的消息框和大量的单击)

如果我删除行MsgBox“Click for next record”,则循环将遍历所有记录,直到到达最后一条记录(控制框中填充了来自最后一条匹配记录的信息,消息框中显示“last record”),然后用户无法查看中间的任何记录

另一方面,如果我一起取出循环,当您单击“下一步”按钮时,它只会将您带到第一个匹配的记录,而当我再次单击“下一步”时,什么也没有发生,它不会转到之后的下一条记录。使用SearchDirection:=xlPrevious时,我的cmdPrevious按钮也有同样的问题

显然,我不了解循环的工作方式或放置位置,或者我正在做的事情不允许cmdNext在不使用循环的情况下继续查找下一条记录。如有任何建议,将不胜感激。下面是我正在使用的代码:

Private Sub cmdNext_Click()

Dim data As Range
Dim findrow As Range
Dim nextrow As Range
Dim ws As Worksheet
Dim Search As String

On Error Resume Next

Set ws = Worksheets("literature_format")
Set data = Sheet1.Range("H:H")

Search = Me.txtSearch.Value

If Search = "" Then
    MsgBox "Enter author or editor name"
    Else


Set findrow = data.find(What:=Search, LookIn:=xlValues, _
        LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
        MatchCase:=False, SearchFormat:=False)

If Not findrow Is Nothing Then
        Set nextrow = findrow
        Do
            Set findrow = data.FindNext(After:=findrow)
            If Not findrow Is Nothing Then
            If findrow.Address = nextrow.Address Then Exit Do
            Me.Control1.Value = findrow.Offset(0, 0)
            Me.Control2.Value = findrow.Offset(0, 3)
            Me.Control3.Value = findrow.Offset(0, 4)
            Me.Control4.Value = findrow.Offset(0, 15)
            Me.Control5.Value = findrow.Offset(0, 2)
            Me.Control6.Value = findrow.Offset(0, -7)
            Me.Control7.Value = "Name of author(s)"
            MsgBox "Click for next record"

            Else

            End If

        Loop
        MsgBox "Last record"

    Else

    End If

End If

End Sub
您不能退出消息框,在记录处停止并检查。(这里的“检查”是指查看记录并单击控制框以读取或复制文本。)

您应该执行以下操作,而不是
MsgBox
提示:

  • 将一些控制按钮(如
    cmdContinue
    )添加到用户表单
  • 您需要添加公共或模块级变量,如
    bContinue as Boolean
    。默认情况下,此变量将为
    False
  • \u单击
    cmdContinue
    按钮的
    过程应将
    bContinue
    值设置为
    True
    ,我们将在步骤4中使用该值
  • 当过程“找到”匹配元素时,填充UserForm上的字段并执行循环,直到满足某个条件(这基本上是一个带有转义条件的无限循环)
  • (可选)包括
    MsgBox
    ,以指示用户应按下“继续”按钮(或者,如果有其他按钮复制/等数据,他们可以使用这些按钮代替)
  • 例如,我认为这是基本方法:

        Do
            Set findrow = data.FindNext(After:=findrow)
            If Not findrow Is Nothing Then
            If findrow.Address = nextrow.Address Then Exit Do
            Me.Control1.Value = findrow.Offset(0, 0)
            Me.Control2.Value = findrow.Offset(0, 3)
            Me.Control3.Value = findrow.Offset(0, 4)
            Me.Control4.Value = findrow.Offset(0, 15)
            Me.Control5.Value = findrow.Offset(0, 2)
            Me.Control6.Value = findrow.Offset(0, -7)
            Me.Control7.Value = "Name of author(s)"
    
            'This should loop indefinitely until the user presses the "cmdContinue" button, and that will allow it to process the next record
            Do While Not bContinue
                DoEvents
            Loop
            ' reset to False so that the above loop will work for the next match
            bContinue = False
            Else
    
            End If
    
        Loop
    
    我用一个非常简单的表单和两个按钮进行了测试,一个按钮用
    DoEvents
    触发无限循环,另一个按钮停止无限循环:

    您不能退出消息框,在记录处停止并检查。(这里的检查是指查看记录并单击控制框以读取或复制文本。)

    您应该执行以下操作,而不是
    MsgBox
    提示:

  • 将一些控制按钮(如
    cmdContinue
    )添加到用户表单
  • 您需要添加一个公共或模块级变量,例如
    bContinue as Boolean
    。默认情况下,此变量将为
    False
  • \u单击
    cmdContinue
    按钮的
    过程应将
    bContinue
    值设置为
    True
    ,我们将在步骤4中使用该值
  • 当过程“找到”匹配元素时,填充UserForm上的字段并执行循环,直到满足某个条件(这基本上是一个带有转义条件的无限循环)
  • (可选)包括
    MsgBox
    ,以指示用户应按下“继续”按钮(或者,如果有其他按钮复制/等数据,他们可以使用这些按钮代替)
  • 例如,我认为这是基本方法:

        Do
            Set findrow = data.FindNext(After:=findrow)
            If Not findrow Is Nothing Then
            If findrow.Address = nextrow.Address Then Exit Do
            Me.Control1.Value = findrow.Offset(0, 0)
            Me.Control2.Value = findrow.Offset(0, 3)
            Me.Control3.Value = findrow.Offset(0, 4)
            Me.Control4.Value = findrow.Offset(0, 15)
            Me.Control5.Value = findrow.Offset(0, 2)
            Me.Control6.Value = findrow.Offset(0, -7)
            Me.Control7.Value = "Name of author(s)"
    
            'This should loop indefinitely until the user presses the "cmdContinue" button, and that will allow it to process the next record
            Do While Not bContinue
                DoEvents
            Loop
            ' reset to False so that the above loop will work for the next match
            bContinue = False
            Else
    
            End If
    
        Loop
    
    我用一个非常简单的表单和两个按钮进行了测试,一个按钮用
    DoEvents
    触发无限循环,另一个按钮停止无限循环:


    @aakmajian干杯!如果您能够在项目中成功实现这一点,对于“第一次”VBA用户来说,您做得非常好!很高兴我能提供帮助!我确实做到了这一点,但是我在使用“后退”按钮时遇到了问题。我有两个后退按钮“后退”和“继续”,它们使用的代码与上面的代码相同(包括您的添加内容)除了它使用SearchDirection:=xlPrevious和.FindPrevious。当我单击“上一步”时,它不会转到最近查看的记录(即真正的上一条记录),而是转到倒数第二条记录。就像代码搜索最后一条记录,然后转到上一条记录一样。“继续”工作如预期。你有什么建议吗?(我需要编辑我原来的帖子来添加这个吗?)嗨@aakmajian,我想我会的