Riepilogo
Questo articolo fornisce le risposte alle domande più comuni sull'automazione di Microsoft Office da Visual C++.
Ulteriori informazioni
Sommario
-
Che cos'è l'automazione?
-
Non si conosce l'automazione, dove si possono trovare buone risorse per saperne di più?
-
Esistono diversi modi per usare l'automazione?
-
Che cos'è COM?
-
Ricerca per categorie allegare all'istanza in esecuzione di un'applicazione di Office?
-
Ricerca per categorie passare parametri facoltativi?
-
Ricerca per categorie rilevare gli eventi esposti dalle applicazioni di Office?
-
Il codice di automazione è troppo lento. Come posso velocizzare le cose?
-
Cosa significano questi enormi valori di errore, come -2147352573 o 0x80030002?
-
Che cos'è una libreria dei tipi?
-
Il codice di automazione funzionava con Microsoft Excel 95, ma non con Microsoft Excel 97. Perché?
-
Perché l'applicazione che automatisco rimane in memoria al termine del programma?
-
Si sa cosa si vuole fare come utente di un'applicazione di Microsoft Office, ma come si esegue questa operazione a livello di programmazione usando l'automazione?
-
È possibile automatizzare un'applicazione di Microsoft Office incorporata?
-
Ricerca per categorie accedere alle proprietà del documento in un documento di Microsoft Office?
Domande e risposte
-
Che cos'è l'automazione?
L'automazione (in precedenza automazione OLE) è una tecnologia che consente di sfruttare le funzionalità di un programma esistente e incorporarlo nelle proprie applicazioni. Ad esempio, è possibile utilizzare le funzionalità di controllo ortografico e grammaticale di Microsoft Word nell'applicazione senza Microsoft Word visibile agli utenti. È anche possibile usare tutti gli strumenti di creazione di grafici, stampa e analisi dei dati di Microsoft Excel. Questa tecnologia può semplificare e velocizzare notevolmente lo sviluppo. -
Non si conosce l'automazione, dove si possono trovare buone risorse per saperne di più? Il capitolo 24 di "Inside Visual C++" di David Kruglinski (ISBN:1-57231-565-2) fornisce una panoramica generale e alcuni ottimi esempi. Inoltre, la Microsoft Knowledge Base è una buona fonte di informazioni.
Se preferisci imparare per esempio, vedi il seguente articolo della Microsoft Knowledge Base:179706 HOWTO Utilizzare MFC per automatizzare Excel & creare/formattare una nuova cartella di lavoro
-
Esistono diversi modi per usare l'automazione?
L'automazione può essere usata in tre modi: MFC, #import e C/C++:-
Con MFC, utilizzare la Creazione guidata classe di Visual C++ per generare "classi wrapper" dalle librerie dei tipi di Microsoft Office. Queste classi, così come altre classi MFC, come COleVariant, COleSafeArray, COleException, semplificano le attività di automazione. Questo metodo è in genere consigliato rispetto agli altri e la maggior parte degli esempi della Microsoft Knowledge Base utilizza MFC.
-
#import, una nuova direttiva resa disponibile con Visual C++ 5.0, crea i "puntatori intelligenti" VC++ da una libreria dei tipi specificata. È molto potente, ma spesso non consigliato a causa di problemi di conteggio dei riferimenti che in genere si verificano quando vengono usati con le applicazioni di Microsoft Office.
-
L'automazione C/C++ è molto più difficile, ma a volte necessaria per evitare sovraccarichi con MFC o problemi con #import. Fondamentalmente, si usano API come CoCreateInstance( e interfacce COM come IDispatch e IUnknown.
È importante notare che ci sono alcune leggere differenze tra l'automazione da C++ rispetto alla normale C, perché COM è stato progettato intorno alla classe C++.
-
-
Che cos'è COM?
L'automazione si basa sul modello COM (Component Object Model). COM è un'architettura software standard basata sulle interfacce e progettata per separare il codice in oggetti autonomi. Si tratta di un'estensione del paradigma OOP (Object Oriented Programming), ma applicabile a applicazioni separate. Ogni oggetto espone un set di interfacce e tutte le comunicazioni a un oggetto, come l'inizializzazione, le notifiche e il trasferimento dei dati, avvengono tramite queste interfacce. COM è anche un set di servizi forniti da DLL (Dynamic-Link Libraries) installate con il sistema operativo. L'automazione usa molti di questi servizi. Un esempio è il servizio "Marshalling", che esegue il pacchetto delle chiamate dell'applicazione client alle funzioni membro delle interfacce dell'applicazione server e le passa, con i relativi argomenti, all'applicazione server. Sembra che le interfacce del server siano esposte nello spazio di memoria del client, il che non accade quando il client è un .exe in esecuzione nel proprio spazio di processo. Il marshalling recupera anche i valori restituiti dai metodi del server oltre i limiti del processo e in modo sicuro nelle mani della chiamata del client. Esistono molti altri servizi essenziali per l'automazione forniti dalle varie librerie COM. Tra le fonti d'informazione vi sono "Inside Ole - Second Edition" di Kraig Byteschmidt, ISBN 1-55615-843-2, "Inside COM" di Dale Rogerson - ISBN 1-57231-349-8 e "Automation Programmer's Reference", ISBN 1-57231-584-9. -
Ricerca per categorie allegare all'istanza in esecuzione di un'applicazione di Office?
Usare l'API GetActiveObject(). I server di automazione si registrano nella tabella degli oggetti ROT (Running Object Table), tramite l'API RegisterActiveObject(). I client di automazione possono arrivare all'istanza in esecuzione con codice come:// Translate server ProgID into a CLSID. ClsidFromProgID // gets this information from the registry. CLSID clsid; CLSIDFromProgID(L"Excel.Application", &clsid); // Get an interface to the running instance, if any.. IUnknown *pUnk; HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk); ASSERT(!FAILED(hr)); // Get IDispatch interface for Automation... IDispatch *pDisp; hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pDisp); ASSERT(!FAILED(hr)); // Release the no-longer-needed IUnknown... pUnk->Release();
NOTA: se sono in esecuzione più istanze dell'applicazione di Office da allegare, sarà possibile collegarsi solo alla prima istanza avviata con l'API GetActiveObject().
Teoricamente, è possibile iterazione ROT per ogni singola istanza, ma le app di Office non si registrano se un'altra istanza è già in ROT perché il moniker per sé è sempre lo stesso (non poteva essere distinto comunque). Questo significa che non è possibile allegare a qualsiasi istanza, ad eccezione della prima. Tuttavia, poiché le app di Office registrano anche i propri documenti in ROT, è possibile allegare correttamente ad altre istanze iterando rot cercando un documento specifico, allegandolo e ottenendo l'oggetto Application da esso. Non è necessario eseguire questa operazione per PowerPoint, perché si tratta di un'applicazione a singola istanza. è possibile eseguire una sola istanza. -
Ricerca per categorie passare parametri facoltativi?
Alcuni metodi hanno parametri "facoltativi". In Visual Basic, è possibile omettere casualmente quando si chiama il metodo. Tuttavia, quando si chiama con Visual C++ è necessario passare uno speciale VARIANT il cui campo .vt è VT_ERROR e .scode campo è DISP_E_PARAMNOTFOUND. Cioè:// VARIANT used in place of optional-parameters. VARIANT varOpt; varOpt.vt = VT_ERROR; varOpt.scode = DISP_E_PARAMNOTFOUND;
Questo è davvero ciò che Visual Basic sta facendo dietro le quinte.
-
Ricerca per categorie rilevare gli eventi esposti dalle applicazioni di Office?
Fondamentalmente si implementa l'interfaccia evento che si desidera intercettare (il "sink") e impostare una connessione di avviso con l'applicazione (l'"origine"). In generale, per configurare la connessione di avviso, si ottiene IConnectionPointContainer del server e si chiama FindConnectionPoint() con l'IID dell'interfaccia evento. In questo modo si ottiene un'interfaccia IConnectionPoint e tutto ciò che rimane è chiamare Advise() con un'istanza dell'interfaccia evento. Il server richiama quindi attraverso questa interfaccia quando si verificano questi eventi. -
Il codice di automazione è troppo lento. Come posso velocizzare le cose?
Una causa comune di problemi di velocità con l'automazione è la lettura e la scrittura ripetitive dei dati. Questo è tipico per i client di automazione di Excel. Tuttavia, la maggior parte degli utenti non è a conoscenza del fatto che questi dati in genere possono essere scritti o letti contemporaneamente usando SAFEARRAY. Per altre informazioni ed esempi informativi, vedere il seguente articolo della Microsoft Knowledge Base:179706 HOWTO: Utilizzare MFC per automatizzare Excel e creare/formattare una nuova cartella di lavoro Inoltre, è importante sottolineare che l'uso degli Appunti a volte può migliorare le prestazioni. Ad esempio, è possibile copiare i dati negli Appunti, quindi usare l'automazione per indicare al server di incollare. Oppure viceversa; indicare al server di copiare gli Appunti e incollarli nell'applicazione.
-
Cosa significano questi enormi valori di errore, ad esempio -2147352573 o 0x80030002?
Questi valori sono noti come HRESULTs e sono definiti in winerror.h. I numeri sono così grandi perché il primo bit indica se si tratta o meno di un risultato di errore. È possibile usare l'utilità ErrLook.Exe fornita con Visual C++ per tradurre questi numeri in descrizioni significative. Se si vuole ottenere a livello di programmazione una descrizione degli errori, è possibile usare l'API FormatMessage().NOTA: se si usa Visual C++ 6.0 e si dispone di una variabile contenente questo valore nella finestra dell'orologio di debug, aggiungere ", hr" (senza virgolette) per fare in modo che Visual C++ lo traduca automaticamente!
-
Che cos'è una libreria dei tipi?
Una libreria dei tipi è simile a un file di intestazione C/C++. Contiene le interfacce, i metodi e le proprietà che un server sta pubblicando. È possibile visualizzare la libreria dei tipi con il Visualizzatore oggetti OLE/COM (Oleview.exe) incluso in Visual C++. Ecco un elenco dei nomi file della raccolta tipi per Microsoft Office 95, 97 e 2000: | delle applicazioni di Office Libreria dei tipi ------------------------+---------------- Word 95 e versioni precedenti | wb70en32.tlb Excel 95 e | precedenti xl5en32.olb PowerPoint 95 e versioni precedenti | Powerpoint.tlb Access 95 e versioni precedenti | msaccess.tlb Raccoglitore 95 | binder.tlb Schedule+ | sp7en32.olb Project | pj4en32.olb | Team Manager mstmgr1.olb Word 97 | msword8.olb Excel 97 | excel8.olb PowerPoint 97 | msppt8.olb | di Access 97 msacc8.olb Raccoglitore 97 | msbdr8.olb Grafico 97 | graph8.olb Outlook 97 | msoutl8.olb Outlook 98 | msoutl85.olb Word 2000 | msword9.olb Excel 2000 | excel9.olb PowerPoint 2000 | msppt9.olb Access 2000 | msacc9.olb Outlook 2000 | msoutl9.olb Word 2002 | msword.olb Excel 2002 | excel.exe PowerPoint 2002 | msppt.olb Access 2002 | msacc.olb Outlook 2002 | msoutl.olb
-
Il codice di automazione funzionava con Excel 95, ma non riesce con Excel 97. Cosa sta succedendo?
Il modello a oggetti per Excel ha apportato una modifica significativa dalla versione 95 alla 97. Excel 95 ha implementato tutti i metodi e le proprietà in una singola implementazione di IDispatch. Questo significava che spesso si potevano chiamare metodi destinati all'oggetto X, dall'oggetto Y. Si tratta di una progettazione non valida, quindi in Office 97 ogni oggetto ha una propria implementazione Idispatch separata. Ciò significa che se si chiede un metodo o una proprietà dall'oggetto X da un oggetto separato Y, viene visualizzato l'errore 0x80020003, -2147352573, "Membro non trovato". Per evitare questo errore, è necessario assicurarsi che l'interfaccia IDispatch sottostante da cui si effettuano chiamate sia semanticamente corretta. -
L'applicazione che automatisco rimane in memoria al termine del programma. Cosa sta succedendo?
Molto probabilmente, questo è perché hai dimenticato di rilasciare un'interfaccia acquisita e dovrai individuarla. Ecco alcuni suggerimenti generali ed elementi da cercare:-
Se si usa #import, è molto probabile che si stia verificando uno dei bug associati al conteggio dei riferimenti. Spesso i bug possono essere corretti, ma in genere è preferibile usare uno degli altri metodi di automazione. #import non funziona molto bene con le applicazioni di Office, perché le librerie dei tipi e l'uso sono piuttosto complessi. Inoltre, tali problemi di conteggio dei riferimenti sono difficili da individuare perché molte delle chiamate COM a livello di interfaccia sono dietro le quinte quando si usa #import.
-
Verificare se si stanno chiamando metodi, ad esempio Open o New, che restituiscono un IDispatch * (LPDISPATCH) e ignorare il valore restituito. Se lo sei, stai abbandonando questa interfaccia restituita e dovrai modificare il codice in modo da rilasciarlo quando non è più necessario.
-
Aggiungi gradualmente un commento alle sezioni del codice fino a quando il problema non scompare, quindi aggiungilo di nuovo con cautela per individuare l'inizio del problema.
-
Si noti che alcune applicazioni rimarranno in esecuzione se l'utente ha "toccato" l'applicazione. Se ciò si verifica durante l'automazione, l'applicazione rimarrà probabilmente in esecuzione in un secondo momento. Le applicazioni di Office hanno una proprietà "UserControl" nell'oggetto Application che è possibile leggere/scrivere per modificare questo comportamento.
-
Inoltre, alcune applicazioni decideranno di rimanere in esecuzione se si è verificato un sufficiente "intervento" dell'interfaccia utente. Se si intende uscire dall'applicazione, chiamare il relativo metodo Quit() sull'oggetto Application. Word verrà arrestato indipendentemente dal numero di riferimenti quando si chiama Esci. Questo comportamento COM non è previsto. Excel, tuttavia, si nasconderà correttamente, ma rimarrà in esecuzione fino al rilascio di tutte le interfacce eccezionali. In generale, è consigliabile rilasciare tutti i riferimenti in sospeso e chiamare Quit() solo se si prevede che l'applicazione venga chiusa.
-
-
Si sa cosa si vuole fare come utente di un'applicazione di Office, ma come si esegue questa operazione a livello di programmazione tramite l'automazione?
Ciò che interessa sono gli oggetti, i metodi e le proprietà che è necessario usare. Il modo migliore per imparare a esplorare i modelli a oggetti di Word, Excel e PowerPoint, in base all'operazione che si vuole eseguire come utente, consiste nell'usare il registratore macro. Basta scegliere Macro\'Registra nuova macro' dal menu Strumenti, eseguire l'attività desiderata, quindi scegliere Macro\'Interrompi registrazione'. Al termine della registrazione, scegliere Macro\Macro dal menu Strumenti, selezionare la macro registrata e quindi fare clic su Modifica. Verrà visualizzato il codice VBA generato che eseguirà l'attività registrata. Tenere presente che la macro registrata non sarà il codice migliore possibile nella maggior parte dei casi, ma è molto buona per un esempio rapido. -
È possibile automatizzare un'applicazione di Office incorporata?
Assolutamente. Il trucco è ottenere il puntatore IDispatch: questo è dato in Visual C++ Technical Note 39 (TN039). -
Ricerca per categorie accedere alle proprietà del documento in un documento di Office?
Le proprietà del documento sono accessibili tramite l'automazione o direttamente tramite IPropertyStorage.