【问题标题】:Excel - How to create button upon Workbook_Open eventExcel - 如何在 Workbook_Open 事件上创建按钮
【发布时间】:2015-06-15 21:35:10
【问题描述】:

我正在尝试制作一个 Excel 加载项以在打开任何工作簿时创建一个简单的按钮,但我得到了

对象变量或With Block变量未设置

我认为这是因为技术上还没有“ActiveWorkbook”。

我要做的第一件事是删除当前工作表上的所有按钮。然后我想放置一个按钮。

有人知道如何实现吗?

代码

Private Sub Workbook_Open()
    ActiveWorkbook.ActiveSheet.Buttons.Delete
    Dim CommandButton As Button
    Set CommandButton = ActiveWorkbook.ActiveSheet.Buttons.Add(1200, 100, 200, 75)
    With CommandButton
        .OnAction = "Test_Press"
        .Caption = "Press for Test"
        .Name = "Test"
    End With
End Sub

然后我有一个Private Sub Test_Press() 来显示一个 MsgBox。但是该按钮并未被创建。

【问题讨论】:

  • 您需要将代码添加到 workbook_open 事件中,以便在您的工作簿打开时触发。
  • 还有一件事,将 commandbutton 定义为一个按钮,然后您就可以确保将代码添加到 ThisWorkbook 页面中的 workbook_open 私有子组件,就在您的 VBA IDE 中的工作表下方跨度>
  • 我想我的道歉不够具体,问题已更新。我希望它位于加载项中,这样每当我打开任何工作簿时,我都希望在 Front sheet 上创建按钮。
  • 当代码运行时它不是活动工作簿,我是对的。但是安装的加载项在文件之前启动,因此当我指定要添加按钮的工作簿的名称时出现超出范围的错误。我不确定如何处理。

标签: vba excel button excel-2013


【解决方案1】:

归功于http://www.jkp-ads.com/Articles/FixLinks2UDF.asp

注意:我有另一个模块我没有在下面发布,其中包含宏 Project_Count 我绑定到我放置在工作簿上的按钮,只有当工作簿名称是 TT_GO_ExceptionReport

我还有一个 VBScript,它可以下载插件,将它放在用户插件文件夹中,然后安装它。如果您想知道如何做到这一点,请发表评论。

解决问题的插件代码:

本工作簿

Option Explicit
    Private Sub Workbook_Open()
    ' Purpose   : Code run at opening of workbook
    '-------------------------------------------------------------------------    
    'Initialise the application
    InitApp
    modProcessWBOpen.TimesLooped = 0

    Application.OnTime Now + TimeValue("00:00:03"), "CheckIfBookOpened"
End Sub

模块 1 名为 modInit 显式选项

'Create a module level object variable that will keep the instance of the
'event listener in memory (and hence alive)
Dim moAppEventHandler As cAppEvents

    Sub InitApp()
        'Create a new instance of cAppEvents class
        Set moAppEventHandler = New cAppEvents
        With moAppEventHandler
            'Tell it to listen to Excel's events
            Set .App = Application
        End With
    End Sub

模块 2 名为 modProcessWBOpen 显式选项

'Counter to keep track of how many workbooks are open
Dim mlBookCount As Long

'Counter to check how many times we've looped
Private mlTimesLooped As Long

' Purpose   : When a new workbook is opened, this sub will be run.
' Called from: clsAppEvents.App_Workbook_Open and ThisWorkbook.Workbook_Open
'-------------------------------------------------------------------------
Sub ProcessNewBookOpened(oBk As Workbook)

    If oBk Is Nothing Then Exit Sub
    If oBk Is ThisWorkbook Then Exit Sub
    If oBk.IsInplace Then Exit Sub

    CountBooks

    'This checks to make sure the name of the new book matches what I 
    'want to place the button on
    If oBk.Name = "TT_GO_ExceptionReport.xlsm" Then
        Dim CommandButton As Button
        Set CommandButton = Workbooks("TT_GO_ExceptionReport.xlsm").Sheets(1).Buttons.Add(1200, 100, 200, 75)
        With CommandButton
            .OnAction = "Project_Count"
            .Caption = "Press for Simplified Overview"
            .Name = "Simplified Overview"
        End With
    End If
End Sub

Sub CountBooks()
    mlBookCount = Workbooks.Count
End Sub

Function BookAdded() As Boolean
    If mlBookCount <> Workbooks.Count Then
        BookAdded = True
        CountBooks
    End If
End Function

' Purpose   : Checks if a new workbook has been opened 
' (repeatedly until activeworkbook is not nothing)
'-------------------------------------------------------------------------
Sub CheckIfBookOpened()

    If BookAdded Then
        If ActiveWorkbook Is Nothing Then
            mlBookCount = 0
            TimesLooped = TimesLooped + 1
            'May be needed if Excel is opened from Internet explorer
            Application.Visible = True
            If TimesLooped < 20 Then
                Application.OnTime Now + TimeValue("00:00:01"), "CheckIfBookOpened"
            Else
                TimesLooped = 0
            End If
        Else
            ProcessNewBookOpened ActiveWorkbook
        End If
    End If
End Sub

Public Property Get TimesLooped() As Long
    TimesLooped = mlTimesLooped
End Property

Public Property Let TimesLooped(ByVal lTimesLooped As Long)
    mlTimesLooped = lTimesLooped
End Property

类模块名为 cAppEvents

' Purpose   : Handles Excel Application events
'-------------------------------------------------------------------------
Option Explicit

'This object variable will hold the object who's events we want to respond to
Public WithEvents App As Application

Private Sub App_WorkbookOpen(ByVal Wb As Workbook)

    'Make sure newly opened book is valid
    ProcessNewBookOpened Wb
End Sub

Private Sub Class_Terminate()
    Set App = Nothing
End Sub

【讨论】:

    【解决方案2】:

    这样的?

    Option Explicit
    Sub Button()
        Dim cButton As Button
        Dim rng As Range
        Dim i As Long
    
        ActiveSheet.Buttons.Delete
    
        For i = 2 To 3 Step 2
            Set rng = ActiveSheet.Range(Cells(i, 2), Cells(i, 2))
            Set cButton = ActiveSheet.Buttons.Add(rng.Left, rng.Top, rng.Width, rng.Height)
            With cButton
                .OnAction = "Test_Press"
                .Caption = "Press for Test " & i
                .Name = "Test" & i
            End With
        Next i
    End Sub
    

    参见示例here

    【讨论】:

    • 这实际上是我用来协助编写代码的 THE 示例。问题是我需要宏成为 Excel 加载项的一部分。我们称之为 addin.xlam。我有一个名为 Test.xlsm 的电子表格。如果 100 个人可以只安装 addin ONCE,然后每周他们都下载一个新的 Test 副本,那就太好了,当他们打开该电子表格时,会为他们显示按钮。您答案中的代码与我的问题相同。当你打开一个电子表格时,你安装的插件首先加载,当它加载时它运行你的代码Button,但是没有 ActiveSheet。
    猜你喜欢
    • 1970-01-01
    • 2011-09-05
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 2011-12-13
    相关资源
    最近更新 更多