2012-03-14 36 views
3

VBAコードを生成したExcelワークブックに正常に挿入できますが、Workbook_Open()イベントを使用してファイルを開くときにVBAコードが実行されます。私はxlsmテンプレートファイルの "ThisWorkbook"オブジェクトにサブを追加しています。次にopenxml生産性ツールを使用してコードを反映させ、コード化されたVBAデータを取得します。OpenXML SDK excelワークブックにVBAを挿入

ファイルが生成され、VBAを表示すると、 "ThisWorkbook"と "ThisWorkbook1"オブジェクトが表示されます。私のVBAは "ThisWorkbook"オブジェクトにありますが、コードはopenで実行されません。 VBAコードを "ThisWorkbook1"に移動してファイルを再度開くと正常に動作します。余分な "ThisWorkbook"が作成されるのはなぜですか? Workbook_Open()サブとともに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 

アイデアはありますか?

+0

VBAエディタ内でThisWorkbookとThisWorkbook1を右クリックすると、** Remove ThisWorkbook ... **選択がグレー表示になりますか? –

答えて

3

私の研究に基づいて、C#で操作できる形式でプロジェクトのパーツデータを挿入する方法はありません。 OpenXML形式では、VBAプロジェクトはバイナリ形式で保存されます。ただし、1つのExcelドキュメントから別のExcelドキュメントにVbaProjectPartをコピーすると機能するはずです。その結果、あなたは、プロジェクトの前に何を言いたいのかを判断する必要があります。

あなたはこれでOKしている場合は、適切なマクロコードと一緒に、「はThisWorkbook」Microsoft ExcelのオブジェクトでテンプレートExcelファイルに次のコードを追加することができます。VbaProjectPartをコピーするには

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

一つのファイルから他のオブジェクト、あなたがこのようなコードを使用します。

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

関連する問題