7

我正在使用大量 Excel vba 脚本,其中一些脚本绑定到 Ctrl 键组合。

我知道如何在 Excel 的用户界面中一次设置一个:拉出 vba 脚本列表 (Alt-F8),选择一个脚本,然后单击选项。然后,您可以将脚本绑定/取消绑定到 Ctrl 键组合。但是,您可以将多个脚本绑定到同一个键,Excel 将选择一个(可能是以某种方式找到的第一个)并忽略其他绑定。

所以,我想将 Ctrl-e 分配给一个脚本,但首先我必须从数百个脚本的列表中找到它当前绑定的其他脚本。

有没有办法让 Excel 列出当前的键绑定(我想用 VBA 宏)?我已经看到了 Word 的解决方案,它检查“KeyBindings”集合。但是,这在 Excel 中不起作用。Excel 有不同的对象吗?

4

2 回答 2

5

搜索了一段时间后,我找不到任何以编程方式获取所有键绑定列表的可能性。

但是,如果您基本上想知道哪个程序在快捷方式上运行,但您不确定并且不想爬过您的个人工作簿、加载项等,您可以创建一个动态断点,该断点将总是在执行的 VBA 代码的第一行停止。为此,只需使用Add Watch对话框(右键单击代码窗口中的某处)输入以下参数:

表达式:计时器,过程:全部模块:全部,手表类型:值更改时中断

然后,只需执行您感兴趣的快捷方式 - VBE 将向您显示绑定到它的例程...

于 2013-06-01T22:22:24.457 回答
4

您可以使用 VBA 宏列出分配给宏的键。事实证明,虽然快捷键不能“直接”访问,但如果你导出一个模块,任何快捷键都会在导出的文件中列出。然后可以解析该文件以返回过程名称和关联的快捷键。

导出文件中包含此信息的行如下所示:

属性MacroShortCutKeys .VB_ProcData.VB_Invoke_Func = " a \n14"

上面加粗的信息是宏的名称,以及相关的快捷键。我不知道结尾的 \n14 的重要性(我不确定它是否会保持一致,因为我没有对此进行广泛的测试。

运行下面的宏需要您在信任中心设置中将选项设置为信任对 VBA 项目对象模型的访问;并且您在代码中列出的 VBA 中设置引用。

我刚刚将结果输出到即时窗口,但您也可以轻松地将其放在工作表上。

导出的文件存储在文件夹 C:\Temp 中,完成后文件将被删除。如果 C:\Temp 不存在,则必须创建它。(这可以在宏中完成,但我很懒)。

如果宏没有快捷键,则不会列出。

编辑该例程仅列出使用 Excel 工作表上的“宏”对话框分配的那些快捷方式。它不会列出使用 Application.OnKey 方法分配的快捷键。还不知道如何获得这些。

Option Explicit
'MUST set to Trust Access to the VBA Project Object Model
'  in Excel Options
'Set reference to:
'Microsoft Visual Basic for Applications Extensibility
'Microsoft Scripting Runtime
'Microsoft VBScript Regular Expressions 5.5
Sub MacroShortCutKeys()
    Dim VBProj As VBIDE.VBProject
    Dim VBComp As VBIDE.VBComponent
    Dim CodeMod As CodeModule
    Dim LineNum As Long
    Dim ProcKind As VBIDE.vbext_ProcKind
    Dim sProcName As String, sShortCutKey As String
    Const FN As String = "C:\Temp\Temp.txt"
    Dim S As String
    Dim FSO As FileSystemObject
    Dim TS As TextStream
    Dim RE As RegExp, MC As MatchCollection, M As Match

Set RE = New RegExp
With RE
    .Global = True
    .IgnoreCase = True
    .Pattern = "Attribute\s+(\w+)\.VB_ProcData\.VB_Invoke_Func = ""(\S+)(?=\\)"
End With

Set FSO = New FileSystemObject
Set VBProj = ActiveWorkbook.VBProject
For Each VBComp In VBProj.VBComponents
    Select Case VBComp.Type
        Case Is = vbext_ct_StdModule
            VBComp.Export FN
            Set TS = FSO.OpenTextFile(FN, ForReading, Format:=TristateFalse)
            S = TS.ReadAll
            TS.Close
            FSO.DeleteFile (FN)
            If RE.Test(S) = True Then
                Set MC = RE.Execute(S)
                For Each M In MC
                    Debug.Print VBComp.Name, M.SubMatches(0), M.SubMatches(1)
                Next M
            End If
    End Select
Next VBComp
End Sub
于 2013-10-12T01:19:37.767 回答