Včasné a pozdní vázání ve VBA
O co jde
Tento poněkud zvláštní název vznikl z anglického Early & Late Binding a znamená, jakým způsobem se můžeme připojovat a tím pádem i ovládat jinou aplikaci/objekt z VBA. Bývá často ne moc dobře pochopeno a někdy není úplně jasné, jak co nejlépe vytvořit instanci aplikace, kterou chceme ovládat.
Jediná věc, která ovlivňuje, jestli bude objekt včasně nebo pozdně vázán, je jeho deklarace.
Proměnné, které jsou deklarované jako specifický datový objekt, jsou vždy včasně vázány.
Proměnné, které jsou deklarované pomocí příkazu Object nebo Variant, jsou vždy pozdně vázány.
Předpokládám, že už máte všichni nějakou zkušenost z alespoň s jedním z těchto typů napojení se na objekt a taky možná, že jste do teď ani netušili, že jste vlastně vázali nějaký objekt. Typicky se to používá, pokud chcete vygenerovat dokument ve Wordu nebo odeslat poštu pomocí Outlooku, popř. ovládat jakoukoliv aplikaci, která podporuje OLE a nabízí na odiv svůj objektový model. Koukněte na následující příklady
Dim objConnection As Object
' nezáleží, jak vytváříte objekt. Vždy jde v tomto případě o POZDNÍ vázání,
' protože jste použili příkaz Object a Excel zatím neví, co bude do této
' proměnné nahráno
Set objConnection = New AODB.Connection
Set objConnection = CreateObject("AODB.Connection")
nebo můžete použít tzv. včasné vázání
Dim objConnection As AODB.Connection
' nezáleží, jak vytváříte objekt, vždy jde v tomto případě o VČASNÉ vázání
' protože jste Excelu řekli, že proměnná bude obsahovat datový typ AODB
Set objConnection = New AODB.Connection
Set objConnection = CreateObject("AODB.Connection")
Všimněte si, že pokud použijete včasné vázání na objekt, který není součástí objektového modelu dané aplikace ( Excelu ), musíte nastavit referenci Tools -> References v menu VBE editoru. V tomto případě byste měli zatrhnout referenci na Microsoft ActiveX Data Objects 2.x.
Výhody a nevýhody
Z pohledu jazyka VBA bychom vždy měli používat včasné vázání, které nám poskytuje následující vymoženosti.
- Jasný účel Při použití včasného vázání je VBA známo jaký datový typ chceme používat a to pomáhá při kompilaci kódu. VBA tím může vyhradit paměť na všechny metody a vlastnosti daného objektu, které pak používáme v našem kódu. Při spuštění kódu ( runtime ) vždy, když kompilátor narazí na volanou metodu nebo vlastnost, je pro něj jednodušší vykonat příkaz, který má uložen v paměti. ( To je trošku zjednodušeno. To, co VBA vlastně ukládá, je číselná adresa kódu, který má být vykonán ze známého místa v paměti )
Když použijeme pozdní vázání, VBA nemá jak zjistit, jaký typ objektu později proměnné přiřadíme. Proto nemůže optimalizovat žádnou metodu ani vlastnost v compile módu. Tzn. že pokaždé, když VBA narazí na metodu nebo vlastnost pozdně vázaného objektu, musí se dotázat a rozhodnout, o jaký typ objektu jde, podívat se na název vlastnosti nebo metody a zjistit kde je vlastně v paměti uložen a poté kód na dané adrese v paměti vykonat. Asi chápete, že je tento proces pomalejší než u včasného vázání. - Kontrola typu Pokud použijete pozdní vázání a např. místo ADODB. Connection použijete ADODB.Command, VBA nebude nijak protestovat. Až následně při runtime modu, když se Váš kód bude snažit použít příkaz, který nepatří pod ADODB.Command, vyskočí známá hláška Debug. Ale když použijete včasné vázání, VBA Vás bude okamžitě upozorňovat, že děláte něco špatně.
- IntellSense Při použití včasného vázání budete mít k dispozici tzv. IntellSense ( po napsání tečky vyjede seznam možných vlastností a metod ), protože VBA ví, o jaký datový typ se jedná. Toto samozřejmě dělá radost programátorovi, který má jednodušší a rychlejší cestu k vytváření celé aplikace.
Jak to vypadá v praxi
Ačkoliv to vypadá, že včasné vázání je to nejlepší, co nás mohlo potkat, záhy zjistíte, že tomu tak není a v praxi je obtížně použitelné.
- Když neznáte verzi aplikace, kterou chcete používat ve svém kódu
Nejzásadnější důvod, proč používat právě pozdní vázání. Pokud např. ve svém kódu používáte verzi aplikace, která je jiná, než na cílovém počítači, Váš kód nebude pracovat a obdržíte chybovou hlášku - Can't find project or library - anebo v okně References bude napsáno u dané knihovny - MISSING - .
Pokud chcete podporovat všechny uživatele Vaší aplikace s jakoukoliv verzí objektu, který používáte ve Vašem kódu, musíte použít pozdní vázání. Pokud budete vytvářet novou instanci objektu, použijte příkaz CreateObject který vytvoří instanci daného objektu, tento příkaz je vhodnější než = New ObjectName.
' vytvoří instanci Excelu v nejnovější verzi, která je nainstalovaná na PC
Set objName = CreateObject("Excel.Application")
' vytvoří instanci Excelu 2003
Set objName = CreateObject("Excel.Application.11") - Když chcete použít
V tomto případě musíte použít pozdní vázání, abyste se vyhnuli chybě při kompilaci. Můžete napsat kód, který bude kontrolovat, zda uživatel má danou aplikaci nainstalovanou - viz. tento kód.
Dim ObjectName As Object
On Error Resume Next
Set ObjectName = CreateObject("Excel.Application.10")
On Error GoTo 0
If ObjectName Is Nothing Then
MsgBox "You need Microsoft Excel 2002 to use this function"
Exit Sub
End If
V praxi pak vypadá vývoj kódu pro ovládání jiných aplikací následovně
- v okně References zatrhnete příslušné objekty
- nadeklarujete všechny proměnné na příslušný datový typ
- po kompletním odzkoušení aplikace a její kompilaci nadeklarujete všechny proměnné na typ Object/Variant a zrušíte zatržení referenci.
Také je vhodné, abyste Vy - jako programátor určili, kdy vznikne instance daného objektu a nenechávali vše na VBA.