A következő címkéjű bejegyzések mutatása: Dátum. Összes bejegyzés megjelenítése
A következő címkéjű bejegyzések mutatása: Dátum. Összes bejegyzés megjelenítése

Hányas vagy? (Reloaded)

Egy korábbi írásban már foglalkoztam azzal, hogyan lehet kiszámítani valakinek a napra pontos életkorát. Lássunk most még egy módszert! A megjegyzések egyikében feltett kérdésre tekintettel kibővítem a lehetőségeket egy további formátummal is.

Van egy függvény az Excelben, amit még a súgó sem tartalmaz:
DÁTUMTÓLIG(kezdő dátum;záró dátum; egység)
A függvény két dátum különbségét számolja ki években, hónapokban vagy napokban. (Jellemző, hogy ez az amúgy kiváló függvény csupán a Lotus 1-2-3-mal való kompatibilitás okán került bele a programba. Úgy látszik, a Microsoft úgy vélte, az ő felhasználói nem méltóak erre az eszközre.)
A függvény részletes leírását magyar nyelven csak a SharePoint szerver kapcsán ismerteti a Microsoft, de ott is hibásan, minthogy magyarra fordították a függvény dátum argumentumait is. Ezekkel az argumentumokkal a függvény a #SZÁM hibaüzenetet eredményezi csupán. A helyes argumentumok tehát Y, M, D, MD, YM és YD. Amennyiben a dátum argumentumokat nem közvetlenül a képletbe írjuk, hanem dinamikusan adjuk meg, úgy nem kell idézőjelek közé tenni őket!

A DÁTUMTÓLIG és a szökőévek
A függvény az YD egység argumentum esetén a kezdő dátum évszáma alapján veszi figyelembe a szökőéveket. Például:

Kezdő dátum Záró dátum Egység Eredmény
2011.02.01 2012.03.01 YD 28
2012.02.01 2013.03.01 YD 29

Életkor: 51 év 11 hónap 4 nap
Ha a fenti formában szeretnénk egyetlen cellában megkapni valakinek a pontos életkorát, akkor − feltételezve, hogy a kezdő dátum a B1, illetve a záró dátum a B2 cellában van − az alábbi képletet kell beírnunk:
="Életkor: "&DÁTUMTÓLIG(B1;B2;"y")&" év " &DÁTUMTÓLIG(B1;B2;"ym")&" hónap "
&DÁTUMTÓLIG(B1;B2;"md")&" nap"
N. B.: A függvény neve angolul DATEDIF().

Fájl letöltése: 2007+ (xlsx) | 97-2003 (xls)

Heuréka! (Reloaded)

Egy korábbi írásomban a billentyűzet használatának előnyei mellett érveltem, és arról írtam, miként lehet a gépelés során felkínált függvénynevet akár néhány karakter beírása után a szerkesztőlécre varázsolni.
Most kaptam egy kérdést: Hogyan lehet a billentyűzetről bevinni az aktuális dátumot egy cellába.
A megoldás olyan mértékig Microsoftos, hogy úgy gondoltam, nem csupán a kérdezőnek válaszolok, hanem a téma megér egy önálló írást is.
Az Excel Súgójának tanúsága szerint a CTRL+SHIFT+: billentyűkombináció beírja a cellába az aktuális időt. Ezzel nincs is semmi baj. Ez működik is a régi (2003-as és korábbi) valamint új verziókban (2007+) egyaránt. Sőt! Működik a cellán állva közvetlenül, a cellában szerkesztő módban (F2) és a szerkesztőlécen is.
A probléma az aktuális dátummal van: a helyzet ebben az esetben már korántsem olyan rózsás, mint az időpont esetében. A működés meglehetősen kaotikus, a telepített verzió, és a csillagok együttállásának a függvénye. A 2003-as és korábbi verziókban ez a funkció csak abban az esetben működik, ha a CTRL+. (pont) billentyűkombinációt a szerkesztőlécen állva nyomjuk le. Erre a Súgó a 2003-as verzió esetében − nagyon helyesen − fel is hívja a figyelmet. A 2007+ verziók esetében azonban egy szó sem esik arról, hogy ne lehetne bárhol megnyomni a CTRL+; (pontosvessző) billentyűkombinációt. Arról most nem beszélek, miért kellett megváltoztatni az esetleg korábbról már megszokott gyorsbillentyű-kombinációt. Csak az ökör következetes, miért lenne akkor a Micorosft az? Azt sem firtatom, hogyan kell vajon egy magyar kódkiosztású billentyűzeten lenyomni a CTRL+; (pontosvessző) billentyűkombinációt, hiszen a pontosvesszőhöz az ALT GR billentyűt is le kell nyomni. Minthogy az ALT GR billentyű egyenértékű a CTRL+ALT (baloldali) billentyűkombinációval, valahogy kezdünk frusztrált állapotba kerülni a dolgok mikéntjét illetően.
Feltétlenül szót érdemel viszont, hogy a Súgóban szereplő billentyűkombináció semmilyen konstelláció esetében sem működik: sem a cellán állva, sem a cellában szerkesztő módban (F2), sem a szerkesztőlécen! Kipróbáltam angol billentyűzettel is, hiszen ott nem kell az ALT GR a pontosvessző leütéséhez: úgy sem működik!

Nem láttam volna persze neki az írásnak, ha csak a Microsoftot akarnám fikázni; van nekem annál jobb dolgom is.
A megoldás pedig, Benevole Lector, aaaaaaaaaaaaaa… −  prrrrrrrrrrrrrrrrrrrrrrr  − tádááááááááá:

CTRL+0 (nulla)

billentyűkombináció, amely − a 2003-as verzióhoz hasonlóan − bármilyen módon működik.

Hányas vagy?

Vannak esetek, amikor nem elegendő nagy vonalakban, pusztán a születési év alapján kiszámítani valakinek az életkorát, hanem pontosan tudnunk kell, hogy az illető betöltött-e már egy bizonyos életkort. Ilyen esetek pl. a nagykorúvá válás a 18. életév betöltésével, a mentesülés életkor alapján az idegenforgalmi adó alól, vagy a 70 év felettiek utazási kedveszménye.
Az alábbi írásban több módszert is bemutatok, hogyan tudod a pontos életkort kiszámítani az Excelben.


1. Képlet
Mint tudod, az Excel az 1900. január 1. óta eltelt napok számaként tarja nyilván a dátumokat. Ha a tárgynapi dátumból kivonod a vizsgálni kívánt személy születési dátumát, megkapod, hány napos az illető.
A születési dátumot igény szerint cellahivatkozásként vagy közvetlenül a képletbe írt konstansként egyaránt megadhatod. Ha a feladat az, hogy egy adott napon állapítsuk meg az életkort, és ezt az eredményt konzerváljuk (azaz az életkor ne változzon meg az idő múltával, ha újra megnyitjuk a fájlt), akkor nem szabad a MA() függvénnyel hivatkoznunk a tárgynapi dátumra, hanem csak állandóként adhatjuk meg azt.
Meglepő módon a dátumkonstansokat (szám!) idézőjelek közé kell tenni (szöveg!).
Végezetül már csak évekre kell átszámolnod a napokat, és az eredményt a legközelebbi egész számra kell lefelé kerekítened. No persze ez sem annyira egyszerű ám, mint amilyennek hangzik. A kivitelezés kapcsán már bizony problémákba ütközünk.
Kezdjük azzal, hogy hány napos is egy év? Hát nem itt van már megint az a fránya szökőév. Nos, amennyiben kortársaink életkorát kívánjuk kiszámítani − és mi mást is kívánhatnánk, hiszen az Excel nem képes az 1900. január 1. előtti dátumokat kezelni, kései utódainknak pedig a születési dátuma az, amit nem ismerünk −, nem tévedünk nagyot, ha úgy vesszük, hogy minden negyedik év szökőév, azaz egy év 365,25 napból áll. E lazaságot megengedve kizárólag az 1900-ban születettek esetében tévedünk, hiszen 1900 nem volt szökőév, de ezt az apró malőrt más eljárással sem tudnánk elkerülni, hiszen − mint arról egy korábbi írásban már szó esett − az Excel tévesen szökőévként kezeli az 1900. esztendőt.
Aztán itt van a kerekítés... Mivel a töredék évet nem vehetjük figyelembe, hiszen a beöltött életévek száma érdekel csak bennünket, a kapott eredményt mindenképpen lefelé kell kerekítenünk. Abból adódóan, hogy az életévek esetében csak az egészeket vesszük figyelembe, nem kell a kerekítés mértékével bajlódnunk, elegendő az eredmény egész részét vennünk. E célra az INT() függvénynél nem találunk kézenfekvőbb megoldást.



Életkor kiszámítása képlettel


2. Függvény
Az ATP (Analysis ToolPak) készletben található YEARFRAC() függvény két dátum (kezdő dátum; befejező dátum) közötti napok számát töredék évként fejezi ki. Ha a függvény első argumentumaként a születési dátumot, második argumentumaként pedig a tárgynap dátumát adod meg, máris megkaptad az életkort tizedes szám alakjában. A függvény alkalmazása során is használhatók cellahivatkozások,  dátumkonstansok, illetve a mindenkori tárgynap meghatározásához a MA() függvény.
A nem kívánt tizedesektől a fentebb már említett INT() függvény segítségével tudsz megválni.
A függvény használatának egyetlen problémája, hogy ha egy másik számítógépen nincsen bekapcsolva az ATP, az életkor helyett az #ÉRTÉK hibaüzenettel találja szembe magát a felhasználó.

=INT(YEARFRAC(születési dátum;MA()))

Szökőévek II.

Szökőév volt-e 1900?
Egy korábbi írásomban tisztába kerülhettél a szökőév fogalmával, így most azonnal vágod a helyes választ: NEM!
Nyilván azt is tudod, hogy a szökőévekben a február hónap 29 napos. (Csak a rend kedvéért jegyzem meg, hogy nem február 29., hanem február 24. a szökőnap!) Most nézzük, hogyan vélekedik a minderről az Excel.
Az A1 cellába írd be:: 1900.02.28, majd a kitöltő négyzet segítségével másold a beírt értéket az A3 celláig.
Te is meglepődtél? (Mert én igen.) Február 28. után február 29. következik, azaz − irgalom anyja, ne hagyj el!az Excel szerint 1900 szökőév volt!
A Microsoft egy percig nem tagadja a hibát, sőt, megmagyarázta, mi ennek az oka, illetve miért nem fogja kijavítani azt sohasem. Angolul nem beszélő olvasóimat kisegítem egy helyenként kiegészített, magyarított kivonattal:
A Lotus 1-2-3 táblázatkezelő első megjelenésekor (1983) − helytelenül − szökőévként kezelte 1900-at. Ez az apró tévedés megkönnyítette a szökőévek kezelését a programban, ugyanakkor semmiféle hibát sem eredményezett a dátumműveletek jelentős részében. Ezt a számítási módot vette át a Multiplan (az Excel elődje; 1982), majd az Excel 2.0 (1987) is, ami egyfelől lehetővé tette ugyanannak a dátum sorszámozási módszernek az alkalmazását, másfelől nagyobb kompatibilitást jelentett a Lotus 1-2-3-mal, biztosítva a munkalapoknak a különböző programok közötti mozgatását.
A Microsoft szerint ugyan nem volna lehetetlen a hibát kijavítani, de úgy vélik, a beavatkozás inkább lenne hátrányos, mint előnyös. Véleményük szerint a hibajavítás az alábbi kellemetlen következményekkel járna:
  • Az MS Excel munkalapokon és más dokumentumokban szinte valamennyi dátum egy nappal csökkenne. Az elcsúszás kijavítása tekintélyes idő- és energia ráfordítást igényelne, kiváltképp a dátumokat kezelő képletek tekintetében.
    Bla, bla, bla... Más szavakkal: ez a hibajavítás nem lenne kifizetődő. Tán nem az a dolga a fejlesztő bandának, hogy rengeteg időt és energiát fordítson egy jól működő szoftver előállítására, nem pedig akár egy percet is arra, hogy megmagyarázza, miért nem tudnak egy ismert hibát kijavítani? Szegény Microsoft... Mindjárt megsajnálom őket.
  • Bizonyos függvények, mint például a HÉT.NAPJA(), eltérő értékeket adnának vissza, ami a munkalap függvények helytelen működését eredményezné.
    Miért kellene ennek így lennie, ha valóban hibajavítás történne? Nyilvánvaló, hogy a feladat nem pusztán annyi, hogy törlik azt a fránya február 29-et. Dolgozni is kellene azért a nem kevés pénzért, fiúk!
  • Megszűnne a dátum sorszámozási módszer kompatibilitása az MS Excel, és más, dátumokat kezelő alkalmazások között.
    Hja, a kompatibilitás... Na és mi volna akkor, ha a többi hibásan működő szoftvert is kijavítanák? Úgy tűnik, ez a lehetőség fel sem merül... Egyszerűbb az IBM-re fogni az egészet. Ők tehetnek mindenről, ők cseszték el az egészet az elején! Nem gondolom, hogy bármilyen hiba reprodukálásával kell biztosítani a kompatibilitást egy hibásan működő szoftverrel. A hibajavítás elvégzése esetén lehet, hogy megszűnne a kompatibilitás, ugyanakkor a Microsoft elmondhatná, hogy az ő programja − ellentétben a többiekkel − jól működik! Ez vajon miért nem szempont?
Amennyiben a hibát nem javítják ki, annak mindössze egy következménye marad:
  • A HÉT.NAPJA() függvény hibás eredményt ad vissza az 1900. március 1. előtti időszakra. Tekintettel arra, hogy elenyésző azoknak a felhasználóknak a száma, akik 1900. március 1. előtti dátumokkal dolgoznak, így az ebből adódó probléma meglehetősen ritka. A hiba ráadásul csak abban az esetben jelentkezik, ha az 1900-as dátum rendszert használjuk.
    Valóban elenyésző lehet azoknak a felhasználóknak a száma, akik 1900. március 1. előtti dátumokkal dolgoznak, minthogy az Excel egyáltalában nem képes arra, hogy az 1900. január 1. előtti dátumokat kezelje. Erről az apróságról az érvelés közepette nem tesz említést a drágalátos Microsoft.
    A megoldás: használjuk az 1904-es dátum rendszert, akkor aztán tényleg semmi problémánk nem lehet. Azt bezzeg nem mulasztják el hangsúlyozni, hogy az összes többi századvégi szökőévet (mint pl. 2100) helyesen kezelik. Dicséretes. Csak egy évet kezelnek rosszul, nem az összeset. Legyünk hálásak érte. Milyen kár, hogy nem a távoli jövőt érintő vízióim nyilvántartására szeretném használni a programot...
Ezzel még koránt sincs vége: szó sincs arról, hogy pusztán ez az egy kellemetlen következménye van az eltűnt napnak. De mostanra legyen ennyi elég. Egy későbbi írásban még visszatérek erre a mizériára.

Off topic: Ius murmurandi záradék
Felhasználó Testvérem! Vedd észre, hogy a szoftverfejlesztés nem rólunk, felhasználókról, hanem róluk, a fejlesztőkről és forgalmazókról szól.  A programozók szerint a felhasználó egy idióta, aki képtelen arra, hogy elmondja, mit akar, ezért helyette is neki, szerencsétlen  fejlesztőnek kell gondolkoznia. Neki kell megmondania, hogy a felhasználónak mi a jó, mert az ostoba felhasználó képtelen ezt saját maga eldönteni. Igaz, a programozók nem értenek az adott szakmához (sokszor a sajátjukhoz sem), de úgy vélik, tudnak programot írni. Így jutunk el aztán fokozatosan oda, hogy teljes mértékben kihal az, amit felhasználó barátnak nevezünk. Mert a programozó bizony mindig a legkisebb ellenállás irányába halad. Ha csak teheti, olyan megoldást választ, ami a legrövidebb idő alatt a legkevesebb munkával a legtöbb pénzt hozza. A felhasználó pedig tűrje békével jobbágy sorsát...



Szökőévek I.

Mit válaszolnál, ha azt kérném tőled, mondd el a szökőév definícióját?
Bizony tévedsz, ha úgy gondolod, hogy minden néggyel osztható év szökőév!
A helyzet koránt sem ennyire egyszerű. A definíció pontosan így hangzik: szökőév minden olyan év, amely osztható 4-gyel, de nem osztható 100-zal. Kivételt képeznek a 400-zal osztható évszámok, ezek szintén szökőévek. Mindhárom esetben természetesen maradék nélküli osztásról van szó. Amennyiben ezt a számítást nem kívánod fejben elvégezni, írd be a vizsgálni kívánt évszámot az A1 cellába, és az alábbi képletet egy másik cellába:

=HA(VAGY(MARADÉK(A1;400)=0;ÉS(MARADÉK(A1;4)=0;
MARADÉK(A1;100)<>0));"szökőév"; "nem szökőév")

A képlet segítségével könnyen ellenőrizhetjük a fenti definíciót a gyakorlatban: szőkőév volt 1600, 2000, de nem volt az 1700, 1800, 1900!

Csak a tőlem elvárható szőrszálhasogatás kedvéért jegyzem meg, hogy egy további feltételvizsgálattal, vagy adatérvényesítéssel meg kellene oldani a megadott évszám ellenőrzését, azaz, hogy ne lehessen kisebb 1582-nél, minthogy XIII. Gergely pápa ebben az évben hajtotta végre a naptárreformot.

Egy későbbi alkalommal még visszatérek a témára.