我正在处理大量Excel vba脚本,其中一些脚本与Ctrl键组合绑定。
我知道如何在Excel的用户界面中一次设置一个:拉出vba脚本列表(Alt-F8),选择一个脚本,然后单击选项。然后,您可以将脚本绑定/取消绑定到Ctrl键组合。但是,您可以将多个脚本绑定到同一个键,Excel将选择一个(可能是以某种方式找到的第一个)并忽略其他绑定。
所以,我想将Ctrl-e分配给一个脚本,但首先我必须从数百个脚本的列表中找到它当前绑定的其他脚本。
有没有办法让Excel列出当前的键绑定(我猜想用VBA宏)? 我见过Word的解决方案,它检查了“KeyBindings”集合。但是,这不适用于Excel。 Excel有不同的对象吗?
答案 0 :(得分:4)
搜索了一段时间后,我找不到以编程方式获取所有键绑定列表的任何可能性。
但是,如果您基本上想要查找,哪个过程在快捷方式上运行,但您不确定并且不想浏览个人工作簿,加载项等,则可以创建动态断点将始终在执行的第一行VBA代码上停止。为此,只需使用Add Watch
对话框(右键单击代码窗口中的某个位置),输入以下参数:
然后,只需执行您感兴趣的快捷方式 - VBE将向您显示绑定它的例程......
答案 1 :(得分: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