Samenvatting
In dit artikel worden veelgestelde vragen over Automation naar Microsoft Office van Visual C++ beantwoord.
Meer informatie
Inhoudsopgave
-
Wat is Automation?
-
Ik ben nieuw bij Automation, waar vind ik goede resources voor meer informatie?
-
Zijn er verschillende manieren waarop ik Automation kan gebruiken?
-
Wat is COM?
-
Hoe kan ik koppelen aan het actieve exemplaar van een Office-toepassing?
-
Hoe kan ik optionele parameters doorgeven?
-
Hoe kan ik gebeurtenissen vastleggen die door de Office-toepassingen worden weergegeven?
-
Mijn automation-code is te traag. Hoe kan ik dingen versnellen?
-
Wat betekenen deze enorme foutwaarden, zoals -2147352573 of 0x80030002?
-
Wat is een typebibliotheek?
-
Mijn automatiseringscode werkte met Microsoft Excel 95, maar mislukt met Microsoft Excel 97. Hoe komt dat?
-
Waarom blijft de toepassing die ik automatiseer in het geheugen nadat mijn programma is voltooid?
-
Ik weet wat ik wil doen als gebruiker van een Microsoft Office-toepassing, maar hoe doe ik dit programmatisch met behulp van Automation?
-
Kan ik een ingesloten Microsoft Office-toepassing automatiseren?
-
Hoe kan ik toegang tot mijn documenteigenschappen in een Microsoft Office-document?
Vragen en antwoorden
-
Wat is Automation?
Automation (voorheen OLE Automation) is een technologie waarmee u kunt profiteren van de functionaliteit van een bestaand programma en deze kunt opnemen in uw eigen toepassingen. U kunt bijvoorbeeld de mogelijkheden voor spelling- en grammaticacontrole van Microsoft Word in uw toepassing gebruiken zonder dat Microsoft Word zichtbaar is voor uw gebruikers. U kunt zelfs alle hulpmiddelen voor grafieken, afdrukken en gegevensanalyse van Microsoft Excel gebruiken. Deze technologie kan uw ontwikkeling aanzienlijk vereenvoudigen en versnellen. -
Ik ben nieuw bij Automation, waar vind ik goede resources voor meer informatie? Hoofdstuk 24 van David Kruglinski's "Inside Visual C++" (ISBN:1-57231-565- 2) biedt een algemeen overzicht en enkele goede voorbeelden. De Microsoft Knowledge Base is ook een goede bron van informatie.
Als u liever op voorbeeld leert, raadpleegt u het volgende artikel in de Microsoft Knowledge Base:179706 MFC gebruiken om Excel te automatiseren & een nieuwe werkmap maken/opmaken
-
Zijn er verschillende manieren waarop ik Automation kan gebruiken?
Er zijn drie basis manieren waarop u Automation kunt gebruiken: MFC, #import en C/C++:-
Gebruik met MFC de Visual C++ ClassWizard om 'wrapperklassen' te genereren uit de Microsoft Office-typebibliotheken. Deze klassen, evenals andere MFC-klassen, zoals COleVariant, COleSafeArray, COleException, vereenvoudigen de taken van Automation. Deze methode wordt meestal aanbevolen boven de andere, en de meeste Microsoft Knowledge Base-voorbeelden gebruiken MFC.
-
#import, een nieuwe instructie die beschikbaar is geworden met Visual C++ 5.0, maakt VC++ 'slimme aanwijzers' op basis van een opgegeven typebibliotheek. Het is zeer krachtig, maar wordt vaak niet aanbevolen vanwege referentietellingsproblemen die meestal optreden bij gebruik met de Microsoft Office-toepassingen.
-
C/C++ Automation is veel moeilijker, maar soms nodig om overhead met MFC of problemen met #import te voorkomen. In principe werkt u met API's zoals CoCreateInstance() en COM-interfaces zoals IDispatch en IUnknown.
Het is belangrijk te weten dat er enkele kleine verschillen zijn tussen Automation en C++ in vergelijking met gewone C, omdat COM is ontworpen rond de C++-klasse.
-
-
Wat is COM?
Automatisering is gebaseerd op het Component Object Model (COM). COM is een standaardsoftwarearchitectuur op basis van interfaces en ontworpen om code te laten scheiden in op zichzelf staande objecten. U kunt het beschouwen als een uitbreiding van het OOP-paradigma (Object Oriented Programming), maar van toepassing op afzonderlijke toepassingen. Elk object maakt een set interfaces beschikbaar en alle communicatie met een object, zoals initialisatie, meldingen en gegevensoverdracht, vindt plaats via deze interfaces. COM is ook een set services die wordt geleverd door dynamic-link libraries (DLL's) die zijn geïnstalleerd met het besturingssysteem. Automation maakt gebruik van veel van deze services. Een voorbeeld is de Marshalling-service, die de aanroepen van de clienttoepassing verpakt naar de lidfuncties van de interfaces van de servertoepassing en deze met hun argumenten doorgeeft aan de servertoepassing. Het lijkt erop dat de interfaces van de server beschikbaar zijn in de geheugenruimte van de client, wat niet het geval is wanneer de client een .exe wordt uitgevoerd in een eigen procesruimte. Marshalling haalt ook de retourwaarden van de methoden van de server terug over de procesgrenzen en veilig in de handen van de client aan te roepen. Er zijn veel andere services die essentieel zijn voor Automation die worden geleverd door de verschillende COM-bibliotheken. Informatiebronnen hierover zijn "Inside Ole - Second Edition" van Kraig Brockschmidt, ISBN 1-55615-843-2, "Inside COM" van Dale Rogerson - ISBN 1-57231-349-8, en "Automation Programmer's Reference", ISBN 1-57231-584-9. -
Hoe kan ik koppelen aan het actieve exemplaar van een Office-toepassing?
Gebruik de API GetActiveObject(). Automation-servers registreren zichzelf in de ROT (Running Object Table), via de Api RegisterActiveObject(). Automation-clients kunnen toegang krijgen tot het actieve exemplaar met code zoals:// 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();
OPMERKING: als er meerdere exemplaren worden uitgevoerd van de Office-toepassing die u wilt koppelen, kunt u alleen koppelen aan het eerste exemplaar dat is gestart met behulp van de API GetActiveObject().
Theoretisch kunt u de ROT voor elk afzonderlijk exemplaar herhalen, maar de Office-apps registreren zichzelf niet als een ander exemplaar al in de ROT staat, omdat de naam voor zichzelf altijd hetzelfde is (deze kan toch niet worden onderscheiden). Dit betekent dat u geen enkele instantie kunt koppelen, behalve aan het eerste exemplaar. Omdat de Office-apps echter ook hun documenten registreren in de ROT, kunt u met succes koppelen aan andere exemplaren door de ROT te herhalen naar een specifiek document, er een bijlage aan te koppelen en vervolgens het toepassingsobject op te halen. U hoeft dit niet te doen voor PowerPoint, omdat het een toepassing met één exemplaar is. u kunt slechts één exemplaar ervan uitvoeren. -
Hoe kan ik optionele parameters doorgeven?
Sommige methoden hebben optionele parameters. In Visual Basic kunt u deze terloops weglaten wanneer u de methode aanroept. Wanneer u echter aanroept met Visual C++ moet u een speciale VARIANT doorgeven waarvan het veld .vt is VT_ERROR en het veld .scode DISP_E_PARAMNOTFOUND. Dat is:// VARIANT used in place of optional-parameters. VARIANT varOpt; varOpt.vt = VT_ERROR; varOpt.scode = DISP_E_PARAMNOTFOUND;
Dit is echt wat Visual Basic achter de schermen doet.
-
Hoe kan ik gebeurtenissen vastleggen die door de Office-toepassingen worden weergegeven?
In principe implementeert u de gebeurtenisinterface die u wilt vastleggen (de 'sink') en maakt u een adviesverbinding met de toepassing (de 'bron'). Over het algemeen krijgt u voor het instellen van de adviesverbinding de IConnectionPointContainer van de server en roept u FindConnectionPoint() aan met de IID van de gebeurtenisinterface. Hiermee krijgt u een IConnectionPoint-interface en hoeft u alleen Nog Advise() aan te roepen met een exemplaar van uw gebeurtenisinterface. De server roept vervolgens terug via deze interface wanneer deze gebeurtenissen optreden. -
Mijn automation-code is te traag. Hoe kan ik dingen versnellen?
Een veelvoorkomende oorzaak van snelheidsproblemen met Automation is het herhaaldelijk lezen en schrijven van gegevens. Dit is gebruikelijk voor Excel Automation-clients. De meeste mensen zijn zich er echter niet van bewust dat deze gegevens meestal allemaal tegelijk kunnen worden geschreven of gelezen met behulp van SAFEARRAY. Zie het volgende Microsoft Knowledge Base-artikel voor meer informatie en informatieve voorbeelden:179706 Procedure: MFC gebruiken om Excel te automatiseren en een nieuwe werkmap te maken/opmaken Het is ook belangrijk om erop te wijzen dat het gebruik van het klembord soms de prestaties kan verbeteren. U kunt bijvoorbeeld uw gegevens naar het klembord kopiëren en vervolgens automatisering gebruiken om de server te laten plakken. Of omgekeerd; laat de server kopiëren naar het klembord en plak deze in uw toepassing.
-
Wat betekenen deze enorme foutwaarden, zoals -2147352573, of 0x80030002?
Deze waarden worden HRESULTs genoemd en worden gedefinieerd in winerror.h. De getallen zijn zo groot omdat de eerste bit aangeeft of het een foutresultaat is of niet. U kunt het hulpprogramma ErrLook.Exe van Visual C++ gebruiken om deze getallen om te zetten in zinvolle beschrijvingen. Als u programmatisch een beschrijving voor de fouten wilt verkrijgen, kunt u de API FormatMessage() gebruiken.OPMERKING: Als u Visual C++ 6.0 gebruikt en een variabele met deze waarde in het venster foutopsporingscontrole hebt, voegt u er ', hr' (zonder de aanhalingstekens) aan toe zodat Visual C++ deze voor u vertaalt.
-
Wat is een typebibliotheek?
Een typebibliotheek is vergelijkbaar met een C/C++-headerbestand. Het bevat de interfaces, methoden en eigenschappen die een server publiceert. U kunt de typebibliotheek weergeven met de OLE/COM Object Viewer (Oleview.exe) die wordt geleverd bij Visual C++. Hier volgt een lijst met de bestandsnamen van de typebibliotheek voor Microsoft Office 95, 97 en 2000: Office Application | Typebibliotheek ------------------------+---------------- Word 95 en eerdere | wb70en32.tlb Excel 95 en eerdere | xl5en32.olb Powerpoint 95 en eerdere | Powerpoint.tlb Access 95 en eerdere | msaccess.tlb Binder 95 | binder.tlb Schedule+ | sp7en32.olb Project | pj4en32.olb Teammanager | mstmgr1.olb Word 97 | msword8.olb Excel 97 | excel8.olb Powerpoint 97 | msppt8.olb Access 97 | msacc8.olb Binder 97 | msbdr8.olb Grafiek 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
-
Mijn automatiseringscode werkte met Excel 95, maar mislukt met Excel 97. Wat gebeurt er?
Het objectmodel voor Excel heeft een belangrijke wijziging aangebracht van versie 95 in 97. In Excel 95 zijn alle methoden en eigenschappen geïmplementeerd in één implementatie van IDispatch. Dit betekende dat u vaak methoden kon aanroepen die zijn bedoeld voor object X, van object Y. Dit was geen goed ontwerp, dus in Office 97 heeft elk object een eigen afzonderlijke Idispatch-implementatie. Dit betekent dat als u vraagt om een methode of eigenschap van object X van een afzonderlijk object Y, u de fout 0x80020003, -2147352573, 'Lid niet gevonden' krijgt. Om deze fout te voorkomen, moet u ervoor zorgen dat de onderliggende IDispatch-interface van waaruit u aanroept, de semantisch juiste is. -
De toepassing die ik automatiseer, blijft in het geheugen nadat mijn programma is voltooid. Wat gebeurt er?
Waarschijnlijk komt dit omdat u bent vergeten een overgenomen interface vrij te geven en u deze moet opsporen. Hier volgen enkele algemene suggesties en dingen die u moet zoeken:-
Als u #import gebruikt, is de kans groot dat u te maken hebt met een van de referentietellingfouten die eraan zijn gekoppeld. Vaak kunnen de fouten worden omzeild, maar meestal heeft het de voorkeur om een van de andere Automatiseringsmethoden te gebruiken. #import werkt niet goed met de Office-toepassingen, omdat de typebibliotheken en het gebruik ervan redelijk complex zijn. Bovendien zijn dergelijke problemen met het tellen van verwijzingen moeilijk op te sporen, omdat veel van de COM-aanroepen op interfaceniveau zich achter de schermen bevinden bij het gebruik van #import.
-
Controleer of u methoden aanroept, zoals Openen of Nieuw, die een IDispatch * (LPDISPATCH) retourneren en de retourwaarde negeert. Als dat zo is, verlaat u deze geretourneerde interface en moet u uw code wijzigen zodat u deze vrijgeeft wanneer u deze niet meer nodig hebt.
-
Voeg geleidelijk secties van uw code uit totdat het probleem verdwijnt en voeg het vervolgens verstandig terug om te achterhalen waar het probleem begint.
-
Houd er rekening mee dat sommige toepassingen actief blijven als de gebruiker de toepassing heeft 'aangeraakt'. Als dit gebeurt terwijl u automatiseert, blijft de toepassing daarna waarschijnlijk actief. De Office-toepassingen hebben de eigenschap UserControl op het toepassingsobject die u kunt lezen/schrijven om dit gedrag te wijzigen.
-
Sommige toepassingen zullen ook besluiten om actief te blijven als er voldoende 'actie' van de gebruikersinterface is opgetreden. Als u de toepassing wilt afsluiten, roept u de methode Quit() aan op het toepassingsobject. Word wordt afgesloten, ongeacht het aantal verwijzingen wanneer Quit wordt aangeroepen. Dit is geen verwacht COM-gedrag. Excel verbergt zichzelf echter op de juiste manier, maar blijft actief totdat alle openstaande interfaces zijn vrijgegeven. Over het algemeen moet u alle openstaande verwijzingen vrijgeven en alleen Quit() aanroepen als u van plan bent de toepassing af te sluiten.
-
-
Ik weet wat ik als office-toepassingsgebruiker wil doen, maar hoe doe ik dit programmatisch via Automation?
Waar u in geïnteresseerd bent, is welke objecten, methoden en eigenschappen u moet gebruiken. De beste manier om te leren navigeren in de objectmodellen van Word, Excel en Powerpoint, op basis van wat u als gebruiker wilt doen, is door macrorecorder te gebruiken. Kies macro\'Nieuwe macro opnemen' in het menu Extra, voer de taak uit waarin u geïnteresseerd bent en kies vervolgens Macro\'Opname stoppen'. Zodra u klaar bent met opnemen, kiest u Macro\Macro's in het menu Extra, selecteert u de macro die u hebt opgenomen en klikt u vervolgens op Bewerken. Hiermee gaat u naar de gegenereerde VBA-code waarmee de taak wordt uitgevoerd die u hebt opgenomen. Houd er rekening mee dat de opgenomen macro in de meeste gevallen niet de best mogelijke code is, maar het is heel goed voor een snel voorbeeld. -
Kan ik een ingesloten Office-toepassing automatiseren?
Absoluut. De truc is het ophalen van de IDispatch-aanwijzer: deze wordt weergegeven in de Visual C++ Technical Note 39 (TN039). -
Hoe kan ik toegang tot mijn documenteigenschappen in een Office-document?
De documenteigenschappen zijn toegankelijk via Automation of rechtstreeks via IPropertyStorage.