2012-03-14 56 views
3

我可以成功地將一塊VBA代碼注入到生成的Excel工作簿中,但我想要做的是使用Workbook_Open()事件,以便在打開文件時執行VBA代碼。我將該sub添加到我的xlsm模板文件中的「ThisWorkbook」對象中。然後,我使用openxml生產力工具來反映代碼並獲取編碼的VBA數據。OpenXML SDK將VBA注入到excel工作簿

生成文件並查看VBA時,會看到「ThisWorkbook」和「ThisWorkbook1」對象。我的VBA位於「ThisWorkbook」對象中,但代碼從不打開。如果我將我的VBA代碼移動到「ThisWorkbook1」並重新打開文件,它可以正常工作。爲什麼要創建一個額外的「ThisWorkbook」?是不可能注入一個Excel工作簿與Workbook_Open()子?這裏是我正在使用的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 

任何人有想法嗎?

+0

在VBA編輯器中,當您右鍵單擊ThisWorkbook和ThisWorkbook1時,是否將** Remove ThisWorkbook ... **選項變爲灰色? – 2012-03-21 14:03:00

回答

3

基於我的研究,沒有辦法以您可以在C#中操作的格式插入項目零件數據。在OpenXML格式中,VBA項目仍以二進制格式存儲。但是,將VbaProjectPart從一個Excel文檔複製到另一個文檔應該有效。因此,您必須事先確定您希望項目部分的內容。

如果你是這行,那麼你可以將下面的代碼添加到模板的Excel文件中的「的ThisWorkbook」 Microsoft 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); 
    } 
} 

希望有所幫助。

+0

我還應該補充說,寫完後我遇到了一個名爲[ClosedXML](http://closedxml.codeplex.com/)的平臺。它專爲與OpenXML Excel文件交互而設計,非常直觀,也可能有所幫助。 – Lentonator 2012-07-30 12:29:39