This is UltimateRPA Documentation
Vyhledání elementu v aplikaci

Představení metod pro hledání

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.

import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaFormsTest.exe")

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.

RpaFormsTest.png
Obrázek 1 Aplikace RpaFormsTest

Nalezení jednoho elementu

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")).

SearchElements_RpaFormsTest_inspector.gif
Obrázek 2 Aplikace RpaFormsTest v Inspectoru

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.

SearchElements_inspector_with_expression.png
Obrázek 3 Inspector s vygenerovaným výrazem
import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaFormsTest.exe")
app.find_first(cf.name("ID"))

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).

Vyhledání více elementů

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.

SearchElements_inspector_two_objects.png
Obrázek 4 Inspector s dvěma elementy Attribute
import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaFormsTest.exe")
app.find_all(cf.name("Attribute"), 2)
SearchElements_highlighted_attributes.png
Obrázek 5 Zvýrazněné elementy v debuggovacím módu

Spustíme aplikaci a vidíme, že se nám zeleným rámečkem označily oba elementy se jménem Attribute.

Vyhledávání od jiného elementu GUI

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.

import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaFormsTest.exe")
ref_elem_condition = cf.name("ID")
right_elem_conditon = cf.class_name("Edit")
app.find_first_right_to(ref_elem_condition, right_elem_conditon)
SearchElements_find_right_to.png
Obrázek 6 Nalezený element v pravo od referenčního elementu

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.

Vyhledání od bodu

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.

import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaFormsTest.exe")
ref_elem_condition = cf.name("Attribute")
elem_condition = cf.class_name("Edit")
app.find_from_point(ref_elem_condition, elem_condition, 70, 30)

Spustíme robota a zeleně se nám orámuje editbox u druhého textu Attribute.

SearchElements_find_from_point.png
Obrázek 7 Nalezený element podle polohy od referenčního elementu

Parameter timeout

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.

import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaFormsTest.exe")
app.find_first(cf.name("Quantity"))

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.

SearchElements_traceback.png
Obrázek 8 Chyba při nenalezení elementu

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).

import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaFormsTest.exe")
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.

SearchElements_quantity_found.png
Obrázek 9 Nalezený element Quantity

Pokud vyhledávání selže

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.

try:
app.find_first()
print("Element not found!")

Vyhledavaní v nadřazeném elementu GUI

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ě.

SearchElements_inspector_tree.png
Obrázek 10 Strom v Inspectoru zobrazující závislosti GUI elementů v RpaTableTest

Pro tento příklad použijeme aplikaci nazvanou RpaTableTest. Upravíme tedy cestu na aplikaci ve funkci exec_app na RpaTableTest.exe.

RpaTableTest.png
Obrázek 11 Okno aplikace RpaTableTest

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.

import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaTableTest.exe")
parent_element = app.find_first(cf.list_item().name("3"))
parent_element.find_first(cf.text().name("GoodFactory"))
app.find_first(cf.text().name("GoodFactory"))

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.

SearchElements_group_element.gif
Obrázek 12 Hledání elementu specifikací nadřazeného elementu

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.

Doporučené postupy při vyhledávání

Jednoznačná identifikace

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íce aplikací

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.