【问题标题】:How can I run a macro as a workbook opens for the first time only?如何在工作簿第一次打开时运行宏?
【发布时间】:2015-04-30 04:21:21
【问题描述】:

我有一个工作簿,它运行一个宏来显示用户窗体 Open1 在打开时使用(非常基本的)代码:

Private Sub Workbook_Open()

    Open1.Show

End Sub

这很好 - 每次我打开工作簿时,用户窗体都会弹出并完美运行。

但是,我希望用户窗体仅在第一次打开工作簿时出现。有没有办法让这种情况发生?

【问题讨论】:

  • 获取一张工作表或添加一张新工作表并将其设为.Visible = xlVeryHidden。将此工作表上的 A1 设置为 false。在运行 Open1.Show 之前检查该值,并在运行后将其设置为 True。您甚至可以在 B1 中使用 Environ("USERNAME"),这样每个用户只运行一次。
  • 是的,听起来应该可以解决问题。谢谢!

标签: vba excel


【解决方案1】:

您可以使用一个虚拟模块,该模块在您第一次打开电子表格时会被删除...

类似:

If ModuleExists("DummyModule") Then
    Open1.Show
    DoCmd.DeleteObject acModule, "DummyModule"
End If

Function ModuleExists(strModuleName As String) As Boolean
    Dim mdl As Object
    For Each mdl In CurrentProject.AllModules
        If mdl.Name = strModuleName Then
            ModuleExists = True
            Exit For
        End If
    Next
End Function

更新:如前所述,Excel vba 中不使用 DoCmd。这将教我在不测试的情况下编写代码! 以下更新后的代码可以使用,但要访问VB环境,需要excel信任。

信任中心>宏设置中有一个设置,您可以勾选此代码以在开发人员宏设置下工作

因此,这可能不是要走的路,因为它会带来安全问题的可能性...

Sub RemoveModule()
    If ModuleExists("DummyModule") Then
        Open1.Show
        Dim vbCom As Object: Set vbCom = Application.VBE.ActiveVBProject.VBComponents
        vbCom.Remove VBComponent:=vbCom.Item("DummyModule")
    End If
End Sub

Function ModuleExists(strModuleName As String) As Boolean
    Dim mdl As Object
    For Each mdl In Application.VBE.ActiveVBProject.VBComponents
        If mdl.Name = strModuleName Then
            ModuleExists = True
            Exit For
        End If
    Next
End Function

【讨论】:

  • DoCmd 在 Access VBA 中使用,但不在 Excel 中!
【解决方案2】:

试试这个:

If Sheets("Hide").Cells(1,1) = "1" Then
    Open1.Show
    Sheets("Hide").Cells(1,1) = "0"
End if

您必须创建工作表 Hide,并将单元格 A1 的值设置为 1,在这种情况下,表单将显示出来。

创建工作表后,用这个隐藏它

Sheets("Hide").Visible = xlVeryHidden

用这个来展示它

Sheets("Hide").Visible = True

【讨论】:

    【解决方案3】:

    这里有一段代码将在保存之间持续存在并允许您重置它。无需创建隐藏工作表。 将其放入模块中(从 Workbook_Open 事件处理程序调用 DisplayFormIfFirstTime ......)

    Option Explicit
    
    Private Const cMoniker As String = "FormHasBeenDisplayed"
    
    Private Sub DisplayFormIfFirstTime()
    If HasBeenOpened = False Then DisplayForm
    End Sub
    
    Public Sub DisplayForm()
    MsgBox "Ok, its not a form but a dialog box...", vbInformation
    End Sub
    
    Public Function HasBeenOpened() As Boolean
    
    Dim oName As Name
    On Error Resume Next
    Set oName = Application.Names(cMoniker)
    On Error GoTo 0
    
    If Not oName Is Nothing Then
        HasBeenOpened = True
    Else
        Call Application.Names.Add(cMoniker, True, False)
    End If
    
    End Function
    
    'Call this to remove the flag...
    Public Sub ResetOpenOnce()
    On Error Resume Next
    Application.Names(cMoniker).Delete
    End Sub
    

    【讨论】:

      【解决方案4】:

      根据 PaulG 提供的想法,我编写了一个升级代码,它将检查名称,如果没有找到运行函数,添加名称并保存工作簿,以便更轻松地解决此问题...

      放置在 ThisWorkbook 中

      Private Sub Workbook_Open()
          Run "RunOnce"
      End Sub
      

      放在一个模块中

      Sub RunOnce()
          Dim Flag As Boolean: Flag = False
          For Each Item In Application.Names
              If Item.Name = "FunctionHasRun" Then Flag = True
          Next
          If Flag = False Then
              Call Application.Names.Add("FunctionHasRun", True, False)
              Application.DisplayAlerts = False
                  ActiveWorkbook.Save
              Application.DisplayAlerts = True
              Call RunOnceFunction
          End If
      End Sub
      
      Private Function RunOnceFunction()
          Open1.Show
      End Function
      
      Sub ResetRunOnce()
          For Each Item In Application.Names
              If Item.Name = "FunctionHasRun" Then
                  Application.Names.Item("FunctionHasRun").Delete
                  Application.DisplayAlerts = False
                      ActiveWorkbook.Save
                  Application.DisplayAlerts = True
              End If
          Next
      End Sub
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-15
        • 2018-07-27
        • 2018-11-06
        • 1970-01-01
        • 2012-09-12
        • 2016-05-28
        相关资源
        最近更新 更多