2011-11-30 7 views
5

Il mio obiettivo è aggiungere macro a una cartella di lavoro di Excel senza dover abilitare "Accesso sicuro al modulo dell'oggetto di progetto VBA" nel Centro protezione dati Excel. (Abilitare l'accesso sembra un rischio per la sicurezza).Come iniettare il codice VBA in Excel .xlsm senza usare Interop?

Trovati pezzi casuali di rompicapo nella mia ricerca iniziale dei fatti: -Vedo che lo script VBA è archiviato nel file .xlsm compresso come vbaProject.bin. -Ci sono diverse risorse gratuite/commerciali che possono lavorare con i file excel: Create excel without interop and template with or without row and columnspan

Sarebbe bello avere semplicemente un file di script di VBA nel progetto C# che il codice C# tira da e inietta nel documento Excel senza VBA interop. Qualunque modo veloce/veloce/semplice/diretto per fare questo o dovrei giocare con le risorse gratuite/commerciali collegate a sopra?

risposta

6

Utilizzando OpenXML SDK 2.0:

  1. Crea il codice di macro e salvarlo in formato .xlsm, dicono snorehorse.xlsm.
  2. Aprire snorehorse.xlsm nel toolkit di produttività OpenXML e creare un codice Reflect nella radice dell'albero.
  3. Trova il codice binario della macro. È in un formato stringa e sembra un personaggio casuale.
  4. Nel proprio IDE, aggiungere un riferimento a OpenXML SDK e creare o aprire a livello di codice il file excel in cui si desidera iniettare il codice macro.
  5. Copia la stringa di macro trovata nel passaggio n. 3 nel codice.
  6. Aggiungere una nuova parte vba alla destinazione.
  7. Inserire i dati della stringa nella nuova parte vba.
  8. Salva ed esegui e sii contento di aver bypassato il Trust Center.

codice Esempio:

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)); 
    } 

ho scelto di aggiungere il dll OpenXML SDK nella costruzione locale del progetto in modo gli utenti finali non dovranno installare l'SDK stessi.

Penso che questo possa essere fatto a un livello inferiore, lavorando con l'XML, senza usare l'SDK OpenXML, ma non ho tentato di imparare come farlo. Se qualcuno può pubblicare il codice, accetterò la risposta sul mio.

Inoltre, se si avesse un modo programmatico per convertire lo script VBA, in un file di risorse incorporato, in una stringa binaria del formato che Excel si aspetta, si potrebbe evitare di copiare e incollare una nuova stringa di dati binari ogni volta volevi cambiare il codice macro. Questa sarebbe una risposta superiore alla mia.

Grazie.

+0

Funziona ancora? Lo proverò sicuramente adesso. –

+0

Dopo 1 ora non riesco ancora a inserire alcun codice nel mio progetto senza corromperlo. Funziona solo se eseguo TUTTO il codice riflesso da OpenXML Toolkit. –

+0

Girato nel buio ... forse "rId8" è già usato? Che ne dici di cambiarlo in qualcosa come "rId888"? – Snorex

1

Se si utilizza EPPlus, è ora possibile includere VBA a livello di programmazione. Vedi qui:

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

+0

Le risposte solo sul collegamento non sono il modo migliore per aiutare le persone –

+1

Anche se il collegamento punta a un'altra risposta di overflow dello stack? Dovrei averlo incollato sulla copia? –