Příklady řešení tisku některých vybraných úloh
V následujícím textu naleznete příklady možných řešení některých vybraných dílčích úloh. Tyto příklady v žádném případě neslouží jako vyčerpávající přehled všech možných řešení všech možných požadavků na tisk. Má sloužit jako jakýsi odrazový můstek začínajícímu uživateli, který se rozhodl nadefinovat si vlastní sestavu. Na uvedených příkladech může nalézt prvotní inspiraci k řešení svých požadavků různými způsoby. Další inspiraci nalezne též v definici tiskových sestav dodávaných dodavatelem (systémových sestav).
Příklady slouží též pro lepší pochopení nabízení a použití datových položek objektů nabízených editorem výrazů.
Nicméně upozorňujeme na to, že definice sestav je věc velmi složitá a s ohledem na tuto skutečnost doporučujeme obrátit se se svými požadavky na servisní konzultanty servisní sítě výrobce.
Na jednotlivých dokladech se nepamatuje jméno uživatele, který doklad vystavil, ale jen odkaz jen jeho interní identifikátor (ID). Podle tohoto identifikátoru lze čerpat další údaje o uživateli z tabulky uživatelů. Tedy mějme formulář dokladu, např. faktury vydané a chceme do něj vytisknout jméno uživatele. ID uživatele, který ji vystavil, je uveden v hlavičce faktury v položce CreateBy_ID.
Řešení 1: Do sestavy vložíme výraz NxGetUserName(MAIN.CreateBy_ID), obecný popis funkce viz kap. Popis některých vybraných funkcí. MAIN je název datasetu, který odpovídá hlavičce dokladu, tedy ze seznamu datových položek objektu vyberete tuto:
Řešení 2: Položka "Vytvořil" je odkazem na objekt, tudíž se rozvíjí do dalších (svých) položek. Mezi nimi je samozřejmě opět položka ID daného uživatele, tedy výraz by mohl mít i podobu NxGetUserName(MAIN.CreateBy_ID.ID). Výsledek by byl stejný, jen by mohl být o něco pomaleji vyhodnocen, jelikož zde již jde o dva dotazy na ID uživatele ("přes dvě tečky" - blíže viz popis Editoru výrazů.)
Řešení 3: Můžeme využít i toho, že jméno daného uživatele je uloženo i v nepersistentní položce DisplayName datového objektu CreatedBy. Pak můžeme na požadované místo tiskové sestavy vložit rovnou tuto položku, tedy v našem příkladu MAIN.CreatedBy_ID. DisplayName. Toto řešení by oproti řešení 1 mohlo být v některých případech o něco pomalejší, jelikož funkce z prvního řešení čerpá údaje z paměti, kde je cacheován seznam uživatelů systému.
Řešení 4: Na podobné úrovni je řešení vložit přímo persistentní položku Name datového objektu CreatedBy, tedy v našem příkladu MAIN.CreatedBy_ID. Name. Toto řešení by v některých případech mohlo být o něco rychlejší než třetí řešení, jelikož nepersistentní položky obvykle nejsou cacheované a vyčíslují, což může být pomalejší než přímé načtení položky z databáze.
Na jednotlivých dokladech se nepamatuje číslo dokladu jako je např. FV-112/2001, ale pouze pořadové číslo v dané řadě, odkazy na danou zdrojovou řadu dokladů (ID dané řady) a období (ID období). Tedy chceme na doklad vytisknout číslo dokladu:
Řešení 1: Do sestavy vložíme výraz NxGetDocumentNumber(MAIN.DocQueue_Code,MAIN.OrdNumber,MAIN.Period_Code), obecný popis funkce viz kap. Popis některých vybraných funkcí. MAIN je název datasetu, který odpovídá hlavičce dokladu. Tedy ze seznamu datových položek objektu pro řadu vyberete tuto: , obdobně pro období. Jedná se o položky, které jsou k dispozici díky definici SQL dotazu z tabulek zdrojových řad a období spojených s tabulkou hlavičky dokladu, což je naznačeno pomlčkou v jejich názvu a jsou k dispozici rovnou v první úrovni stromu položek.
Řešení 2: Položky "Zdrojová řada" a "Období" jsou odkazy na objekt, tudíž se rozvíjí do dalších (svých) položek. Mezi nimi jsou samozřejmě opět položky "Zkratka" řady a období. Tedy výraz by mohl mít i podobu: NxGetDocumentNumber(MAIN.DocQueue_ID.Code,MAIN.OrdNumber,MAIN.Period_ID.Code). Výsledek by byl stejný, jen by mohl být o něco pomaleji vyhodnocen, jelikož zde již jde o dva dotazy na zkratky ("přes dvě tečky" - blíže viz popis Editoru výrazů.)
Řešení 3: Můžeme využít i toho, že číslo dokladu je uloženo i v nepersistentní položce DisplayName datového objektu hlavičky daného dokladu. Pak můžeme na požadované místo tiskové sestavy vložit rovnou tuto položku, tedy v našem příkladu MAIN.ID. DisplayName.
Dále se může vyskytnout potřeba tisknout číslo dokladu, u něhož v momentě definice tiskové sestavy není známo, o jaký doklad se bude konkrétně jednat - může jít o různý businessobject (různou tabulku). Na takovou položku se můžeme odkazovat použitím PDocument_ID.
V případě, že je do reportu vybírána takováto položka s nejednoznačným určením dat a je zadána hned z první úrovně nabízeného datového stromu (editace výrazu), tak je třeba předřadit před datový popis prvku vlastní ID nadřazeného objektu (např. <Vlastní ID.PDocument_ID.DisplayName>), jinak prvek nic nevytiskne.
V hlavičce pokladní příjemky budeme chtít tisknout číslo placeného dokladu. Pak v definici tiskové sestavy použijeme výraz MAIN.ID.PDocument_ID.DisplayName.
Na jednotlivých dokladech se nepamatuje jméno vlastní (naší) firmy další její identifikační údaje, jelikož, jaká je vlastní firma se poznává podle toho, do jaké firmy se uživatel přihlásil při spuštění agendy vyžadující přihlášení do firmy. Údaje o vlastní firmě, jako je její jméno, IČO, DIČ (kromě její adresy) atd. jsou uloženy v tabulce GlobData, ale po přihlášení do firmy se cacheují v paměti a odtud se také čerpají pro tisk. Na dokladech se pouze pamatuje odkaz na adresu vlastní firmy, a to z toho důvodu, že systém ABRA Gen umožňuje zásadní opravy vlastní adresy a je tudíž třeba zajistit, aby si doklad pamatoval, s jakou adresou byl vystaven. Adresa vlastní firmy (a její případné opravy) jsou uloženy v samostatné tabulce adres (Adresses).
Řešení A: Jméno vlastní firmy: do sestavy vložíme výraz NxGetCompanyName. IČO vlastní firmy: do sestavy vložíme výraz NxGetCompanyOrgIdentNumber atd. Další údaje o firmě viz popis sady funkcí NxGetCompany..., které vrací údaje o vlastní firmě (viz kap. Popis některých vybraných funkcí). Jiné řešení se zde nenabízí, jelikož připojovat tabulku GlobData k tabulce dokladů a čerpat údaje přímo z ní by nebylo smysluplné.
Řešení B1: Adresa vlastní firmy: Jak bylo řečeno výše, na dokladu se pamatuje odkaz na adresu vlastní firmy. Položka "Vlastní adresa" je standardně odkaz na objekt, tudíž se rozvíjí do dalších (svých) položek: . Mezi nimi jsou k dispozici položky jako ulice, město atd. Tedy např. pro tisk ulice: do sestavy vložíme položku MAIN.Address_ID.Street, tedy ze seznamu datových položek objektu pro řadu vyberete tuto:. Pro tisk města vložíme položku MAIN.Address_ID.City atd.
Řešení B2: Pro údaje vlastní adresy nejsou k dispozici položky rovnou v první úrovni stromu položek (jednalo by se o položky, které jsou k dispozici díky definici SQL dotazu z tabulky adres spojené s tabulkou hlavičky dokladu, což by bylo naznačeno pomlčkou v jejich názvu). Nicméně existuje možnost nechat si nabízet i tyto: Vysvětlíme např. pro pokladní příjmy: Pomocí nástroje DynSQL si vyhledáme příslušný SQL dotaz pro pokladní příjmy. Do SQL dotazu přidáme výraz, který zajistí připojení tabulky adres, tedy např.:
LEFT JOIN Addresses AD ON AD.ID=A.Address_ID
Ten pro všechny pokladní příjemky podle položky Address_ID dohledá a připojí z tabulky adres ty záznamy, na které se pokladní příjemky odkazují. Dále definujeme odpovídající Alias na odpovídající Business objekt, tedy např. AD...TNxAddress, s prefixem např. Address a popiskou např. Vl.adresa. Po exportu do Repozitoře nám přibudou v první úrovni datových položek objektů položky: Vl.adresa-Ulice(Address_Street):, Vl.adresa-Město(Address_City) atd. Do tiskové sestavy pak lze vybrat přímo tyto položky, tedy v sestavě bude např.: MAIN.Address_Street.
Toto byl pouze učebnicový příklad demonstrující možnosti systému. V praxi by byl samozřejmě nesmysl upravovat všechny SQL dotazy nad doklady, když jsou tytéž položky přítupny byť přes objekt vlastní adresy, viz Řešení B1.
V databázi se na jednotlivých dokladech pamatuje např. částka bez daně celkem, ale již se nepamatují některé jiné součtové položky nutné pro tisk dokladu, např. částka bez daně v základní sazbě DPH. Pokud tedy chceme vědět, jaká je částka celkem bez daně v sazbě 22%, můžeme to řešit následovně (objasníme na příkladu faktury vydané):
Řešení 1: Můžeme využít toho, že Business objekt faktury vydané obsahuje několik nepersistentních položek, do kterých nasčítává některé zásadní údaje z faktury. Mezi nimi je i položka LocalAmountWithoutVATBasic, která obsahuje částku celkem za základ v sazbě 22%. Jak bylo řečeno v kap. Datové položky objektů, nepersistentní položky jsou dostupné přes rozvinutou položku vlastní ID. Tedy položka MAIN.ID.LocalAmountWithoutVATBasic vložená do sestavy vytiskne částku celkem bez daně pro sazbu 22% v měně dokladu.
Řešení 2: Součty za různé položky můžeme řešit pomocí proměnných definovaných v sestavě, do kterých si průběžné součty budeme ukládat. Tedy v našem případě: do inicializačního skriptu sestavy vložíme výraz NxValueCreate('CBEZ22'); který způsobí po spuštění sestavy založení proměnné námi nazvané CBEZ22 (celkem bez daně 22%). Do finalizačního skriptu sestavy vložíme výraz NxValueDestroy('CBEZ22'); jelikož po ukončení sestavy je třeba proměnnou z paměti uvolnit, aby tam zbytečně nezůstávala a neblokovala místo v paměti. V pruhu řádků faktury vložíme do finalizačního skriptu výraz NxValueSet('CBEZ22',NxValueGet('CBEZ22')+If(Rows.VATRate=22, Rows.TAmountWithoutVAT),0); který způsobí, že je-li na řádku sazba 22%, přičte ke stávající hodnotě proměnné CBEZ22 základ bez daně daného řádku pamatovaný v položce Rows.TAmountWithoutVAT, jinak ji ponechá beze změny. Obdobně bychom řešili sazbu 5% a 0% a částky DPH celkem.
Jiná možnost je přidat si pruh připojený k pruhu řádků, sumační výraz si vložit do podmínky tisku tohoto řádku a rozšířit jej tak, aby se podmínka vyhodnotila jako neplatná. Tedy pruh bude sloužit k sumaci hodnot, ale tisknout se nebude. Tedy např. NxValueSet('CBEZ22',NxValueGet('CBEZ22')+If(Rows.VATRate=22, Rows.TAmountWithoutVAT),0) and False. Obecný popis použitých funkcí viz kap. Popis některých vybraných funkcí.
Na závěr stačí připojit další pruh vyhodnocovaný po zpracování všech řádků dokladu (může to být např. patička subdetailu, ve kterém se zpracovávají řádky daného dokladu, podrobněji viz Pruhy v sestavě) a vložit do něj položku pro tisk spočítané částky, tedy v našem případě NxValueGet('CBEZ22').
Toto byl opět pouze učebnicový příklad demonstrující možnosti systému. V praxi by bylo zbytečné definovat počítat součty pomocí proměnných, pokud jsou tyto součty již k dispozici přímo v databázi nebo jako nepersistentní položky daného objektu (viz Řešení 1). Nicméně tento princip můžete využít k libovolnému jinému součtování.
Pokud tvoříte sestavu, kde se odkazujete na položky Business objektů (BO), může být následné sestavení tisku poměrně pomalé. Např. pokud pro tisk čísla dokladu použijete výraz MAIN.ID.Displayname, znamená to, že se natahuje BO a je to pomalé. Pokud nahradíte v takových sestavách MAIN.ID.Displayname za NxGetDocumentNumber(MAIN.DocQueue_Code, MAIN.OrdNumber, MAIN.Period_Code), pak bude vyhodnocení rychlejší.
Podmínkou samozřejmě je, aby se v takových sestavách i pro další položky nepoužívaly další výrazy odvozené od MAIN.ID....
V některých tiskových sestavách je žádoucí, aby kromě běžně se opakujících textů tiskly i text variantně zadaný před vlastním sestavením dané tisk. sestavy. V tom případě lze využít funkce NxTextInputDialog(<Str1>:String, <Str2>:String, <Num3>:Numeric):String. jedná se o funkci pro uživatelské zadání textu s pamětí již vložených hodnot, kde
- <Str1> identifikátor pro ukládání vložených hodnot
- <Str2> nadpis vstupního okna
- <Num3> šířka vstupního okna v bodech
Vrací uživatelem vložený řetězec.
Příkladem mohou být výplatní pásky, kdy mzdová účetní chce dát zaměstnancům na vědomí nějakou skutečnost formou poznámky na výplatní pásce např. "Tento měsíc budou vydávány zálohy pouze do 12:00". Tento text se ale bude v čase měnit (každý měsíc bude chtít sdělit jinou informaci, tudíž není možné daný text vložit do sestavy napevno. Potom v definici tisk. sestavy lze využít funkci NxTextInputDialog. Např.:
NxTextInputDialog('WageSlip','Zadejte text, který se má vytisknout na konci výplatní pásky',300)
V inicializačním skriptu tisk. sestavy je třeba nadefinovat:
- NxValueCreate('AdditionalTXT'); ... { vytvoření proměnné pomocí NxValueCreate()}
- NxValueSet('AdditionalTXT', NxTextInputDialog('WageSlip','Zadejte text, který se má vytisknout na konci výplatní pásky',300)) ... { uložení zadané hodnoty do proměnné pomocí NxValueSet()}
Proměnnou pak lze použít pomocí NxValueGet(). V místě tisk. sestavy, kde chceme zadaný text tisknout, stačí definovat funkci NxValueGet('AdditionalTXT'). Pak, při spuštění tisku dané sestavy se nejdříve zobrazí dialog, kam uživatel vepíše aktuálně požadovaný text:
Zadaný text se pak vytiskne na určené místo v tisk. sestavě. Jednou zadaný text do sady již dříve zadaných textů a ty při příštím vyvolání nabízí v rámci skrytého seznamu.
Na závěr je třeba do finalizačního skriptu nadefinovat:
- NxValueDestroy('AdditionalTXT') ... { zrušení proměnné pomocí NxValueDestroy()}
V některých tiskových sestavách je vhodné, aby před sestavením tisku uživatel zvolil jednu z předem daných voleb, které ovlivní vzhled výsledného výstupu. V tom případě lze využít funkce NxChoiceInputDialog(<Str1>:String, <Str2>:String, <Num3>:Numeric, <Num4>:Numeric):String, která slouží k výběru jedné z předdefinovaných hodnot, které se zobrazí ve skrytém seznamu (combo box). Parametry funkce:
- <Str1> seznam jednotlivých hodnot, tj. obsah skrytého seznamu s ohodnocením jednotlivých voleb: 'Popis hodnoty 1,ocenění hodnoty 1|Popis hodnoty 2,ocenění hodnoty 2|...atd.'
- <Str2> nadpis vstupního okna, tj. text, který se zobrazí jako popis skrytého seznamu
- <Num3> šířka vstupního okna v bodech pro zobrazení dialogu
- <Num4> reprezentace navracené hodnoty. 0 popis hodnoty, 1 ocenění hodnoty
Vrací reprezentaci uživatelem vybrané hodnoty jako řetězec, tj. ohodnocení vybrané volby.
Tisk přihlášky-odhlášky zaměstnance k nemocenskému pojištění v agendě Prac. poměrů, kdy uživatel pouze zvolí, zda chce tisknout přihlášku nebo odhlášku, aniž by bylo nutno mít tisk. sestavy 2.
Potom v definici tisk. sestavy lze využít funkci NxChoiceInputDialog. Tj. v inicializačním skriptu tisk. sestavy nadefinujeme např. : NxValueSet('Action', NxChoiceInputDialog('Přihláška zaměstnance,1|Odhláška zaměstnance,2', 'Vyberte, o jaký druh dokladu se jedná:', 300,1)).
V místě tisk. sestavy, kde se tiskne, zda se jedná o přihlášku, stačí definovat podmínku if(NxValueGet('Action')='1','X',''). Obdobně pro odhlášku.
Pak, při spuštění tisku dané sestavy se nejdříve zobrazí dialog, kde uživatel zvolí jednu z hodnot:
Je-li vybrána přihláška, bude v záhlaví v příslušné položce sestavy zatrženo, že se jedná o přihlášku