使用.find,.findnext,使用和不使用循环在excel userform中创建下一个按钮时出现问题

时间:2016-09-22 18:33:35

标签: excel vba

这是我第一次制作Excel用户表单并使用VBA编码。我正在Excel中创建一个用户表单,以便能够根据搜索条件搜索科学论文,例如"作者名称","关键词","物种"等(来自论文的信息输入Excel)。每个搜索字词目前都是不同的用户表单,此示例基于"作者搜索"窗体。

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

使用下面的代码,当我点击下一个按钮时,在每个匹配的记录中填充控制框并弹出消息框("点击下一个")(它找到我的所有记录,大!)。问题是,如果在消息框中单击“确定”,它将直接转到下一个记录和下一个消息框。您无法退出消息框,停在记录并检查。 (通过检查这里我的意思是看一下记录,然后点击一个控制盒来阅读或复制文本。)这一直持续到它遍历所有记录(这可能是很多消息框和很多点击,因为记录数量)。

如果我删除行MsgBox"单击以查找下一条记录",则循环将一直遍历所有记录,直到它到达最后一条记录(控制框填充了最后一条记录的信息)记录和消息框说"最后记录")然后用户不能查看其间的任何记录。

另一方面,如果我一起取出循环,当你单击cmdNext按钮时它只会带你到第一个匹配的记录,当我第二次点击Next时,没有任何反应,它不会去之后的下一个记录。使用SearchDirection我的cmdPrevious按钮有同样的问题:= xlPrevious。

显然有一些关于循环是如何工作的,或者说我不理解的地方,或者我正在做的事情,当我在不使用循环的情况下尝试时,不允许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

1 个答案:

答案 0 :(得分:0)

  

您无法退出消息框,停在记录中并进行检查。 (通过这里检查我的意思是查看记录并单击控制框以阅读或复制文本。)

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

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

        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的无限循环,另一个触发无限循环:

    enter image description here

    Dim bContinue As Boolean
    
    Private Sub CommandButton2_Click()
        bContinue = True
    End Sub
    
    Private Sub UserForm_initialize()
    
    End Sub
    Private Sub CommandButton1_Click()
        bContinue = False
        Do While Not bContinue
            DoEvents
        Loop
    End Sub