Accesso a Proprietà del documento personalizzato di Excel a livello di codice

Sto cercando di aggiungere proprietà personalizzate a una cartella di lavoro che ho creato a livello di codice. Ho un metodo per ottenere e impostare le proprietà, ma il problema è che la cartella di lavoro restituisce null per la proprietà CustomDocumentProperties. Non riesco a capire come inizializzare questa proprietà in modo che possa aggiungere e recuperare proprietà dalla cartella di lavoro. Microsoft.Office.Core.DocumentProperties è un’interfaccia, quindi non posso andare e fare quanto segue

if(workbook.CustomDocumentProperties == null) workbook.CustomDocumentProperties = new DocumentProperties; 

Ecco il codice che devo ottenere e impostare le proprietà:

  private object GetDocumentProperty(string propertyName, MsoDocProperties type) { object returnVal = null; Microsoft.Office.Core.DocumentProperties properties; properties = (Microsoft.Office.Core.DocumentProperties)workBk.CustomDocumentProperties; foreach (Microsoft.Office.Core.DocumentProperty property in properties) { if (property.Name == propertyName && property.Type == type) { returnVal = property.Value; } DisposeComObject(property); } DisposeComObject(properties); return returnVal; } protected void SetDocumentProperty(string propertyName, string propertyValue) { DocumentProperties properties; properties = workBk.CustomDocumentProperties as DocumentProperties; bool propertyExists = false; foreach (DocumentProperty prop in properties) { if (prop.Name == propertyName) { prop.Value = propertyValue; propertyExists = true; } DisposeComObject(prop); if(propertyExists) break; } if (!propertyExists) { properties.Add(propertyName, false, MsoDocProperties.msoPropertyTypeString, propertyValue, Type.Missing); } DisposeComObject(propertyExists); } 

La proprietà line = workBk.CustomDocumentProperties come DocumentProperties; imposta sempre le proprietà su null.

Questo sta usando Microsoft.Office.Core v12.0.0.0 e Microsoft.Office.Interop.Excell v12.0.0.0 (Office 2007)

Ho guardato il mio codice e posso vedere che accedo alle proprietà usando l’associazione tardiva. Non riesco a ricordare perché, ma inserirò del codice nel caso in cui sia d’aiuto.

 object properties = workBk.GetType().InvokeMember("CustomDocumentProperties", BindingFlags.Default | BindingFlags.GetProperty, null, workBk, null); object property = properties.GetType().InvokeMember("Item", BindingFlags.Default | BindingFlags.GetProperty, null, properties, new object[] { propertyIndex }); object propertyValue = property.GetType().InvokeMember("Value", BindingFlags.Default | BindingFlags.GetProperty, null, propertyWrapper.Object, null); 

EDIT : ah, ora mi ricordo perché . 🙂

EDIT 2 : la risposta di Jimbojones – per utilizzare la parola chiave dynamic – è una soluzione migliore (se si considera la facilità d’uso rispetto al sovraccarico prestazionale dell’utilizzo dynamic ).

Se si sta utilizzando .NET 4.0, è ansible utilizzare la parola chiave dynamic per l’associazione tardiva

  Document doc = GetActiveDocument(); if ( doc != null ) { dynamic properties = doc.CustomDocumentProperties; foreach (dynamic p in properties) { Console.WriteLine( p.Name + " " + p.Value); } } 

Ho trovato la soluzione qui .

Ecco il codice che ho trovato:

  public void SetDocumentProperty(string propertyName, string propertyValue) { object oDocCustomProps = workBk.CustomDocumentProperties; Type typeDocCustomProps = oDocCustomProps.GetType(); object[] oArgs = {propertyName,false, MsoDocProperties.msoPropertyTypeString, propertyValue}; typeDocCustomProps.InvokeMember("Add", BindingFlags.Default | BindingFlags.InvokeMethod, null, oDocCustomProps, oArgs); } private object GetDocumentProperty(string propertyName, MsoDocProperties type) { object returnVal = null; object oDocCustomProps = workBk.CustomDocumentProperties; Type typeDocCustomProps = oDocCustomProps.GetType(); object returned = typeDocCustomProps.InvokeMember("Item", BindingFlags.Default | BindingFlags.GetProperty, null, oDocCustomProps, new object[] { propertyName }); Type typeDocAuthorProp = returned.GetType(); returnVal = typeDocAuthorProp.InvokeMember("Value", BindingFlags.Default | BindingFlags.GetProperty, null, returned, new object[] { }).ToString(); return returnVal; } 

Una certa gestione delle eccezioni è necessaria da consegnare se la proprietà non esiste quando viene recuperata

Risposta tardiva a questa domanda, ma ho elaborato un metodo più semplice per aggiungere DocumentProperties personalizzate che potrebbero essere utili a qualcuno in futuro.

Il mio problema è stato che chiamare il metodo Add () con il tipo di sistema fornito da System.String.GetType () ha triggersto un COMException: Type mismatch. Facendo riferimento al link nelle risposte precedenti è chiaro che questo metodo si aspetta un tipo specifico di Office, quindi il codice che ha finito per funzionare per me è stato:

 var custProps = (Office.DocumentProperties)this.CustomDocumentProperties; custProps.Add( "AProperty", false, MsoDocProperties.msoPropertyTypeString, "AStringProperty" ); 

Poiché si tratta di un object CustomDocumentProperty, la proprietà personalizzata verrà aggiunta senza difficoltà, ma se è necessario verificare l’esistenza o convalidare il valore quando la proprietà CustomDocument non esiste, sarà necessario rilevare System.ArgumentException.

MODIFICARE

Come sottolineato nel commento di Oliver Bock, questo è un Office 2007 e una soluzione unica, per quanto ne so.