c# - OpenXML SDK 将 VBA 注入(inject) excel 工作簿

标签 c# excel openxml-sdk vba

我可以成功地将一段 VBA 代码注入(inject)生成的 excel 工作簿,但我想做的是使用 Workbook_Open() 事件,以便在文件打开时执行 VBA 代码。我正在将 sub 添加到我的 xlsm 模板文件中的“ThisWorkbook”对象。然后我使用 openxml 生产力工具来反射(reflect)代码并获得编码的 VBA 数据。

生成文件并查看 VBA 时,我看到“ThisWorkbook”和“ThisWorkbook1”对象。我的 VBA 在“ThisWorkbook”对象中,但代码从不在打开时执行。如果我将我的 VBA 代码移动到“ThisWorkbook1”并重新打开文件,它工作正常。为什么要创建一个额外的“ThisWorkbook”?不能用 Workbook_Open() sub 注入(inject) excel 电子表格吗?这是我正在使用的 C# 代码片段:

private string partData = "...";  //base 64 encoded data from reflection code
//open workbook, myWorkbook
VbaProjectPart newPart = myWorkbook.WorkbookPart.AddNewPart<VbaProjectPart>("rId1");
System.IO.Stream data = GetBinaryDataStream(partData);
newPart.FeedData(data);
data.Close();
//save and close workbook

有人有想法吗?

最佳答案

根据我的研究,没有办法以您可以在 C# 中操作的格式插入项目部分数据。在 OpenXML 格式中,VBA 项目仍然以二进制格式存储。但是,将 VbaProjectPart 从一个 Excel 文档复制到另一个应该可行。因此,您必须提前确定您希望项目部分表达的内容。

如果您对此没问题,那么您可以将以下代码连同适当的宏代码一起添加到“ThisWorkbook”Microsoft Excel 对象中的模板 Excel 文件中:

Private Sub Workbook_Open()
    Run "Module1.SomeMacroName()"
End Sub

要将 VbaProjectPart 对象从一个文件复制到另一个文件,您可以使用如下代码:

public static void InsertVbaPart()
{
    using(SpreadsheetDocument ssDoc = SpreadsheetDocument.Open("file1.xlsm", false))
    {
        WorkbookPart wbPart = ssDoc.WorkbookPart;
        MemoryStream ms;
        CopyStream(ssDoc.WorkbookPart.VbaProjectPart.GetStream(), ms);

        using(SpreadsheetDocument ssDoc2 = SpreadsheetDocument.Open("file2.xlsm", true))
        {
            Stream stream = ssDoc2.WorkbookPart.VbaProjectPart.GetStream();
            ms.WriteTo(stream);
        }
    }
}

public static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[short.MaxValue + 1];
    while (true)
    {
        int read = input.Read(buffer, 0, buffer.Length);
        if (read <= 0)
            return;
        output.Write(buffer, 0, read);
    }
}

希望对您有所帮助。

关于c# - OpenXML SDK 将 VBA 注入(inject) excel 工作簿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9707228/

相关文章:

c# - 使用 Open XML SDK 读取上传的 pptx 文件

c# - Kinect NullReferenceException 错误

c# - JpegBitmapEncoder.Save() 在使用元数据写入图像时抛出异常

excel - Powershell 从 Excel 列导入的日期和时间格式错误

c# - 与 LINQ to XML 合并

c# - 无法使用 UWP 应用程序访问我系统上的 Word 文档

c# - 异步等待何时更改线程?

javascript - 如何获取复选框选定的值并传递给 asp.net mvc 4 中的 Controller

VBA 双舍入与单舍入

sql - 如何编写从 SQL 数据库返回值的 Excel 函数?