1

我正在为 Excel 2003 编写一个小型 VBA 加载项,其想法是加载项在目录中查找任何“.xlt”文件,并为找到的每个文件添加一个按钮到“模板”菜单,该菜单提供快速获取空白模板的方法。大多数加载项都运行良好,但我遇到了一点问题,我很难理解为什么它不工作。

这是构建菜单的代码示例。

Public Sub BuildMenu()

Dim Active_Menu_Bar As Office.CommandBar
Dim Tmplts_MenuItem As Office.CommandBarControl
Dim Tmplts_MenuControl As Office.CommandBarControl
Dim objSearch
Dim TemplatesPath As String

DeleteControls

Application.Interactive = False

Set Active_Menu_Bar = Application.CommandBars.Item(1)
Set Tmplts_MenuItem = Active_Menu_Bar.Controls.Add(msoControlPopup, , , 10, True)

With Tmplts_MenuItem
    .Caption = "Templates"
    .BeginGroup = False
    .Tag = C_TAG
End With

TemplatesPath = FetchValue("TemplatesPath")

Set objSearch = Application.FileSearch
    objSearch.LookIn = TemplatesPath
    objSearch.SearchSubFolders = False
    objSearch.Filename = "*.xlt"
    objSearch.Execute

For Each strFile In objSearch.FoundFiles

    'Remove Path from strFile
    strFile = Replace(strFile, TemplatesPath, "")

    Select Case strFile
        Case "Journal.xlt"
            Set Tmplts_MenuControl = Tmplts_MenuItem.Controls.Add(Type:=msoControlButton, temporary:=True)
            With Tmplts_MenuControl
                .Caption = "New Journal"
                .OnAction = "'" & ThisWorkbook.Name & "'!NewJournal"
                .Tag = C_TAG
            End With

        Case "Budget Journal.xlt"
            Set Tmplts_MenuControl = Tmplts_MenuItem.Controls.Add(Type:=msoControlButton, temporary:=True)
            With Tmplts_MenuControl
                .Caption = "New Budget Journal"
                .OnAction = "'" & ThisWorkbook.Name & "'!NewBudgetJournal"
                .Tag = C_TAG
            End With

        Case Else
            Set Tmplts_MenuControl = Tmplts_MenuItem.Controls.Add(Type:=msoControlButton, temporary:=True)
            With Tmplts_MenuControl
                .Caption = "New " & strFile
                .OnAction = "'" & ThisWorkbook.Name & "'!NewGenericTemplate(""" & TemplatesPath & strFile & """)"
                .Tag = C_TAG
            End With

    End Select
Next

Set objSearch = Nothing

Set Tmplts_MenuControl = Tmplts_MenuItem.Controls.Add(Type:=msoControlButton, temporary:=True)
With Tmplts_MenuControl
    .Caption = "User Preferences"
    .OnAction = "'" & ThisWorkbook.Name & "'!UserPrefs"
    .BeginGroup = True
    .Tag = C_TAG
End With

Application.Interactive = True

End Sub

如您所见,有一个 select case 语句说,对于特定的“已知”模板,为按钮分配一个宏,以便处理该模板的要求(例如,Journal 模板的宏也填充了几个字段始终具有特定值的模板,例如由application.username) 填充的用户名,该位按预期工作。

问题在于 Case Else。我希望能够选择恰好在目录中的任何其他模板并将完整路径传递给“通用”宏,该宏将根据模板创建一个新工作簿,而无需任何花哨的附加功能,因此在OnAction部分MenuControl我正在传递模板的完整路径。

但是,当我单击菜单控件时,什么也没有发生,没有错误消息,什么都没有。

这是NewGenericTemplate宏的代码。

Sub NewGenericTemplate(MyTemplate As String)

Workbooks.Add Template:=MyTemplate
MsgBox MyTemplate

End Sub

简单的东西(意思是我可能忘记了一些非常明显的东西),msgbox当我意识到菜单按钮不起作用并且我想检查该值是否实际上被传递时,我添加了,所以现在我得到了 msgbox 而不是什么都没有(由于某种原因两次),它显示了模板的正确路径,但没有添加工作簿。

任何帮助,将不胜感激。

PS我也尝试在NewGenericTemplate宏中设置断点,但代码没有中断

4

2 回答 2

0

不幸的是,我不得不把这个问题搁置几个星期,但今天我回到了它,我决定回到基础,只是寻找一种方法将变量从菜单按钮传递到宏,从而导致我到这个线程

我现在所做的是将.OnAction属性从

.OnAction = "'" & ThisWorkbook.Name & "'!NewGenericTemplate(""" & TemplatesPath & strFile & """)"

.OnAction = "'NewGenericTemplate """ & strFile & """'"

所以基本上删除了对包含宏的文件的引用。我也只传递文件名而不是完整路径,所以下面是我现在用于NewGenericTemplate例程的代码。

Public Sub NewGenericTemplate(MyTemplate As String)

Dim TemplatesPath As String
Dim FullPathToTemplate As String

'Retrieve path to Templates Directory
TemplatesPath = FetchValue("TemplatesPath")

FullPathToTemplate = TemplatesPath & MyTemplate

If Dir(FullPathToTemplate) <> "" Then
    Workbooks.Add FullPathToTemplate
    Else
    MsgBox "Template File not Found, it may have been moved or deleted.", vbExclamation, "File Not Found"
End If

End sub

希望这应该是排序。

于 2013-04-18T11:16:29.457 回答
0

好的。我能够修改这个线程的建议。

使用新控件,添加.Parameter如下内容:

With Tmplts_MenuControl
   .OnAction = "'" & ThisWorkbook.Name & "'!NewGenericTemplate"
  .Parameter = "'" & ThisWorkbook.FullName & "'!NewGenericTemplate"
  .Caption = "New Generic Template"
  .FaceId = 99
  .Style = msoButtonCaption
  .BeginGroup = True
End With

然后,我修改NewGenericTemplate子程序来接收这个.Parameter。有点儿。由于我们不能按索引引用控件,因为它们看起来是动态的,所以我只是循环现有的控件/子控件,并myTemplate根据控件的.OnAction值进行分配。

Sub NewGenericTemplate()
Dim varControls As Variant 'top level controls
Dim ctrl As Variant 'secondary controls within top-level
Dim myTemplate As String

'Since I can't refernce the controls by Index (they are dynamic), we loop over them:
For Each varControls In Application.CommandBars("Command Bar Name").Controls '<--- EDIT AS NECESSARY
    For Each ctrl In varControls.Controls
        If ctrl.OnAction = "'" & ThisWorkbook.FullName & "'!NewGenericTemplate" Then
            myTemplate = ctrl.Parameter
            GoTo EarlyExit:
        End If
    Next
Next

Exit Sub 'if no parameter has been assigned.

EarlyExit:
If Not myTemplate = vbNullString Then
    Workbooks.Add Template:=myTemplate
End If

End Sub

这对我来说很成功,以前的尝试因您遇到的相同问题而失败。

于 2013-03-25T21:40:27.157 回答