1497


Interakcje z innymi aplikacjami

W tym rozdziale:

• Uruchamianie innych aplikacji z poziomu Excela

• Wykorzystanie automatyzacji do sterowania innymi aplikacjami

Uruchamianie innych aplikacji z poziomu Excela

Uruchamianie innych aplikacji z poziomu Excela jest bardzo często przydatną operacją. Dzięki niej można na przykład z poziomu Excela uruchomić inną aplikację Microsoft Office lub nawet DOS-owy skrypt wsadowy.

Zastosowanie funkcji Shell języka VBA

Funkcja Shell języka VBA powoduje, że uruchamianie innych programów jest stosun­kowo proste. Poniżej przedstawiono kod procedury StartCalc, która uruchamia program calc.exe, czyli popularny Kalkulator systemu Windows.

Sub StartCalc()

Dim Program As String

Dim TaskID As Double

On Error Resume Next

Program = "calc.exe"

TaskID = Shell(Program, 1)

If Err <> 0 Then

MsgBox "Nie można uruchomić programu " & Program, vbCritical, "Błąd!"

End If

End Sub

Na rysunku 1 zaprezentowano okno aplikacji, która została uruchomiona za pomocą powyższej procedury.

0x01 graphic

Rysunek 1. Uruchamianie aplikacji Kalkulator z poziomu Excela

Funkcja Shell zwraca identyfikator zadania dla aplikacji. Identyfikator ten można następ­nie wykorzystać do uaktywnienia zadania. Drugi argument funkcji Shell określa sposób wyświetlania aplikacji (l oznacza aktywne okno o domyślnym rozmiarze). Informacje o innych wartościach tego argumentu można uzyskać w systemie pomocy.

Jeżeli wykonanie funkcji Shell nie powiedzie się, następuje wygenerowanie błędu. Z tego powodu w powyższej funkcji wykorzystano polecenie On Error, które wyświetla komu­nikat, jeżeli nie może znaleźć pliku wykonywalnego lub jeżeli wystąpi inny błąd.

Kod VBA nie zatrzymuje działania po uruchomieniu aplikacji za pomocą funkcji Shell. Mówiąc inaczej, funkcja Shell uruchamia aplikację w sposób asynchroniczny. Jeżeli za wywołaniem funkcji Shell w procedurze znajdują się dodatkowe instruk­cje, będą one wykonywane równolegle z uruchomionym programem. Jeżeli dowolna instrukcja wymaga interwencji użytkownika (np. wyświetla się okno informacyjne), a aktywna jest inna aplikacja, zaczyna migać pasek tytułu Excela.

Czasami trzeba uruchomić aplikację za pomocą funkcji Shell i zatrzymać kod VBA do czasu jej zamknięcia. Może tak się zdarzyć, jeżeli na przykład uruchomiona aplikacja generuje plik, który jest używany w dalszej części kodu. Chociaż nie można wstrzymać wykonywania kodu, możesz utworzyć pętlę, która monitoruje stan aplikacji. Poniżej pre­zentuję przykład kodu wyświetlającego okno informacyjne w chwili zakończenia dzia­łania aplikacji uruchomionej za pomocą funkcji Shell.

Declare Function OpenProcess Lib "kernel32" _

(ByVal dwDesiredAccess As Long, _

ByVal bInheritHandle As Long, _

ByVal dwProcessId As Long) As Long

Declare Function GetExitCodeProcess Lib "kernel32" _

(ByVal hProcess As Long, _

lpExitCode As Long) As Long

Sub StartCalc2()

Dim TaskID As Long

Dim hProc As Long

Dim lExitCode As Long

Dim ACCESS_TYPE As Integer, STILL_ACTIVE As Integer

Dim Program As String

ACCESS_TYPE = &H400 ' ?Val("&H400")=1024

STILL_ACTIVE = &H103 ' ?Val("&H103")=259

Program = "calc.exe"

On Error Resume Next

' Przekazanie zadania do powłoki

' uruchomienie programu przy użyciu funkcji Shell

TaskID = Shell(Program, 1)

' Pobieranie uchwytu procesu

hProc = OpenProcess(ACCESS_TYPE, False, TaskID)

If Err <> 0 Then

MsgBox "Nie można uruchomić programu " & _

Program, vbCritical, "Błąd!"

Exit Sub

End If

Do 'Pętla

' Sprawdź proces

GetExitCodeProcess hProc, lExitCode

' Zezwól na obsługę zdarzeń

DoEvents

Loop While lExitCode = STILL_ACTIVE

' Zadanie zakończone, wyświetlanie komunikatu

MsgBox Program & " został zamknięty."

End Sub

Funkcja OpenProcess otwiera istniejący proces. Parametry:

dwDesiredAccess - uprawnienia do procesu. Uprawnienia są porównywane z deskryptorami zabezpieczeń nałożonymi na proces. Parametr ten może przyjmować wartość jednej lub wielu flag uprawnień do procesu.

bInheritHandle - jeśli ten parametr ma wartość True, uchwyt może być dziedziczony; w przeciwnym wypadku uchwyt nie może być dziedziczony.

dwProcessId - identyfikator procesu, którego uchwyt ma być otworzony.

Wartość zwracana: jeśli funkcja się powiedzie, zwraca otwarty uchwyt określonego procesu. Jeśli funkcja się nie powiedzie, zwraca wartość NULL (0).

W czasie, kiedy pracuje uruchomiony wcześniej program, procedura wykonuje w pętli Do ... Loop funkcję GetExitCodeProcess, sprawdzając zwracaną wartość (lExitCode). Kiedy program zakończy działanie, zmienna lExitCode przyjmie inną wartość, pętla zakoń­czy działanie i wykonywanie kodu VBA zostanie wznowione.

Skoroszyt z tym przykładem - UruchamianieKalkulatora.xlsm.

Uaktywnianie aplikacji z poziomu Excela.

W poprzednim podrozdziale omówiono sposoby uruchamiania aplikacji. W więk­szości przypadków nie interesuje nas jednak uruchomienie nowej kopii aplikacji, ale uaktywnienie aplikacji, która już została wcześniej uruchomiona.

Wykorzystanie instrukcji AppActivate

W zaprezentowanej poniżej procedurze ActivateCalc wykorzystano instrukcję AppActivate w celu uaktywnienia działającej aplikacji (w tym przypadku jest to Kalkulator systemu Windows). Argumentem instrukcji AppActivate jest tytuł apli­kacji (tekst na pasku tytułu). Jeżeli instrukcja AppActivate wygeneruje błąd, będzie to oznaczało, że Kalkulator nie został wcześniej uruchomiony. W takim przypadku proce­dura go uruchomi.

Sub ActivateCalc()

Dim AppFile As String

Dim CalcTaskID As Double

AppFile = "Calc.exe"

On Error Resume Next

AppActivate "Kalkulator"

If Err <> 0 Then

Err = 0

CalcTaskID = Shell(AppFile, 1)

If Err <> 0 Then MsgBox "Nie można uruchomić Kalkulatora"

End If

End Sub

Skoroszyt z tym przykładem - UruchamianieKalkulatora.xlsm.

Uaktywnianie aplikacji pakietu Microsoft Office

Jeżeli aplikacja należy do pakietu Office, do jej uaktywnienia można użyć metody ActivateMicrosoftApp obiektu Application. Na przykład wykonanie poniższej procedury spowoduje uruchomienie Worda:

Sub StartWord()

Application.ActivateMicrosoftApp xlMicrosoftWord

End Sub

Jeżeli w momencie wykonywania procedury Word był już uruchomiony, nastąpi jego uaktywnienie. W instrukcji wywołania tej metody można także wykorzystać inne stałe:

- xlMicrosoftPowerPoint

- xlMicrosoftMail

- xlMicrosoftAccess

- xlMi1crosoftFoxPro

- xlMicrosoftProject

- xlMicrosoftSchedulePlus (nieco starszy program pakietu Microsoft Office, przeznaczony do zarządzania czasem i zdarzeniami).

Wykorzystanie automatyzacji w programie Excel

W Excelu można napisać makro zarządzające pracą innej aplikacji, na przykhid Worda. Mówiąc ściślej, za pomocą makra w Excelu mozna zarządzać serwerem automatyzacji Worda. W takiej sytuacji Excel jest aplikacją klieneką, natomiast Word serwerem. Mozna też napisać aplikacją sterującą Excelem w Visual Basicu. Proces zarządzania aplikacją przez inną aplikację czasami nazywa się łączeniem i osadzaniem obiektów (ang. Objeet Linking and Embedding - OLE) lub po prostu automatyzacją.

Zalety automatyzacji są niezaprzeczalne. Na przyklad programista, który chce wygene­rować wykres, może po prostu wykorzystać inną aplikację, pobraćz niej obiekty, uzyskać obiekt Chart, a następnie wykorzystywać jego właściwości i metody. Automatyzacja w pewnym sensie zaciera granice pomiędzy aplikacjami. Użytkownik Excela może pra­cować z obiektem Accessa i zupełnie nie zdawać sobie z tego sprawy.

Niektóre aplikacje, takie jak na przykład Excel, mogą działać zarówno jako aplikacja-klient, jak i jako aplikacja-serwer. Inne mogą działać wyłącznie jako aplikacje typu klient lub wyłącznie jako aplikacje typu serwer.

W tym podrozdziale zademonstrowano sposób użycia języka VBA w celu korzystania z obiektów innych aplikacji. W przykładach posługuję się Wordem, ale pojęcia te w rów­nym stopniu dotyczą innych aplikacji udostępniających obiekty do automatyzacji - a takich aplikacji jest coraz więcej.

Działania z obiektami innych aplikacji z wykorzystaniem automatyzacji

Do osadzania w arkuszu Excela obiektu, na przykład dokumentu Worda, służy polecenie Wstaw obiekt, znajdujące się na w grupie opcji Tekst, na karcie Wstawianie. Dodatkowo można utworzyć obiekt i wykonywać z nim działania za pomocą kodu VBA (działania te stanowią sedno mechanizmu automatyzacji). W takim przypadku zazwyczaj mamy pełny dostęp do obiektów. Dla programistów taka technika zwykle jest korzystniejsza od osadzania obiektów w arkuszach. W przypadku osadzania obiektów użytkownik musi znać sposób posługiwania się aplikacją obiektu automatyzacji. Natomiast jeżeli do wyko­nywania działań z obiektem wykorzystamy język VBA, możemy tak zaprogramować obiekt, aby działania z nim sprowadzały się do prostych czynności, na przykład kliknięcia przycisku.

Wczesne i późne wiązanie

Przed wykonaniem działań z obiektem zewnętrznym należy utworzyć jego instancję. Można to zrobić na dwa sposoby: wykorzystując wczesne wiązanie (ang. early binding) lub późne wiązanie (ang. late binding). Termin wiązanie dotyczy dopasowywania utworzonych przez programistę wywołań funkcji do właściwego kodu implementującego funkcje.

Wczesne wiązanie

Aby wykorzystać wczesne wiązanie, należy utworzyć odwołanie do biblioteki obiektów poprzez wybranie polecenia Tools/References w edytorze Visual Basic. Na ekranie wyświetli się okno dialogowe podobne do tego, które zaprezentowano na rysunku 2. Aby utworzyć odwołanie, odszukaj i zaznacz na liście żądaną bibliotekę.

0x01 graphic

Rysunek 2. Dodawanie odwołania do pliku biblioteki obiektów

Po zdefiniowaniu odwołania do biblioteki obiektów można wykorzystać przeglądarkę obiektów (jak pokazano na rysunku 3) do przeglądania nazw obiektów oraz ich metod i właściwości. Aby uruchomić przeglądarkę obiektów, należy wcisnąć F2 w edytorze Visual Basic.

0x01 graphic

Rysunek 3. Za pomocą przeglądarki obiektów można uzyskać informacje o obiektach, do których zdefiniowano odwołania

W przypadku użycia wczesnego wiązania należy zdefiniować odwołanie do konkretnej wersji biblioteki obiektów. Na przykład możesz wprowadzić odwołanie do biblioteki Micro­soft Word 10.0 Object Library (dla Worda 2002), Microsoft Word 11.0 Object Library (dla Worda 2003), Microsoft Word 12.0 Object Library (dla Worda 2007) lub Microsoft Word 14.0 Object Library (dla Worda 2010). Po zdefiniowaniu odwołania w celu utwo­rzenia obiektu powinieneś użyć następującej instrukcji:

Dim WordApp As New Word.Application

Zastosowanie wczesnego wiązania do tworzenia obiektów, polegającego na skonfigu­rowaniu odwołania do biblioteki obiektów zazwyczaj jest wydajniejszym i szybszym rozwiązaniem niż użycie wiązania późnego. Wczesne wiązanie można jednak zastoso­wać tylko wtedy, gdy obiekt jest zapisany w osobnym pliku biblioteki typu lub obiektu. Dodatkowo użytkownicy korzystający z aplikacji muszą zainstalować kopię określonej biblioteki.

Kolejną zaletą wczesnego wiązania jest możliwość wykorzystania stałych zdefiniowa­nych w bibliotece obiektu. Word, podobnie jak Excel, zawiera wiele predefiniowanych stałych, które można wykorzystać w kodzie VBA - ale tylko w przypadku wczesnego wiązania. W przypadku późnego wiązania można jedynie skorzystać z rzeczywistych wartości, a nie stałych.

Kolejną zaletą wczesnego wiązania jest umożliwienie wykorzystania przeglądarki obiek­tów edytora Visual Basic oraz opcji automatycznego wyświetlania listy składowych uła­twiającej dostęp do właściwości i metod (ang. Auto List Members). Mechanizmy te są niedostępne w przypadku wykorzystania późnego wiązania, ponieważ typ obiektu jest znany dopiero w fazie wykonywania programu.

Późne wiązanie

W fazie wykonywania programu wykorzystuje się funkcję CreateObject w celu utwo­rzenia obiektu lub funkcję GetObject w celu uzyskania zapisanego instancji obiektu. Taki obiekt jest deklarowany jako ogólny typ Object, a odwołanie do niego jest określane w fazie wykonywania programu.

Późne wiązanie można wykorzystać nawet wtedy, kiedy nie jest znana wersja aplikacji zainstalowanej w systemie użytkownika. Na przykład wykonanie poniższego kodu spo­woduje utworzenie obiektu typu Word (kod działa dla Worda 97 i wersji późniejszych):

Dim WordApp As Object

Set WordApp = CreateObject("Word.Application")

W przypadku zainstalowania wielu wersji Worda można utworzyć obiekt dla określonej wersji. Na przykład poniższa instrukcja utworzy obiekt Worda 2003:

Set WordApp = CreateObject("Word.Application.11")

Klucz rejestru Windows dla obiektu automatyzacji Worda, a także odwołanie do obiektu Application w języku VBA są takie same: Word.Application. Nie jest to jednak odwołanie do tego samego elementu. Deklaracja obiektu jako As Word.Application lub jako As New Word.Application dotyczy obiektu Application w bibliotece Word. Jednak wywołanie funkcji CreateObjectC ("Word.Application") dotyczy nazwy, pod jaką występuje najwyż­sza wersja Worda w rejestrze Windows. Nie jest to uniwersalna zasada dla wszystkich obiektów automatyzacji, ale obowiązuje dla głównych składników pakietu Office 2010.

Jeżeli użytkownik zastąpi Worda 2003 Wordem 2010, funkcja CreateObject ("Word.Application") dalej będzie działać prawidłowo, choć tym razem będzie odwoływać się do nowej aplikacji. Jeżeli jednak usuniemy Worda 2010, wykonanie funkcji CreateObject ("Word.Application.14"), w której użyto nazwy symbolicznej odpowiadającej Wordowi 2010, nie powiedzie się.

Funkcja CreateObject wykorzystana dla obiektu automatyzacji, na przykład Word.Application lub Excel.Application, zawsze tworzy nowy egzemplarz obiektu automa­tyzacji. Oznacza to, że zawsze zostanie uruchomiona nowa kopia tej części aplikacji, która bierze udział w automatyzacji. Nawet jeżeli dana instancja obiektu automatyzacji już działa, utworzony zostanie jego nowy egzemplarz, a następnie obiekt określonego typu.

Aby wykorzystać bieżący egzemplarz lub uruchomić aplikację i spowodować, aby został załadowany plik, należy skorzystać z funkcji GetObject.

W celu automatyzacji aplikacji pakietu Office zaleca się wykorzystanie wczesnego wiązania i odwołań do najwcześniejszej wersji produktu, która, jak się spodziewamy, jest zainstalowana w systemach klienckich. Jeżeli na przykład chcemy wykorzystać automatyzację dla Worda 2003, Worda 2007 oraz Worda 2010, w celu zachowania zgodności z wszystkimi trzema wersjami powinniśmy wykorzystać bibliotekę Worda 2003. Oczywiście oznacza to, że nie będzie można wykorzystać właściwości dostępnych w nowszych wersjach Worda.

Funkcja GetObject a CreateObject

Obie funkcje VBA, GetObject i CreateObject, zwracają odwołanie do obiektu, ale dzia­łają w inny sposób.

Funkcja CreateObject służy do tworzenia interfejsu do nowego egzemplarza aplikacji. Należy z niej skorzystać, jeżeli aplikacja nie działa. Nawet jeżeli egzemplarz aplikacji został wcześniej uruchomiony, funkcja spowoduje uruchomienie nowego egzemplarza aplikacji. Na przykład poniższa instrukcja spowoduje uruchomienie Excela, a obiekt zwrócony w zmiennej XLApp będzie odwołaniem do utworzonego obiektu Excel.Application:

Set XLApp = CreateObject("Excel.Application")

Funkcję GetObject wykorzystuje się z aplikacją, która już działa, lub w celu uruchomienia aplikacji z jednoczesnym załadowaniem pliku. Na przykład poniższa instrukcja spowo­duje uruchomienie Excela i jednoczesne załadowanie pliku MójPlik.xlsx. Obiekt zwró­cony w zmiennej XLBook będzie odwołaniem do obiektu Workbook (pliku MójPlik.xlsx).

Set XLBook = GetObject("C:\MójPlik.xlsx")

Prosty przykład późnego wiązania

W poniższym przykładzie zademonstrowano sposób utworzenia obiektu Worda za pomocą późnego wiązania. Procedura tworzy obiekt, wyświetla numer wersji, zamyka aplikację Worda, a następnie niszczy obiekt (zwalniając tym samym używany przez niego obszar pamięci):

Sub GetWordVersion()

Dim WordApp As Object

Set WordApp = CreateObject("Word.Application")

' WordApp.Visible = True

MsgBox WordApp.Version

WordApp.Quit

Set WordApp = Nothing

End Sub

Obiekt Worda utworzony w tej procedurze będzie niewidoczny. Aby zobaczyć obiekt w czasie, kiedy są z nim wykonywane działania, należy ustawić jego właściwość Visible na wartość True, tak jak pokazano poniżej:

WordApp.Visible = True

Przykład ten można też zaprogramować przy użyciu wczesnego wiązania. Zanim jednak będzie to możliwe, należy wybrać polecenie Tools/References, aby ustawić odwołania do biblioteki obiektów Worda i wprowadzić następujący kod:

Sub GetWordVersion()

Dim WordApp As New Word.Application

MsgBox WordApp.Version

WordApp.Quit

Set WordApp = Nothing

End Sub



Wyszukiwarka