【问题标题】:Excel vba: Informative modal window (blocking for the user, non-blocking for the macro)Excel vba:信息模式窗口(用户阻塞,宏非阻塞)
【发布时间】:2015-09-11 11:47:42
【问题描述】:

我有一个宏 Excel 可以做很多事情。其中之一是运行查询(通过 ADODB.Connection)。查询可以持续很长时间,所以我想:

  • 显示一个模态信息对话框,显示“正在运行查询 3”(例如),没有任何按钮(用户不能关闭它)。它应该阻止用户,但不阻止宏。
  • 运行查询。
  • 关闭信息窗口。

在伪代码中:

dim cn as new ADODB.Connection
dim rs as new ADODB.Recordset

dim dia as InfoDialog
set dia = new InfoDialog "running query 3"

cn.Open cn_string
rs.Open query_string, cn, ...

dia.close

我更喜欢无需导入新库的解决方案(vba 编辑器 > 工具 > 参考)。例如,使用类似于 'CreateObject("WScript.Shell")' 的内容。如果不可能,那么库导入也是受欢迎的(最好是标准库,因为不必在用户的计算机上安装东西)。


更新:根据 Kenda 的建议,我制作了一个带有标签“Label1”的 userForm“InfoDialog”,并创建了两个库函数以使其易于使用:

sub show_info(text as string)

    InfoDialog.Label1.Caption = text
    InfoDialog.Show
    DoEvents

end sub

sub close_info()

    InfoDialog.Hide

end sub

所以现在我可以写了:

show_info "Connecting to db ..."
cn.Open cn_string

show_info "Running query ..."
rs.Open query_string, cn, ...

close_info

【问题讨论】:

标签: excel vba


【解决方案1】:

只需在您的代码中插入带有标签的 UserForm 即可

Form1.Show
Form1.Label1.Text="running query 3"
...
Form1.Hide

在结尾可选卸载表单,Unload Form1

【讨论】:

    【解决方案2】:

    我在运行宏时遇到了另一个问题。当我运行大型代码时,Excel 2010 看起来像是冻结了,但宏仍在后台运行。并且用户没有 ProgressBar。所以我在框架中使用带有蓝色背景颜色的标签的一些技巧。 (包含:名为 lblDescription 的标签,名为 FrameProgress 的框架,其中名为 LabelProgress 的标签)

    对于非冻结,请执行以下操作: 1)在激活表单上添加子

    Private Sub UserForm_activate()
        Call ImportDat
    End Sub
    

    2) 在Module1 中启动Sub

    Sub ShowDialog()
        UserForm1.LabelProgress.Width = 0
        UserForm1.Show
    End Sub
    

    3) 在 Module1 中使用此代码制作您的 Sub(魔术字是 DoEvents

    Sub ImportDat()
    Dim Counter As Integer
    Dim RowMax As Integer    
    Dim PctDone As Single
      Application.ScreenUpdating = False
      Counter = 1
      RowMax = 10000
      For i = 0 To RowMax -1 
        PctDone = i / RowMax
        With UserForm1
          .lblDescription = "Processing " + CStr(i + 1) + " from " + CStr(RowMax)
          .FrameProgress.Caption = Format(PctDone, "0%")
          .LabelProgress.Width = PctDone * (.FrameProgress.Width - 10)
        End With
        DoEvents
      Next i
      Application.ScreenUpdating = True
      Unload UserForm1
    End Sub
    

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2011-07-14
      • 1970-01-01
      • 2012-01-01
      • 2016-07-06
      • 1970-01-01
      • 2012-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多