c# - 使用 Excel Interop 手动编译 PERSONAL.xlsb 时,将快捷键分配给 VBA 宏?

标签 c# excel vba excel-interop

这是一个小众问题,所以我会尽力定义所有内容。我正在使用 Excel 2007。

我们公司使用 excel 来制作表格。我们有许多 worker 使用这些表格。出于安全原因,我们不希望我们的电子表格包含宏,但我们仍然需要使用 VBA 对普通工作簿中的数据进行大量操作。因此,我们所有的宏都在每个员工的 PERSONAL.xlsb 文件中定义,并且可以在我们的正常工作簿上调用。由于我们在此工作簿上运行了许多不同的宏,因此使用快捷方式调用它们真的很方便。快捷方式在 excel 中定义,如下所示:

Assigning Macro Hotkeys

PERSONAL.xlsb 文件很特殊,因为无论何时打开任何 excel 文件,Excel 都会自动将其作为隐藏背景工作簿打开。这很棒,因为它使您能够在当前工作簿的 PERSONAL.xlsb 中调用用户定义的宏,而无需当前工作簿启用宏。

.xlsb 是一个二进制扩展名,并使用一些专有的 Microsoft 压缩算法。问题是编写宏和 VBA 代码是通过 Excel 中捆绑的 VBA IDE 完成的。这意味着您编写的代码不以明文形式存储,excel 充当中间人,将您的 VBA 代码读取/写入 .xlsb 文件中的二进制 blob。

由于我们使用(并计划添加)许多宏,因此在我选择的编辑器中将它们编码为普通文件并使用 git 跟踪更改将非常有利。理想情况下,我想要一个包含一堆不同 .vba 文件的开发文件夹,以便在逻辑上分隔每个宏。然后我想要一个纯文本配置文件,为每个 .vba 代码模块定义可选的快捷键。

然后,当我对更改感到满意时,我想运行一个使用 Microsoft Excel Interop 的程序将这一切编译成一个漂亮的 PERSONAL.xlsb 文件,可以很容易地保持最新并发送给其他员工。我几乎实现了所有这些,但我不知道如何将快捷键分配给代码模块。

这是我将 VBA 文件编译成 .xlsb 文件的示例代码:

using Microsoft.Office.Interop.Excel;
using Microsoft.Vbe.Interop;
using System;
using System.IO;

namespace BinaryCompile
{
    class Program
    {
        private static string path = @"C:\Users\Path\To\Source";

        static void Main(string[] args)
        {
            var excel = new Microsoft.Office.Interop.Excel.Application();
            //Console.WriteLine(path);
            var workbook = excel.Workbooks.Add();

            var project = workbook.VBProject;

            include_files(get_vba_files(), ref project);

            excel.MacroOptions();

            workbook.SaveAs(path + "/PERSONAL.xlsb", XlFileFormat.xlExcel12);
            workbook.Close();

            Console.Read();
            excel.Quit();

        }

        static string[] get_vba_files()
        {
            return Directory.GetFiles(path, "*.vba");
        }

        static void include_files(string[] vba_files, ref VBProject project)
        {
            foreach (string source in vba_files)
            {
                var module = project.VBComponents.Add(vbext_ComponentType.vbext_ct_StdModule);
                module.CodeModule.AddFromFile(source);
                module.Name = Path.GetFileNameWithoutExtension(source);

            }
        }
    }
}

我找不到任何关于如何为这些以编程方式生成的模块分配快捷键的文档。

最佳答案

这是一个选项,如果您可以随意修改 vba 文件。如果您在 Excel 中创建一个宏,分配一个快捷方式,然后导出模块,您将看到该文件具有以下结构:

Attribute VB_Name = "MyModule"
Sub MyFunction()
Attribute MyFunction.VB_ProcData.VB_Invoke_Func = "y\n14"
    'Do Your stuff
End Sub

Sub MyFunction2()
Attribute MyFunction2.VB_ProcData.VB_Invoke_Func = "q\n14"
    'Do more stuff
End Sub

"y\n14""q\n14" 中的第一个字符将是您与 Ctrl 键一起使用的快捷键,在这些情况下,Ctrl+yCtrl+q

旁注:我试过你的代码,我只能通过删除 excel.MacroOptions(); 行来让它工作。

关于c# - 使用 Excel Interop 手动编译 PERSONAL.xlsb 时,将快捷键分配给 VBA 宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48025523/

相关文章:

c# - 为什么将 ComboBox.SelectedValue 设置为 null 会导致 ArgumentNullException?

excel - 将输入框默认更改为当前输入

VBA使用FormulaR1C1找到左边直到空格

excel - 如何在 Excel 工作表中获取今天的日期?

c# - WCF REST 推送流服务

c# - 如何使用 Mongo 命令对 DocumentDB 中的文档执行 "patch"操作

c# - 如何将 Entity Framework 6 绑定(bind)到 KendoUI Grid

xml - 如何在 MSXML - VBA 中获取 XML 元素的数组索引?

python - 如何在python中将选定的数据从一列移动到另一列

excel - 根据多个条件筛选出 Power Query 的行