V této kapitole si na několika příkladech ukážeme, jak v aplikaci vyhledávat elementy GUI. Tato kapitola předpokládá, že už umíte používat Inspector a víte co je to condition factory.
Nejdříve si připravíme kód pro spuštění aplikace RpaFormsTest. Naimportujeme modul urpa. Funkcí condition_factory si vytvoříme konstantu cf. Definujeme si funkci main, ve které pomocí funkce set_debug_mode spustíme robota v debuggovacím režimu, který nám nalezený element GUI zvýrazní zeleným rámečkem a tak se můžeme přesvědčit, že jsme opravdu našli to, co jsme chtěli. Cesta na aplikaci v argumentu funkce exec_app může být absolutní nebo relativní vůči skriptu.
Cesta k aplikaci "TutorialApps/RpaFormsTest.exe" je relativní od umístění spouštěného skriptu a předpokládá, že skript je uložený v hlavní složce s nástroji UltimateRPA. Pokud je váš skript uložený jinde, nezapomeňte cestu upravit.
Spustíme si aplikaci RpaFormsTest.exe bez robota, abychom si jí mohli prohlédnout a Inspectorem aplikaci prozkoumáme tak, jak jí vidí robot.
Jako první najdeme label ID. Levým tlačítkem myši aktivujeme zaměřovač v Inspectoru, tlačítko myši držíme stisknuté a kurzor přemístíme nad text ID v aplikaci RpaFormsTest. Element GUI se nám orámuje zelenou barvou. Pokud jsme s výběrem spokojeni, pustíme tlačítko myši a v pravé polovině Inspectoru si označíme checkbox Name a v Search function vybereme find_first. V části nazvané Expression se nám vygeneruje příkaz pro hledání. Měl by vypadat takto app.find_first(cf.name("ID"))
.
Pro nalezení jednoho elementu GUI používáme metodu find_first. S jejím použitím už jste se mohli setkat v kapitole První robotizace. Tato metoda vrátí první element GUI, který odpovídá podmínce v jejím parametru condition. O tom, jak vytvářet podmínky, se můžete dočíst v kapitole condition factory. Metoda nám vrátí objekt třídy AppElement, se kterým můžeme provádět uživatelské interakce nebo se zeptat na jeho vlastnosti. O tom se dozvíme více v další kapitole. Pro vyhledání nám teď stačí pouze zkopírovat výraz z Inspectoru do kódu.
Spustíme robota pomocí klávesové zkratky (ALT + F9) nebo v horním menu PyScripteru vybereme volbu Run a potom External Run. Debuggovací režim nám zeleným rámečkem označí nalezený element ID. Metoda find_first najde vždy první element GUI ve stromě objektů, který odpovídá zadané podmínce (condition).
V některých případech, ale potřebujeme pro danou podmínku (condition) najít všechny elementy GUI najednou. V té chvíli použijeme metodu find_all. Ta nám vždy vrátí python seznam všech nalezených elementů GUI, které odpovídají podmínce. Pokud žádný element GUI metoda nenajde, vrátí prázdný seznam. Stejně jako v případě find_first je prvním argumentem metody podmínka (condition), ve které definujeme, podle jakých vlastností chceme elementy GUI najít. Tato metoda má navíc druhý nepovinný argument elements, který je ve výchozím nastavení rovný nule a říká, kolik minimálně elementů GUI musí robot najít. V našem testovacím případě zkusíme najít dvakrát text Attribute v aplikaci RpaFormsTest. Použijeme Inspector a zaměřovač přeneseme na libovolný text Attribute. Zaškrtneme checkbox Name a v levé části Inspectoru pod polem pro vyhledávání vidíme, že v aplikaci existují dva elementy, které mají Name rovno hodnotě Attribute. V Search function vybereme find_all a náš vygenerovaný příkaz by měl vypadat takto app.find_all(cf.name("Attribute"))
. Ten si zkopírujeme a v našem skriptu s ním nahradíme předchozí hledání. Protože aplikace obsahuje tento element dvakrát, nastavíme druhý argument funkce na integer 2, aby nám robot vždy vyhledal všechny texty Attribute, které mají v aplikaci být.
Spustíme aplikaci a vidíme, že se nám zeleným rámečkem označily oba elementy se jménem Attribute.
Někdy se dostaneme do situace, že prvek v aplikaci nejsme schopni jednoznačně najít sám o sobě. V těchto případech si můžeme pomoc jiným referenčním elementem, který se nachází poblíž prvku, který chceme najít. V příkladu, který si ukážeme, budeme chtít v aplikaci RpaFormsTest najít editbox vedle textu ID. Použijeme k tomu metodu find_first_right_to. Jako referenční objekt si vybereme text ID a od něj napravo budeme hledat editbox. Pro tuto metodu už Inspector nevygeneruje celý výraz, ale pořád si můžeme pomoc tím, že si v něm připravíme condition. První condition je pro referenční objekt. Zaměřovačem v Inspector najedeme na text ID a uvolníme tlačítko myši. Vybereme checkbox Name a jako Search function zvolíme (none). Vygeneruje se nám následující kus kódu cf.name("ID")
. Ten si zkopírujeme a v našem skriptu si ho uložíme do proměnné ref_elem_condition. Pak si vytvoříme condition pro objekt, který chceme najít. Zaměřovač přesuneme na editbox napravo od textu ID. V menu zaškrtneme checkbox Class name a ponecháme (none) v Search function. Vygeneruje se nám následující kus kódu cf.class_name("Edit")
, který si uložíme do proměnné right_elem_condition. Pak na objekt app zavoláme metodu find_first_right_to s prvním parametrem ref_elem_condition a druhým right_elem_condition.
Spustíme skript, a protože máme aktivní debug mode, uvidíme zelený rámeček kolem editboxu.
Stejným způsobem používáme metody find_first_down_to, find_first_left_to a find_first_up_to.
V některých případech si nevystačíme ani s předchozím řešením a tak pak musí nastoupit metoda find_from_point. Ta také používá k vyhledávání referenční element GUI. Od jeho levého vrchního rohu hledáme pomocí souřadnic x a y požadovaný element GUI. Pomocí této metody si najdeme editbox u druhého Attribute. První text Attribute nám bude sloužit jako referenční element GUI. Použijeme Inspector, abychom si vytvořili condition pro referenční element GUI, která bude vypadat takto cf.name("Attribute")
. Tu si zkopíruje do skriptu a uložíme do proměnné ref_elem_condition. Pro element GUI, který chceme najít, vytvoříme condition opět pomocí Inspectoru. Přetáhneme zaměřovač na editbox u druhého textu Attribute a zaškrtneme checkbox Class name, což nám vygeneruje kód cf.class_name("Edit")
, který si v našem skriptu vložíme do proměnné elem_condition. Nakonec nad objektem app zavoláme metodu find_from_point s prvním parametrem ref_elem_condition, druhým elem_condition. Třetí a čtvrtý parametr představují souřadnice x, y v pixelech od levého vrchního rohu referenčního elementu GUI. V našem případě se dají použít například hodnoty 70 a 30.
Spustíme robota a zeleně se nám orámuje editbox u druhého textu Attribute.
Všechny metody pro vyhledávání elementu GUI mají nepovinný parametr timeout. Ten udává, jak dlouho může robot objekt vyhledávat v ms. Ve výchozím nastavení robota je to pět sekund (5000 ms). To ale v některých případech nestačí. Možná už jste si při používání aplikace RpaFormsTest všimli, že pokud jí spustíme tak chvilku trvá, než se nám načte poslední pole formuláře pojmenované Quantity. Teď se pokusíme tento element vyhledat hned po startu aplikace. Použijeme proto níže uvedený kód.
V tomto případě se nám spustí aplikace a začne se vyhledávat objekt, který ještě není načtený. To bude trvat 5 s a potom robot skončí chybou ElementNotFoundError.
Tento problém můžeme jednoduše opravit tím, že zvedneme timeout, například na 10 sekund (10000 ms). Upravíme tedy poslední řádek předchozího kódu na app.find_first(cf.name("Quantity"), 10000)
.
Teď když aplikaci spustíme a chvilku počkáme, objeví se nám pole Quantity a hned na to se orámuje zelenou barvou. V další kapitole si ukážeme jednoduchý příklad, co můžeme dělat, pokud očekáváme situaci, že bychom nějaký element nemuseli najít a robot by nám skončil chybou.
Pokud robot nenajde žádný objekt, který by odpovídal zadaným parametrům, vyhodí chybu ElementNotFoundError. Chybu může zachytit v bloku try a except a zpracovat jí, aniž by došlo k ukončení skriptu.
Všechny výše uvedené postupy ukazují případ, kdy vyhledáváme element GUI nebo elementy GUI v celé aplikaci. UltimateRPA ale umožňuje element GUI vyhledat jen v části aplikace a to v nadřazeném elementu GUI. Jak jsou na sobě elementy GUI závislé, můžeme vidět v levé části aplikace Inspector, v tak zvaném stromě.
Pro tento příklad použijeme aplikaci nazvanou RpaTableTest. Upravíme tedy cestu na aplikaci ve funkci exec_app na RpaTableTest.exe
.
Aplikaci si teď bez pomoci robota spustíme a prohlédneme si jí v Inspectoru. Zameřovač Inspectoru přeneseme na libovolné místo aplikace. To nám zpřístupní strom elementů GUI v levé části. To co ve stromě uvidíte, se může lišit podle toho, jaký element GUI jste v aplikaci vybrali, ale v každém případě byste měli vidět element RpaTableTest[Window] a pod ním element GUI List, který představuje tabulku v aplikaci. Pokud si rozbalíme i tento element GUI najdeme elementy 1[ListItem] až 22[ListItem] ty představují řádky tabulky. My si vybereme řádek číslo 3 a vytvoříme si pro něj výraz s metodou find_first, který bude vypadat takto app.find_first(cf.list_item().name("3"))
. Výraz si zkopírujeme do kódu a uložíme do proměnné parent_element. Takto najdeme náš nadřazený element GUI. V něm si teď zkusíme najít text GoodFactory. Najeďte zaměřovačem Inspectoru na libovolný text GoodFactory. V pravé části zaškrtneme name a Inspector nám vygeneruje tento výraz app.find_first(cf.text().name("GoodFactory"))
. Ten zkopírujeme a vložíme ho do našeho kódu pod poslední řádek a potom ho vložíme do kódu ještě jednou. Hned si vysvětlíme proč, ale nejdřív ještě v prvním řádku nahradíme app objektem parent_element, takže řádek bude vypadat takto parent_element.find_first(cf.text().name("GoodFactory"))
. V tomto řádku kódu vyhledáváme text GoodFactory pouze v rámci třetího řádku tabulky, zatímco ve výrazu pod ním, vyhledáme první text GoodFactory v celé aplikaci.
Když robota spustíme, nejdříve se nám zelenou barvou orámuje třetí řádek tabulky, potom text GoodFactory na třetím řádku a nakonec GoodFactory v řádku prvním.
Všechny metody, které jsme si zatím v tomto návodu představili, můžeme používat i pro vyhledávání v nadřazeném elementu GUI.
Je třeba vždy ověřit, že při opakovaném hledání opravdu nacházíme element GUI, který jsme najít chtěli. Tomu musíme přizpůsobit metodu, kterou element GUI vyhledáváme a condition, které má nalezený objekt odpovídat.
Všechny metody, které slouží k vyhledání elementu GUI, prohledávají strom pouze pro vybranou aplikaci, takže takto není možné najít element GUI jiné aplikace. Některé aplikace při svém běhu spouští jiné aplikace, které mají vlastní proces. Tyto aplikace je potřeba nejprve identifikovat a až potom v nich začít vyhledávat elementy GUI. O tom, jak pracovat s více aplikacemi, si můžete přečíst v kapitole.