Rubriky
Užitečnosti

Nečekejte, prohlížejte si videa, ještě než se stáhnou

Možná už se vám stalo, že jste si chtěli stáhnout nějaké (samozřejmě naprosto legální) dlouhé video z internetu, třeba z UložTo či podobné služby, a chcete se na něj co nejdříve podívat, nečekat třeba 2 hodiny, než se stáhne.

Jenže Chrome stahovaný soubor ukládá při stahování přejmenovaný s koncovkou CRDOWNLOAD – nejspíše proto, že by spuštění nějakého nekompletního spustitelného souboru mohlo při troše smůli přivodit systému problém (pád systému, poničení dat atd.). Takže už to není soubor .MP4, .AVI atp. a nejde tak spustit.

Ale všechny dnes používané formáty videí počítají s tím, že se donačítají do paměti postupně, ostatně to znáte určitě i třeba z YouTube, kde se také pustí video okamžitě a nečeká se, až se stáhne celé.

Takže stačí, když prostě poklepete normálně na ten .CRDOWNLOAD soubor, neleknete se hlášky, že k tomuto formátu není přiřazena žádná aplikace, a prostě k ní přiřadíte váš oblíbený přehravač videí. A můžete rovnou sledovat, zatímco se bude video donačítat (ani přehravače s tím problém zřejmě nemají, minimálně ty co používám já, třeba VLC).

Rubriky
Užitečnosti

Jak na uživatelské funkce v Google Sheets (příklad funkce encodeURI)

Už jsem tu psal o vlastních funkcích/vzorcích pro MS Excel, které se od standardních VBA maker (subrutin) liší použitím Function namísto Sub a tím, že návratovou hodnotou je automaticky proměnná uvntiř této funkce, která se jmenuje stejně jako název funkce.

Uživatelské vzorce v Google Sheets se od ostatních funkcí neliší vlastně vůbec v ničem, jsou to prostě normální Google Apps Script (v podstatě Javascript) funkce a návratová hodnota se prostě řeší standardním returnem. Snadno jim lze také vytvořit nápovědu pomocí standardního JSDoc.

Bohužel většina funkcí, které někdo vytvářel a někde zveřejnil není psána správně, typickým problémem je kromě absence nápovědy také to, že nepočítají, že by někdo danou funkci použil na nějaké pole prvků a že by návratovou hodnotou také mohlo být pole prvků.

Vše ukážu na jednoduchém příkladu standardní Javascript funkce encodeURI, když byste ji chtěli použít ve vzroci v Google Sheets. Jděte do Nástroje / Editor skriptů a vložte:

/**
 * Encodes special characters, except: , / ? : @ & = + $ # (Use encodeURIComponent() to encode these characters)
 * http://www.w3schools.com/jsref/jsref_encodeuri.asp
 *
 * @param {string|Array} input The text or range of cells to be encoded.
 * @return Encoded input.
 * @customfunction
 */
function ENCODEURI(input) {
 if (input.map) { // Test whether input is an array.
 return input.map(ENCODEURI); // Recurse over array if so.
 } else {
 return encodeURI(input.toString() );
 }
}
  • Na začátku je JSDoc dokumentace, která se pak objeví v bublině, když budete funkci používat. Prvních 40 znaků je vidět už v přehledu funkcí. Nepovinná, ale velmi doporučuji
  • @param vysvětluje, jaké parametry se očekávají na vstupu. V tomto případě jeden parametr input, který může být buď string a nebo Array. Také je vidět v nápovědě
  • v @return si můžete poznačit, co očekáváte na výstupu, ale nikde to vidět není
  • @customfunction říká Google Sheets, že se jedná o uživatelskou funkci a že ji má nabízet mezi funkcemi.
  • Následuje samotná funkce v Google Apps Script / Javascriptu. Není povinné, aby byla psaná velkými písmeny, jen jsou tak psané všechny build-in funkce, tak je fajn to ctít. Tady ve script editoru jsou funkce case sensitive, v Google Sheets nikoliv, takže tam pak klidně můžete použít =encodeURI(string) jako používáte někde na webu.
  • Pak je zde jednoduchý rekurzivní hack, který využije Javascript funkci map, která zavolá vybranou funkci na každý prvek pole – v tomto případě tedy rekurzivně zavolá sebe sama.
  • A když se o pole nejedná, tak funkce převede hodnotu na string, převede jí přes Javascript funkci encodeURI a vrátí jí zpět do Google Sheets.
  • Pozor, kdybych chtěl pojmenovat funkci malými písmeny, tedy encodeURI, shodně jako je ta Javascript funkce, kterou zde volám, tak místo ní zavolá opět sebe sama a funkce se zacyklí.

Výsledek vidíte na obrázku. Všimněte si, že jsem vzorec napsal opět jen do jedné buňky, a to ve formátu B1:B, takže se propíše na všechny řádky.

vlastni-funkce

Rubriky
Užitečnosti

ARRAYFORMULA – důvod, proč si zamilujete Google Sheets

Mám moc rád MS Excel a jsem přesvědčen, že neexistuje lepší tabulkový kalkulátor. Ale přesto čím dál častěji používám Google Sheets a to ze dvou důvodů – snadné (a bezplatné) sdílení tabulek a funkce ARRAYFORMULA.

Ona to vlastně není až tak úplně funkce, je to jen jakýsi konstrukt, který říká, že daný vzorec se týká nějakého pole buněk, nikoliv jedné. Ano, i MS Excel má pole vzorců, jenže je zde podstatný rozdíl – u MS Excelu musíte předem označit všechny buňky, které se mají vyplnit výsledkem, u Google Sheets napíšete vzorec jen do jedné a on vyplní všechny ostatní.

Skvěle se to totiž hodí i pro řešení problému, který jsem zmínil včera, tedy když potřebujete do nějakého sloupce tabulky dát nějaké hodnoty či výpočet a chcete, aby se to automaticky počítalo u všech řádků a nemuseli řešit problémy, když nějaké řádky přesunete, přidáte, smažete.

Tedy řekněme, že máte

  • v buňkách A1 až A1000 nějaké hodnoty
  • v buňkách B1 až B1000 nějaké další hodnoty

A potřebujete do buněk C1 až C1000 dá třeba násobek hodnot v předchozích dvou sloupcích, tedy pro buňku C1 byste napsali =A1*B1

Takže vy místo toho napíšete do C1 vzorec

=ARRAYFORMULA(A1:A*B1:B)

a Google automaticky doplní všechny hodnoty. A co víc, když zkusíte nějakou hodnotu z kteréhokoliv řádku ve sloupci C smazat nebo změnti, tak ji Sheets okamžitě dopočítá zpět. Další výhodou je pak rychlost, nemáte to totiž 1000 výpočtů, ale jen jeden (byť nad tisíci řádků).

Nahrazení A1 za A1:A jsme Google Sheets řekli, aby prostě počítal od A1 až do konce sloupce A. Proto jste si asi všimli, že Sheets doplní výpočet do všech řádků, nejen do těch tisíce. Při řešení využijeme druhé úžasné funkce Google Sheets, o které si někdy povíme více a to je funkce Filter. Prostě napíšeme

=ARRAYFORMULA(FILTER(A1:A*B1:B;A1:A<>""))

Tím říkáme „Použij výpočet A1*B1 na všechny pole od A1 resp. B1 po poslední pole ve sloupci A resp. B, ale pouze pakliže příslušná buňka ve sloupci A není prázdná“.

Teď si možná říkáte, že to tak užitečné není, že toho byste dosáhli i třeba pomocí Formátovaných tabulek, které má Excel někdy od verze 2007 a které také umí vyplňovat vzorce do všech řádků. Jenže tyhle funkce v Google Sheets fungují i napříč listy. Takže si dáme další příklad:

Řekněme, že vám nějaký online systém vyjíždí CSV tabulku, kde máte seznam objednávek – ID uživatele, ID objednávky a její hodnotu. Vy si tenhle seznam natáhnete do vaší Google tabulky pomocí další skvělé funkce IMPORTDATA.

No a teď chcete mít na dalším listu seznam objednávek, které byly vyšší než 1000 Kč. Zvládnete to tímhle jedním zápisem na další list:

=ARRAYFORMULA(FILTER('List 1'!A1:C;'List 1'!C1:C>1000))

Tedy vezmi mi všechny hodnoty z A1:C, ale pouze za předpokladu, že hodnota ve sloupci C je vyšší než 1000. Úchvatné, ne? V Excelu byste to museli řešit makry či kontingenčními tabulkami, se všemi jejich nevýhodami.

A to není všechno – výstup pak můžete i seřadit podle nějakého sloupce, třeba sestupně podle posledního sloupce, díky funkci SORT

=ARRAYFORMULA(SORT(FILTER('List 1'!A1:C;'List 1'!C1:C>10);3;FALSE))

Jo a možná vás napadlo: kdybyste chtěli udělat součet všech objednávek pro jednotlivé uživatele, tak aby se jejich ID neopakovalo, můžete použít funkci UNIQUE nad sloupcem s ID uživateli a následně využít funkce SUMIF, a opět přes ARRAYFORMULA si ji natáhnout do všech řádků ke všem uživatelům.

Rubriky
Užitečnosti

Zmenšete PDF, PNG a JPG o desítky procent

Pokaždé, než na svůj web umístíte nějaké větší PDF, PNG či JPG, nebo než je pošlete mailem, zamyslete se nad tím, jestli náhodou zbytečně nezatěžujte příjemce/čtenáře.

Ono se sice třeba 10 MB na PDF může zdát v dnešní době málo, jenže když si vezmete, že většina lidí si otevírá maily na mobilu a u webů už to jsou také desítky procent lidí, tak taková příloha jim vezme nejen tuny času, ale i velkou část jejich limitu (a na webech často ani nepoznají, že se proklikávají do nějakého PDF). A i průměrného cca. 2Mb/s pevného připojení je znát, jestli se vám něco otevře za 5 vteřin, nebo za 20.

Řešení je přitom snadné – doporučuji službu http://smallpdf.com/compress-pdf, se kterou běžně zmenšíte PDF na čtvrtinu velikosti bez (viditelné) ztráty kvality, případně rovnou zvažte, jestli třeba jednostrákové letáky nepřevést na JPG pomocí http://smallpdf.com/pdf-to-jpg. Umí i další kousky, jako převést PDF z/do Office, spojit / rozdělit PDF atd.

Datový objem obrázků pak podobně razantně a snadno můžete změnit přes https://tinypng.com/ (nenechte se zmást názvem, zmenší i JPG), zachová se i průsvitnost PNG. Mají k dispozici i plugin do Photoshopu a API pro vývojáře, kteří by to chtěli integrovat do svých systémů, s tím že 500 úprav je zdarma, další za nějaký mrzký peníz. Používáte-li WordPress, tak je k dispozici i plugin, který vše udělá za vás.

Rubriky
Užitečnosti

Chrome – otevření stejné URL na jiném počítači (sdílení tabů)

Jestli třeba jako já používáte více počítačů (např. firemní/soukromý), určitě jste už někdy potřebovali na druhém počítači otevřít tab z prvního. Můžete si sice třeba poslat URL sobě samému do mailu, ale existuje i snadnější řešení.

Chrome má standardně zapnuté sdílení tabů (případně jej můžete povolit – Nastavení / Rozšířená nastavení synchronizace / Otevřené karty. Když to máte zapnuté, tak můžete prostě z hamburger menu Chromu vybrat Nedávno použité karty (případně ještě Další …) a tam vidíte i taby otevřené v Chromu na jiném počítači (pakliže jste na obou přihlášeni stejně).

Rubriky
Užitečnosti

Excel – automatické vyplnění hodnot ve všech řádcích

Tenhle tip jsem se dozvěděl teprve nedávno, což vzhledem k tomu, jak hodně Excel používám posledních 20 let a jak často jsem to potřeboval, je dost na pováženou.

Asi to znáte – máte v Excelu tabulku, která má tunu řádků. Vy potřebujete dát do nějakého sloupce hodnotu nebo vzorec a chcete je nakopírovat (či rozšířit) do všech řádků až do konce tabulky.

Nepochybně víte, že můžete vzít tu tečku/křížek vpravo dole myší a táhnout a táhnout, ale to je u hodně dlouhých tabulek fakt pruda.

Nebo to možná řešíte jako donedávna já, kdy jsem šel nejdříve do řádku, kde jsou hodnoty, tam jsem zmáčknul CTRL+šipka_dolů, přešel do sloupce, který jsem chtěl vyplnit, tam napsal cokoliv, pak kliknul na CTRL+šipka_nahoru, abych se dostal na tu horní buňku, kde mám vzorec, pak CTRL+SHIFT+šipka_dolů pro označení rozsahu od této buňky až po poslední buňku, načež jsem zmáčknul F2 pro aktivování vzorce v té horní buňce, a konečně CTRL+ENTER pro vyplnění dané hodnoty ve všech označených buňkách. Zní to strašně složitě, ale takhle jsem to dělal dvacet let a je to otázka méně než jedné vteřiny a nemusím sundat ruce z klávesnice.

Nebo jste si možná jako já udělali makro (doporučuji podívat se na vlastnost Range.CurrentRegion (tedy třeba ActiveCell.CurrentRegion.Rows.Count, což vám spočítá počet řádků v regionu buněk okolo aktuálně vybrané buňky).

No a nebo prostě a jednoduše uděláte dvojklik, na té tečce/křížku v pravém dolním rohu buňky, do které jste napsali vzorec, místo abyste za to táhli. Tímto vyplníte všechny následující buňky, až do konce aktuálního regionu. A pakliže máte vybráno více buněk a kliknete na tu tečku/křížek, tak Excel zkusí klasicky následující hodnoty dopočítat (tj. když budete mít v 1. řádku napsáno 1, ve druhém 2, označíte obě buňky a ve vedlejším sloupci budete mít třeba sto řádků s nějakými hodnotami, tak po dvojkliku na tečku/křížek se vyplní následujících 98 řádků hodnotami 3-100).

P.S.: kdybyste někdo věděl, jak toho dosáhnout nějakou klávesovou zkratkou, tak to uvítám.

Rubriky
Užitečnosti

WordPress tip: snadné pojmenování akcí a filtrů

Když se pořádně naučíte programovat ve WordPressu, zamilujete si nepochybně akce a filtry stejně jako já a budete jich aplikovat ve vašem kódu desítky či stovky.

To má ale několik nevýhod

  1. furt musíte vymýšlet, jak je pojmenovávat, a to tak, abyste je pak zas nějak našli
  2. přitom se ale nesmí funkce se stejným názvem opakovat, jinak dojde ke konfliktu
  3. mám pak někdy tunu funkcí, které se aplikují na stejnou akci/filtr a různě se kříží či dělají to samé
  4. nesmí se tyto funkce jmenovat stejně, jako funkce, které definovali autoři WP či pluginů.
  5. optimálně by měly být funkce a filtry snadno přenosné i na další weby

Za těch 10 let co s WP dělám jsem si vymyslel systém, který všechny tyto problémy řeší – pojmenovávám své akce a filtry vždy přesně podle názvu dané akce či filtru a před to používám jednotný prefix.

Např. si řeknu, že budu jako prefix vždy používat své jmého, tedy „kapler_“. Takže když chci vytvořit funkci k filtru sanitize_tile, prostě ji pojmenuji kapler_sanitize_title. Tedy funkce z minulého příspěvku by vypadala takto

function kapler_sanitize_title($title) {
    return str_replace('+', '-', $title); // sanitize plus with dash
}
add_filter('sanitize_title', 'kapler_sanitize_title');

Pointa je, že:

  1. nemusím přemýšlet ani vteřinu nad názvem a přitom se nikdy nebude jmenovat jako funkce někoho jiného (mé jméno je celkem unikátní)
  2. každý filtr či akce má vždy jednu mou funkci, tedy nemůže dojít ke konfliktu, resp. když dojde, tak vím, že už jsem tuto funkci aplikoval jinde a můžu je tak sloučit
  3. Tím že mám všechny filtry vztahující se k jedné proměnné u sebe, nehrozí, mnohem snadněji zkontroluji, jestli se nějak nekříží
  4. Takové funkce snadno přenesu i na jiné weby, protože mají prostě vždy stejnou strukturu

Teoretickou nevýhodou je snad jen ztráta té informace o tom, co daná funkce dělá z názvu funkce. Ale to jen na první pohled. Ve skutečnosti ta funkce už svým názvem prostě jasně říká, že se něco provádí s filtrem sanitize_title. A co konkrétně se provádí, to je pak definováno komentáři u těch jednotlivých úprav.

Klíčové je, že pakliže změním/rozšířím funkcionalitu, nemusím měnit název funkce, aby přesně vyjadřoval její funkčnost. Tedy když budu chtít nahrazovat nejen + ale i = za pomlčku, tak nemusím funkci přejmenovávat z „plus_to_dash“ na „plus_and_equals_to_dash“, ani nemusím vytvářet druhou funkci „equals_to_dash“ aplikovanou na stejný filtr, ani nemusím mít neodpovídající chování funkce „plus_to_dash“, kdyby dělala něco jiného, než jen „plus to dash“.

Prostě bych jen změnil nahrazování za

str_replace(array('+','='), '-', $title)
Rubriky
Užitečnosti

WordPress – filtry a akce pro začátečníky

Na všechny weby své a svých klientů už asi 10 let používám nejpoužívanější CMS na světě – WordPress. Miluji na něm jeho snadnou modifikaci, díky které můžete snadno ze základního systému pro správu blogů udělat pokročilý systém na správu téměř jakéhokoliv obsahu, a přitom geniální zachování aktualizovatelnosti.

Základem této snadné modifikace jsou dva skvělé prvky – akce a filtry. Prakticky na každou zabudovanou funkci WP jsou aplikované nějaké akce a/nebo filtry.

Řekněme, že potřebujete upravit chování WP při tvorbě slugů – hezkých URL – z titulku příspěvku – např. chcete, aby se + symbol převáděl na pomlčku. Zjistíte (nejsnadněji vhodným dotazem na Google), že toto provádí interně funkce sanitize_title.

A teď – mohli byste jí upravit, ale pak by jste o tuto úpravu přišli při příští aktualizaci WP. Nebo kdyby WP byl plně objektový systém, byste mohli tuto funkci přepsat vlastní funkcí, ale to by často znamenalo, že byste museli zkopírovat celou větší funkci, jen kvůli malé změně, a když by se tato funkce ve wordpressu měnila, museli byste si dávat pozor, aby ta vaše držela krok.

Místo toho má WP právě filtry a akce:

  • filtry mají na vstupu nějakou hodnotu (typicky text) a vy navázáním vaší funkce na tento filtr můžete tuto hodnotu změnit.
  • akce mají jen své místo a prioritu a vy navázáním své funkce na danou akci můžete na daném místě provést vlastní akci – typicky něco vypsat.

Takže zpět k našemu příkladu. Funkce sanitize_title má před výstupem na sebe nevázán filter, který se jmenuje také sanitize_title (není vždy pravidlem, že se shodují, záleží s čím pracují).

Vy tak můžete do svého tématu (např. do svého souboru s funkcemi functions.php) napsat následující volání tohoto filtru:

function plush_to_dash($title) {
    return str_replace('+', '-', $title);
}
add_filter('sanitize_title', 'plus_to_dash');

Řádek add_filter aplikuje váš filtr definovaní funkcí „plus_to_dash“ na filtr, který se jmenuje sanitize_title a který je aplikovaný v kódu u funkce sanitize_title na proměnou $title. Vaše funkce plus_to_dash tak bere na vstupu tuto jednu proměnou a nahradí v ní plus za pomlčku a výsledek vrátí.

Podobně fungují akce, které však nepracují s hodnotou, ale jen s místem, kde jsou umístěné. Tedy např. akce wp_head:https://codex.wordpress.org/Plugin_API/Action_Reference/wp_head je zodpovědná za vypsání veškerého obsahu do hlavičky vašeho webu. Když tedy budete chtít do hlavičky třeba vlastní styl, uděláte to nějak takto:

add_action('wp_head','hook_css');

function hook_css()
{

$output="<style> .wp_head_example { background-color : #f1f1f1; } </style>";

echo $output;

}

A pointa je, že akce i filtry je možné nejen přidávat, ale i odstraňovat a tím můžete snadno změnit i výchozí chování WordPressu. Toho docílíte snadno funkcemi remove_action resp. remove_filter.

Např. řekněme, že se vám nelíbí, že WordPress na výstupu automaticky převádí pevné odřádkování v obsahu příspěvku na odstavce. Dělá to tak, že aplikuje funkci wpautop na filter the_content.  Tedy není nic snazšího, než tento filtr odstranit:

remove_filter( 'the_content', 'wpautop' );

 

Rubriky
Užitečnosti

Excel+VBA – vložit jako text

Asi to znáte – kopírujete odněkud text do Excelu a on se tam vloží i s formátováním. Jasně, můžete jít na Home / Paste / Paste special / Insert as Unicode, nebo Home / Paste / Paste values (podle toho, jestli vkládáte text z nějakého dokumentu, či jestli vkládáte hodnoty z nějaké excelové tabulky) – ale to je samozřejmě otravné a zdržující.

Takže pro tyto účely jsem si vytvořil toto makro, kterému jsem přiřadil myslím dobře zapamatovatelnou zkratku CTRL+SHIFT+V.

Makro nejdřív zkusí obsah schránky vložit jako Excelové hodnoty, když se nezadaří, tak to zkusí jako Unicode text, a když ani to nejde, tak prostě jen pípne.

Sub Vlozit_jako_text()
'
' Vlozit_jako_text Makro
'
' Klávesová zkratka: Ctrl+Shift+V
'
On Error GoTo unicode
 Selection.PasteSpecial Paste:=xlPasteValues
 Exit Sub
unicode:
 On Error GoTo finish
 'ActiveSheet.PasteSpecial Format:="Text v kódu Unicode"
 ActiveSheet.PasteSpecial Format:="Unicode Text"
 Exit Sub
finish:
 Beep
 
End Sub
Rubriky
Užitečnosti

Excel+VBA – reset filtru tabulky při jejím zavření

Jestli pracujete ve firmě ve více lidech na jedné tabulce a používáte filtry, tak se vám už určitě stalo, že jste otevřeli tabulku a byly tam vyfiltrované nějaké položky podle potřeb někoho jiného a vy jste to museli nejdřív zrušit.

Já to vyřešil tak, že se u příslušné tabulky při ukládání (případně by šlo při otvírání filtr prostě zrezetuje. Následující makro je třeba přiřadit objektu ThisWorkbook („Pricelist“ je název listu, kde chci při ukládání rezetovat filtr, šlo by samozřejmě smyčkou projít všechny):

Private Sub Workbook_BeforeClose(Cancel As Boolean)

On Error Resume Next
 ActiveWorkbook.Sheets("Pricelist").ShowAllData

End Sub