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