C# týden Slevový týden - Březen
Využij náš slevový týden a získej až 30 % bodů navíc zdarma! Zároveň také probíhá C# týden se slevou na e-learning až 80 %
Hledáme fulltime programátora do ITnetwork týmu -100% homeoffice, 100% časově flexibilní #bezdeadlinu Mám zájem!

7. diel - Google Apps Script - Získanie externých dát - Kurzy ČNB III

V minulej lekcii, Google Apps Script - Získanie externých dát - Kurzy ČNB II , sme získali dáta zo servera ČNB ako textový reťazec. Budeme pokračovať jeho spracovaním a uložením do tabuľky.

Spracovanie kurzového lístka

Dáta z ČNB v textovom tvare máme, skúsime si napísať funkciu, ktorá je rozporcujeme do tvaru vhodného na uloženie do tabuľky. Môže vyzerať napríklad takto:

function porcuj_data(kurzy, datum) {
  var radky = String(kurzy).split('\n'); // rozdělí celý text podle znaku pro nový řádek
  var prvni_radek = String(radky.shift()); // z pole odeber první řádek a pro jistotu ho převeď na text
  var dilky = prvni_radek.split(' '); // rozděl podle mezery, jako první část by mělo být datum kurz. lístku
  if(dilky[0] != datum){ // začátek kurzovního lístku se neshoduje s datem, které potřebujeme
    return false; // funkce nevrátí data, ale hodnotu false
  }
  var radek;
  var arr_vyst = []; // pole na výstupní data
  for(var i = 0;i < radky.length; i++){ // cyklus přes všechny zbývající řádky (první řádek už v poli není)
    radek = String(radky[i]).split('|'); // rozděl řádek na dílky podle znaku |
    if(radek.length == 5){ // kontrola, jestli řádek obsahuje správný počet položek
      arr_vyst.push(radek) // přidej řádek do pole
    }
  }
  return arr_vyst;
}

Väčšina kódu je asi jasná už z komentárov. Najprv sa zbavíme prvého riadku a skontrolujeme, či je na ňom správny dátum. Ak nie, funkcia končí a vráti false. Inak prejdeme zostávajúce riadky, rozdelíme každý z nich podľa znaku '|' a postupne ich pridáme do výstupného poľa, ktoré funkcie vráti.

Kontrola, či je počet dielikov päť, je z dôvodu, že na konci vráteného texte je prázdny riadok, ktorý po rozdelení bude obsahovať len jeden dielik a havarovalo by nám vloženie dát do tabuľky. Podobne by sme mohli napríklad strážiť dĺžku riadku a riadok s nulovou dĺžkou preskočiť.

Zápis kurzov na list tabuľky

Na samotný zápis ani nebudeme samostatnú funkciu písať. Napíšeme si rovno funkciu, ktorá vykoná celú operáciu načítanie a uloženie naraz a bude neskôr volaná časovým spúšťačom:

function zpracuj_kurzy() {
  var dnes = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'dd.MM.yyyy'); // dnešní datum v českém tvaru DD.MM.RRRR

  var sheet = zaloz_list(dnes); // založ list, nebo vrať existující
  sheet.clear(); // smaž obsah i formátování

  var kurzy_txt = nacti_data_z_cnb(kurzy_url, dnes); // získej kurzy jako text
  var kurzy = porcuj_data(kurzy_txt, dnes); // rozděl a vrať ve formátu pro vložení do tabulky

  if(kurzy === false) { // na začátku dat není datum dnes
    var range = sheet.getRange(1,1); // vyber buňku A1
    range.setValue('Kurzy nenalezeny'); // zapiš do ní text
  }else{
    var range = sheet.getRange(1,1, kurzy.length, 5); // vyber oblast pro data
    range.setValues(kurzy); // vlož data
    nastav_vzhled(sheet); // upraví vzhled listu
    smaz_prazne_bunky(sheet); // smaž prázdné buňky v tabulce
  }
}

Z komentárov by snáď mala byť funkčnosť jasná, pridáme len niekoľko poznámok.

Vidíme prvé použitie knižnice Utilities, ktorá nám z javascriptového objektu Date vyrobí reťazec v tvare 'DD.MM.RRRR'.

Metóda sheet.clear() vymaže ako dáta, tak aj prípadné formátovanie buniek, veľkosť písma, orámovanie, podfarbenie atď.

Možnosti mazanie sú širšie. Možno mazať samostatne dáta a zachovať formátovanie metódou clearContents(), zmazať formátovanie a ponechať dáta pomocou clearFormats(), alebo pomocou clearNotes() zmazať poznámky.

Ak funkcia porcuj_data() vráti false, zapíšeme túto informáciu na list do bunky A1. V prípade, že sú dáta načítané správne, vložíme ich do tabuľky príkazom range.setValues(kurzy).

Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!

Pred vlastným vložením dát je potrebné vybrať oblasť (range), ktorá musí počtom riadkov a stĺpcov zodpovedať množstvu dát. Akonáhle veľkosť oblasti a dát nesúhlasí, vkladanie dát skončí chybou.

Vidíme, že vo funkcii sa výber oblasti vykonáva takto:

var range = sheet.getRange(1, 1, kurzy.length, 5);

čiže počet riadkov určíme z dĺžky poľa kurzy, ale počet stĺpcov máme natvrdo zadaný. V prípade, že by ČNB do kurzového lístka napríklad pridala ďalší stĺpec, skript by nám prestal fungovať.

Podobne, ak by sa v kurzovom lístku vyskytla chyba a na niektorom riadku boli len 4 stĺpce, vkladanie by havarovalo, pretože počet stĺpcov máme nastavený na 5.

Ešte si ukážeme funkcie nastav_vzhled() a smaz_prazne_bunky(), o ktorých sme zatiaľ nehovorili a ktoré sa volajú po vložení dát.

Nastav_vzhled ()

Po funkciu nastav_vzhled() budeme chcieť zvýrazniť prvý riadok, nastaviť šírku stĺpcov a pár ďalších drobností. Možnosti formátovania sú samozrejme ďaleko väčšie. V podstate čokoľvek, čo sa dá v tabuľke nastaviť ručne, je možné nastaviť aj pomocou skriptu. Naše funkcie by mohla vyzerať napríklad takto:

function nastav_vzhled(sheet) {
  sheet.autoResizeColumns(1, 5); // přizpůsobí šířku sloupců A - E aktuálnímu obsahu
  sheet.setFrozenRows(1); // první řádek zůstane na místě při rolování tabulkou
  var range = sheet.getRange(1, 1, 1, 5); // vyber oblast hlavičky
  range.setBackground('#cccccc'); // nastav hlavičce světle šedé pozadí
  range.setFontWeight("bold"); // nastav hlavičce tučné písmo
}

Funkčnosť je asi jasná z komentárov, prípadne si funkciu upravte a vyskúšajte ďalšie možnosti formátovania.

Smaz_prazne_bunky ()

A ešte si ukážeme funkciu smaz_prazne_bunky().

Každý novozaložený list tabuľky má stĺpce A - Z a 1000 riadkov. Ďalšie stĺpce aj riadky je samozrejme možné celkom ľubovoľne pridávať. Limitovaní sme iba celkovým počtom buniek tabuľky, ktorý je momentálne 5 miliónov.

Do tohto limitu sa samozrejme naše skladovanie kurzov bez problémov vojde, ale ak budete uvažovať o väčšiu aplikácii v Google Suite, ktorá bude pre ukladanie dát využívať tabuľky, je dobré o limite vedieť.

S tým súvisí aj to, čo by mala robiť naše funkcie. Ak vieme, že na liste viac dát jednoducho nebude, môžeme nevyužité stĺpce a riadky vymazať. Len musíme dať pozor, aby sme nemazali i miesta, kde máme dáta. Funkcia môže vyzerať napríklad takto:

function smaz_prazne_bunky(sheet) {
  var data_range = sheet.getDataRange(); // vyber oblast dat
  var posl_radek = data_range.getLastRow(); // číslo posledního řádku
  var posl_sloupec = data_range.getLastColumn(); // číslo posledního sloupce
  var smaz_radku = sheet.getMaxRows() - posl_radek - 1; // kolik řádků smazat
  var smaz_sloupcu = sheet.getMaxColumns() - posl_sloupec - 1; // kolik sloupců smazat
  if(smaz_radku > 0){ // je co mazat?
    sheet.deleteRows(posl_radek + 1, smaz_radku);
  }
  if(smaz_sloupcu > 0){ // je co mazat?
    sheet.deleteColumns(posl_sloupec + 1, smaz_sloupcu);
  }
}

Aby sme neodstránili žiadne dáta nám pomôže zabezpečiť metóda sheet.getDataRange(). Tá vyberie kompletné oblasť obsahujúce dáta. Nezáleží na tom, či sú v dátach prázdne riadky alebo stĺpce, táto metóda vždy vráti oblasť, v ktorej sú všetky bunky obsahujúce nejakú hodnotu.

A pozor, ľavý horný roh oblasti vždy začína bunkou A1, aj keby bola prvá dáta napríklad až v stĺpci F.

Potom využijeme metódy sheet.getMaxRows() a sheet.getMaxColumns(), ktoré vracia celkový počet riadkov a stĺpcov na liste a spočítame si koľko stĺpcov a riadkov je potrebné zmazať. Počty o jeden znížime, takže vpravo by nám mal zostať jeden voľný stĺpec a dole jeden voľný riadok.

Podmienky testujúci počet riadkov a stĺpcov na zmazanie potrebujeme pre prípady, keď funkciu pre daný list zavoláme opakovane. Prvé volanie riadky a stĺpce zmaže a pri druhom volaní by sa skript pokúšal odstrániť 0 riadkov a 0 stĺpcov a havaroval by.

No a máme hotovo. Skúste si funkciu zpracuj_kurzy() niekoľkokrát spustiť a v tabuľke sa presvedčte, či sa kurzy správne ukladajú. Môžete list s dnešným dátumom zmazať a funkciu znovu spustiť. Ak je všetko v poriadku, mal by sa list znovu vytvoriť a naplniť dátami.

Časový spúšťač

Na záver založíme časový spúšťač, ktorý bude funkciu zpracuj_kurzy() spúšťať každý deň, povedzme o 16:00. Z menu vyberieme voľbu Upraviť -> Spúšťače aktuálneho projektu a vpravo dole klikneme na tlačidlo Pridať spúšťač.

Postup sme už prebrali v lekcii o spúšťačoch.

V paneli nastavíme parametre podľa nasledujúceho obrázku a vytvoríme spúšťač:

Vytvorenie spúšťače v Google Apps Script

Samozrejme, že pre otestovanie spúšťače nie je potrebné čakať do druhého dňa. Jednoducho si vytvorte spúšťač, ktorý pobeží každú minútu, a po otestovaní či všetko funguje mu nastavte interval jedenkrát denne.

Páči sa vám Apps Script a tento seriál?
A dočítali ste až do konca?
Potom nezabudnite na hodnotenie ;-)

A na záver malý domácu úlohu. Tipnite si, čo sa zapíše do tabuľky cez víkend, kedy sa kurzy nevyhlasujú, a napíšte to do komentárov.


 

 

Článok pre vás napísal Jan Hora
Avatar
Ako sa ti páči článok?
Ešte nikto nehodnotil, buď prvý!
Autor se poslední 4 roky věnuje programování pro Google Suite.
Predchádzajúci článok
Google Apps Script - Získanie externých dát - Kurzy ČNB II
Všetky články v sekcii
Google API
Aktivity (1)

 

 

Komentáre

Avatar
Erik Šťastný:19.9.2019 14:20

Ty jo to je dost hustý, uvažuju, že ušetřím 50 korun měsíčně za hosting a přepíšu si své scriptíky co něco takového tvoří do téhle Google srandy :)

 
Odpovedať
19.9.2019 14:20
Avatar
Jan Hora
Redaktor
Avatar
Jan Hora:20.9.2019 8:41

Určitě doporučuju :-) Dá se s tím dělat milion věcí. A nemusíš pak řešit jak nějaká data prohlížet když jsou v tabulce. Můžeš si je filtrovat, sdílet, exportovat do PDF, dělat grafy. A všechno můžeš dělat podle potřeby ručně nebo skriptem. Prostě krása :-D

 
Odpovedať
20.9.2019 8:41
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!
Avatar
Tomáš Vojta:23. marca 20:35

Díky za super návod, jen jestli bys upravil chybičku v této trojlekci, oproti tvému kódu máš tady v článcích jinak napsané funkce zpracuj_kurzy(); a zaloz_list(); když jedu krok po kroku z článku tak to nefunguje, ale pak z toho tvého https://script.google.com/…WwWeRKC/edit?… to vše jede jak má :). Pak jenom kdybys připsal že když to někdo zkouší o víkendu tak to bude házet chybu ve funkci porcuj_data() na řádku if(dilky[0] != datum){ protože o víkendu je jiný datum než co vrací ČNB (ta vrací jen ten pátek) tak to pak nic nepíše do Spreadsheetu. Tak díky a budu se těšit kdyžtak na další návody.

 
Odpovedať
23. marca 20:35
Avatar
Jan Hora
Redaktor
Avatar
Jan Hora:24. marca 8:35

Ahoj,
zkusím na to mrknout. Ta chyba s víkendem je tam víceméně schválně. Jsi první kdo se kvůli ní ozval :-).
Jinak na itnetwork je těch článků celkem 7. Pak jsem je zveřejnil ještě na medium.com pod hlavičkou AppSatori se kterýmí externě spolupracuju https://medium.com/@hora.jan tam jich je celkem 11, prvních 7 stejných jako jsou tady na itnetwork. A nakonec se postupně zvěřejňují na stránkách AppSatori https://www.appsatori.eu/blog tam jsou zatím 3. Postupně cca po týdnu tam najede těch 11 a pak budou přibývat další. Na medium a itnetwork už nic nového nebude.
Kdybys chtěl s něčím poradit, tak se klidně ozvi na hora.jan@gmail.com nebo na honza@appsatori.eu.
Ahoj, Honza

 
Odpovedať
24. marca 8:35
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zobrazené 4 správy z 4.