2016-09-22 142 views
1

这是我第一次制作Excel用户窗体并使用VBA编码。我正在Excel中创建一个用户表单,以便能够根据诸如“作者姓名”,“关键词”,“种类”等搜索词搜索科学论文(论文中的信息输入到Excel中)。每个搜索词当前都是一个不同的用户表单,并且此示例基于“作者搜索”用户表单。使用.find,.findnext,使用和不使用循环的excel用户窗体中的下一个按钮的问题

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

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

如果我删除MsgBox的“单击下一条记录”,则循环会一路通过所有记录,直到达到最后一条记录(控制框将填充上一个匹配记录和消息框的信息说“最后的记录”),然后用户就不能查看其间的任何记录。

另一方面,如果我一起取出循环,当您单击cmdNext按钮时,它只会将您带到第一个匹配记录,并且当我再次单击下一步时,没有任何反应,它不会发生到那之后的下一个记录。我用我的cmdPrevious按钮使用SearchDirection:= 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 

回答

0

您不能退出消息框,在记录停止和检查。 (通过检查在这里我的意思是看记录,然后点击控制箱读取或复制的文本。)

取而代之的是MsgBox提示,你应该做到以下几点:

  1. 添加一些控制按钮像cmdContinue到UserForm。
  2. 您需要添加一个公共或模块级变量,如bContinue as Boolean。这个变量默认为False
  3. _Click程序cmdContinue按钮应设置bContinue值为True,我们将在步骤4中使用该值。
  4. 当过程“找到”一个匹配的元素时,填充UserForm中的字段并执行一个循环,直到满足一些条件(这基本上是一个带有逃逸条件的无限循环)。
  5. 任选地,包括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无限循环,而另一个停止无限循环:

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 
+1

非常感谢大卫,完美的工作! – aakmajian

+0

@aakmajian欢呼!如果你能够在你的项目中成功实现这一点,那么对于“第一次”的VBA用户来说,你的表现非常好!很高兴我能帮上忙! –

+0

我确实得到了这个工作,但是我后面的按钮有问题。除了使用SearchDirection:= xlPrevious和.FindPrevious外,我有两个后退按钮“返回”和“继续”,它们使用与上述相同的代码(加上您的代码)。当我点击“返回”时,不是转到最近查看的记录(即真正的上一个记录),而是转到倒数第二个记录。就好像代码搜索最后一个记录然后去了那个之前那样。 “继续”按预期工作。你有没有任何建议? (我需要编辑我原来的帖子来添加这个?) – aakmajian