如何在不使用Interop的情况下将VBA代码注入Excel .xlsm?

时间:2011-11-30 19:26:32

标签: c# excel-vba interop vba excel

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

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

在C#代码中简单地拥有一个VBA脚本文件,C#代码从中提取并注入到Excel文档中而没有VBA互操作会很好。任何快速/快速/简单/直接的方式,或者我应该使用上面链接的免费/商业资源吗?

2 个答案:

答案 0 :(得分:6)

使用OpenXML SDK 2.0

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

    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 :(得分:2)

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

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