【问题标题】:How to inject VBA code into Excel .xlsm without using Interop?如何在不使用互操作的情况下将 VBA 代码注入 Excel .xlsm?
【发布时间】:2012-01-10 00:42:14
【问题描述】:

我的目标是将宏添加到 Excel 工作簿,而无需在 Excel 信任中心中启用“信任对 VBA 项目对象模块的访问”。 (启用访问似乎存在安全风险)。

在我最初的事实调查搜索中发现了一些随机的谜题: -我看到 VBA 脚本作为 vbaProject.bin 存储在压缩的 .xlsm 文件中。 - 有几个免费/商业资源可以处理 excel 文件: Create excel without interop and template with or without row and columnspan

最好在 C# 项目中简单地拥有一个 VBA 脚本文件,C# 代码从该文件中提取并注入到没有 VBA 互操作的 Excel 文档中。有什么快速/快速/简单/直接的方法可以做到这一点,还是我应该使用上面链接的免费/商业资源?

【问题讨论】:

    标签: c# excel interop vba


    【解决方案1】:

    使用OpenXML SDK 2.0

    1. 创建宏代码并将其保存为 .xlsm 格式,例如 snorehorse.xlsm。
    2. 在 OpenXML Productivity Toolkit 中打开 snorehorse.xlsm 并在树根上执行反射代码。
    3. 找到宏的二进制代码。它是字符串格式,看起来像随机字符。
    4. 在您的 IDE 中,添加对 OpenXML SDK 的引用,并以编程方式创建或打开您要向其中注入宏代码的 excel 文件。
    5. 将第 3 步中找到的宏字符串复制到您的代码中。
    6. 向目标添加新的 vba 部件。
    7. 将字符串数据输入新的 vba 部分。
    8. 保存并运行,很高兴您绕过了信任中心。

    示例代码:

    using DocumentFormat.OpenXml;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Spreadsheet;
    
    private string partData = "...";
    
        public void vbaInjector{    
            [code to create / open spreadsheet using OpenXML omitted]
            VbaProjectPart vbaProjectPart1 = snoreSpreadsheetDoc.WorkbookPart.AddNewPart<VbaProjectPart>("rId8");
            System.IO.Stream data = GetBinaryDataStream(partData);
            vbaProjectPart1.FeedData(data);
            data.Close();
            [code to close spreadsheet and cleanup omitted]
        }
    
    
        private System.IO.Stream GetBinaryDataStream(string base64String)
        {
            return new System.IO.MemoryStream(System.Convert.FromBase64String(base64String));
        }
    

    我选择将 OpenXML SDK dll 添加到项目的本地构建中,这样最终用户就不必自己安装 SDK。

    我认为这可以在较低级别上完成,使用 XML,而不使用 OpenXML SDK,但我还没有尝试学习如何做到这一点。如果有人可以发布代码,我会接受我的答案。

    此外,如果有一种编程方式将嵌入资源文件中的 VBA 脚本转换为 excel 期望格式的二进制字符串,则可以绕过每次复制和粘贴新的二进制数据字符串的麻烦。想更改宏代码。这将是我的一个更好的答案。

    谢谢。

    【讨论】:

    • 1 小时后,我仍然无法将任何代码注入到我的项目中而不会损坏它。仅当我执行 OpenXML 工具包反映的所有代码时才有效。
    • 在黑暗中拍摄...也许“rId8”已被使用?把它改成“rId888”怎么样?
    【解决方案2】:

    如果您使用 EPPlus,您现在可以通过编程方式包含 VBA。见这里:

    Writing and Executing VBA Macros on Excel without using Excel.Interop

    【讨论】:

    • 仅链接答案并不是帮助人们的最佳方式
    • 即使链接指向另一个 Stack Overflow 答案?我应该复制粘贴它吗?
    猜你喜欢
    • 2016-05-27
    • 1970-01-01
    • 2012-05-11
    • 2011-06-23
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多