Visszaszámláló kódszelet VBA-ban

Hogy mindig tudjuk hányadán állunk

2016. január 16. - Office Guru

Valószínűleg többekben felmerült az igény a napi feladatok során, hogy visszaszámlálást szúrjanak be Excel dashboardjukba, táblájukba, mondjuk így jelezve az adott táblát megtekintő felhasználók számára, hogy egy tréning mikor kezdődik vagy éppenséggel mikor van egy feladat határideje.

Bár elsőre komplexnek tűnik egy ilyet megvalósítani, VBA segítségével ezt nem annyira nehéz megalkotni, csak ismerni kell a megfelelő utasításokat (azokat pedig könyvekből vagy éppen a hivatalos Microsoft dokumentációból is le lehet vadászni).

Első lépésként válasszuk ki a cellát, amelyben ezt a visszaszámláló órát szeretnénk elhelyezni, majd a Ribbonunk Home füle alatt található Number szekcióból formázzuk meg Time típusra az adott cellát (ez az én esetemben most az I8 lesz:

800.jpgÍrjuk be a kiválasztott Time formátumban, hogy pontosan mennyiről szeretnénk visszaszámolni - 1 óra, 1 nap, 1 hónap stb.:

801.jpgEzután nyomás a VBA-editorba, ahol az itt már korábban leírtaknak megfelelően szúrjunk be egy új modult az Insert menü Module parancsa segítségével:

802.jpgMielőtt összedobnánk ezt az aprócska kódot, két fontos parancsot jegyezzünk meg magunknak, mert ez a kettő fog segíteni ennek a makróban az összehozásában. Az egyik a TimeSerial funkció, ami nem tesz mást, mint a paramétereiként megadott óra, perc és másodperc értékek alapján visszaad egy időpontot, például

TimeSerial(16,25,17)

4:25:17 időpontot adja vissza. A másik, amit meg kell jegyeznünk a TimeValue funkció, amely a paramétereként megadott dátum értékét adja vissza nekünk, például

TimeValue(12:00 AM)

0.5-öt ad vissza, hiszen az pontosan a nap felét jelenti.

A következő lépések már konkrétan a kódunk felépítéséhez szükségesek, persze nem feltétlenül ez a legjobb megoldás, ami következik, hiszen jómagam is láttam ennek több verzióját, de az alaplogika többnyire azonos. Két szubrutinra, Subra van szükségünk, az első nagyjából nem fog semmi mást csinálni, mint az Application.OnTime metódus segítségével minden egyes értékváltásnál (tehát ha 23:00:00-ból 22:59:59 lesz, az egy értékváltás) újra meg újra elindítja majd a második szubrutint.

Az első Subban definiáljuk egy változót, Date típusként, ezzel is jelezve, hogy itt dátum- vagy időértéket szeretnénk majd tárolni, majd ebbe a változóba töltsük a jelen pillanat idejét plusz egyetlen másodpercet, hiszen azt akarjuk, hogy a visszaszámlálónk valós időben működjön.

803.jpgAhogy látható, változónk neve az Ido (hibát követtem el, hiszen igencsak nem célszerű szubrutinunknak és változónknak ugyanazt a nevet adni, de most már így marad), ezt Date típussal deklaráltuk, majd az itt már többször átbeszélt módon feltöltöttük jelen pillanatunk idejével plusz egyetlen másodperccel. Jelen pillanatunkat a Now paranccsal határozhatjuk meg, ami visszaadja az adott időpillanatot, ehhez pedig hozzáadunk 1 másodpercet. A TimeValue alkalmazására kódunk második részlete miatt lesz szükség, hiszen az Application.Ontime Now +Timevalue (meghatározott időparaméter) azt fogja meghatározni, hogy az ezután megadott szubrutin mennyi idő eltelte után fusson le, azaz kódunknál maradva az

Application.OnTime Ido, "Visszaszamlalo"

utasítás az Ido változóban betöltött 1 másodperc eltelte után lefuttatja a Visszaszamlalo neven létrehozott második szubrutinunkat. Ha abban pedig majd meghívjuk a folyamat végén az Ido szubrutinunkat, akkor belátható, hogy másodpercenként le fog futni mindkettő szubrutin.

804.jpgMásodik szubrutinunkról már tudjuk, hogy a "Visszaszamlalo" nevet viseli és ez nem fog mást csinálni, mint megadott I8 cellánk értékét módosítja másodpercenként. Ehhez először deklaráljunk egy változót Range típussal, ebbe fogjuk beállítani majd kezdőértékként azt a cellát, ahol a visszaszámlálónk fut majd:

805.jpgAki követi a blogot, annak szerintem ezt a részt már nem kell magyarázni, a változónk kezdőértékeként beállítottuk az I8-as cellát az Application.ActiveSheet.Range("I8") utasítással.

És most következik az egész történet kulcsa, amikor Tartomany változónk értékét (Tartomany.Value) megváltoztatjuk a Tartomany változónk értékéből kivont egyetlen másodperccel, amit a következőképpen adunk meg:

806.jpgFentebb már beszéltünk a TimeSerial utasításról, így valószínűleg teljesen egyértelmű, hogy mit miért csináltunk itt, az eredmény pedig az lesz, hogy a szubrutin futása után I8 cellánk értéke 1 másodperccel kevesebb lesz.

Célszerű esetleg betenni egy popup üzenetet arra az esetre, ha végezne a visszaszámláló (hiszen alapvetően pont ez lenne a cél), amit egy szimpla IF utasítással tudunk megtenni, azaz ha Tartomany.Value (Tartomany változónk értéke) eléri a nullát, akkor MsgBox utasítással írjon ki egy üzenetet. Sose felejtsük el lezárni az IF ciklust.

807.jpgUtolsó lépésünk pedig már csak annyi, hogy eme szubrutinunk végén indítsuk el/hívjuk meg a másik szubrutint, hogy jól működjön a visszaszámlálás. Más szubrutinokat a Call parancs segítségével tudunk meghívni.

808.jpgMaga a kód nem bonyolult és a felhasználási területek is elég szűkösnek tűnnek, de a lényeg, hogy tanuljunk belőle és ha már van fogalmunk az időkhöz kapcsolódó parancsok egy részéről, már el tudunk indulni ilyen kódokkal is.

A bejegyzés trackback címe:

https://officeguru.blog.hu/api/trackback/id/tr778277066

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Kartall 2017.01.10. 04:17:09

Ez nagyon jónak tűnik, de hogyan kellene leállítani a futásukat? Mert, ha bezárom azt a füzetet, amiben futottak, de más Excel dokumentum megnyitva marad, akkor újra visszanyitja a visszaszámlálót tartalmazó munkafüzetet.