【问题标题】:Excel VBA UserForm 'OK'Excel VBA 用户窗体“确定”
【发布时间】:2016-09-16 19:56:32
【问题描述】:

有谁知道如何以与消息框“确定”按钮相同的方式制作用户表单功能?我会解释的。

我在电子表格的列中检测到错误。当发现错误时,会弹出如下消息框:

MsgBox "请输入有效数据"

当我选择“确定”时,它会转到列中的下一个错误。这很好,当然消息框是模态的,它会冻结应用程序。我希望用户能够编辑数据,然后转到下一个错误。所以,我设计了一个用户表单,它可以是非模态的。太好了,除了我希望宏前进到下一个错误。如果用户更正错误,它将执行此操作。如果他们不这样做,它只会停留在那个错误单元格。

我知道为什么会这样。我的用户窗体“下一步”按钮只调用找到第一个错误的宏。但我想知道是否有办法解决这个问题。

错误检查从第 19 行开始,因为这是用户输入数据的开始。

我在此处包含指向电子表格的链接。模块 1 'NextValidationError' 运行良好并继续处理下一个错误。模块 14 只是在错误处挂起,直到它被解决。我希望它能够跳过。

https://www.dropbox.com/s/yqko5kj19pnauc9/Transparency%20Data%20Input%20Sheet%20for%20Indirect%20Spend%20V7%2009212016%20v2%200.xlsm?dl=0

谁能给我建议如何让模块 14 作为模块 1 继续进行?

【问题讨论】:

  • 将最后一个错误的行号r存储在全局变量中,当用户单击“下一步”时,开始检查下一行。
  • 嗨蒂姆,感谢您的建议。您能否演示或详细说明?

标签: vba excel


【解决方案1】:

类似这样的:

Dim r_start As Long

Sub CheckNames()
    Dim r As Long
    'Dim emptyRow As Boolean

     If r_start = 0 Then r_start = 19

     With ActiveSheet
        For r = r_start To 5000
            'Checks entire row for data. User may skip rows when entering data.
            If WorksheetFunction.CountA(.Range(.Cells(r, 1), .Cells(r, 33))) > 0 Then
                If ((.Cells(r, 2) = "") <> (.Cells(r, 3) = "")) Or _
                   ((.Cells(r, 2) = "") = (.Cells(r, 4) = "")) Then

                    MsgBox "Please fill in First and Last Name or HCO in Row " & r & "."

                End If
            End If
        Next
    End With

End Sub

除非我误读了您的代码,否则您可以将您的两项检查与Or 结合使用。

当用户完成检查时,您将需要一些方法来重置r_start(如果此后表单保持打开状态)。

编辑:这是一个非常基本的示例。 UserForm1 有两个按钮——“下一步”和“关闭”

“下一个”的代码就是:

Private Sub CommandButton1_Click()
    ShowErrors
End Sub

在常规模块中:

Dim r_start As Long

'this kicks off the checking process
Sub StartChecking()
    r_start = 0
    UserForm1.Show vbModeless
    ShowErrors
End Sub

'a simple example validation...
Sub ShowErrors()

    Dim c As Range, r As Long

    If r_start = 0 Then r_start = 9

    For r = r_start To 200
        With ActiveSheet.Rows(r)
            If Not IsNumeric(.Cells(1).Value) Then
                UserForm1.lblMsg.Caption = "Cell " & .Cells(1).Address() & " is not numeric!"
                r_start = r + 1
                Exit Sub
            End If
        End With
    Next r

    r_start = 0

    UserForm1.lblMsg.Caption = "No more errors"

End Sub

【讨论】:

  • Tim,当我用 UserForm2.show 替换 MsgBox 时,它没有前进。实际上,它也没有出现在我的原始代码中:(我的 UserForm2 中的两个按钮是关闭,用于卸载表单和 Next 调用 CheckNames。你知道我是否应该更改任何一个按钮吗?另外,r_start 不会增加或者在整个函数中调用,这有关系吗?如果我在这里很密集,我很抱歉。我相信你很清楚。你是对的,我可以将这两个检查与 Or 结合起来。我真的很感激。
  • 对用户表单的结构一无所知,很难弄清楚你在做什么......是什么触发了流程的开始?
  • 当然,这个过程是由用户触发的。输入所有数据后,用户选择按钮来检查数据。这只是众多检查中的一项,但这是我无法上班的唯一一项。 userform2 的代码如下,其中 CommandButton1 标题为“Close”并退出进程,CommandButton2 标题为“Next”并调用 CheckNames。这有意义吗? Option Explicit Private Sub CommandButton1_Click() ActiveSheet.Range("A18").Select Unload Me End Sub Private Sub CommandButton2_Click() Call CheckNames End Sub
  • @MatthewIngle - 如果您有关于答案的后续问题,最好编辑您自己的问题,而不是编辑答案......此时共享工作簿可能更容易(或者它的一些清理版本),如果你能做到的话。
  • @MatthewIngle - 那是很多代码......目前很难看到流程是如何工作的,因为每个验证都是一个单独的子一个单独的形式。我认为它会从重写中受益:创建一个验证整行的单个过程,然后让您的表单显示该行上的所有错误(使用标签或多行文本框)。您只需要一种通用形式:如果您需要更改用户在任何给定点看到的内容,则动态更新标题和/或标签。
猜你喜欢
  • 2014-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-15
  • 1970-01-01
相关资源
最近更新 更多