Kezdők hibái (VBA)
2013-01-30T09:37:24+01:00
2013-01-30T13:51:04+01:00
2022-07-23T16:11:18+02:00
  • Azért nem árt megismerni a VBA "típusok" trükkjeit is.

    pl. a Dátum egy "egyszerű" szám.

    Ha egy cellában van egy dátumod, akkor pl. a
    For i = Date To Range("a1") Debug.Print i Next
    Szépen lazán elszámol a mai naptól az a1-es cella napjáig.

    --

    dim i as integer 'mert függvényeknél reklamál, ha nem integer


    Ez elég érdekes kérdés
    dim i as integer x=fuggveny(i) .. function fuggveny(a as integer) ..

    esetén ha más típus az nem tetszik neki.

    (Ugyan azt a memória helyet használja az "a" és az "i" is)


    Így pedig nem érdekes a típus:
    Sub ttt() Dim i x = fuggveny(i) End Sub Function fuggveny(ByVal a As Integer) End Function

    --

    Sebességmérésre ez is lehet egy megoldás:
    kezd=timer ' Itt az egyik variáció kozep=timer ' Itt a másik variáció veg=timer msgbox kozep-kezd & " " & veg-kozep
    Mutasd a teljes hozzászólást!
  • Valószínűleg ilyenkor a praktikusság, későbbi felhasználhatóság szokott dönteni, persze fontos lehet a sebesség is, főleg ha nagy a táblázatod.
    Érdemes lehet lemérni az időt, mennyi idő alatt végez az egyik vagy másik megoldással.

    Idő mérésre pl. monitor megoldása:

    Public Declare Function QueryPerformanceCounter Lib "Kernel32" (X As Currency) As Boolean
    Public Declare Function QueryPerformanceFrequency Lib "Kernel32" (X As Currency) As Boolean

    lásd itt:
    http://prog.hu/tarsalgo/137553/Excel+2007+tablazatbol+adatokat+kiiro..
    Mutasd a teljes hozzászólást!
  • set objcet = Nothing célszerű tenni

    Akkor ezeket is belepakolom, gondolom ártani nem árt.

    Amit dióhéjban elmondhatok az annyi, hogy a ciklusokból a For Each a leglassabb.


    dim i as integer i = 1 do while i<10 (...) i=i+1 loop
    vagy for ciklus
    dim i as integer 'mert függvényeknél reklamál, ha nem integer for i=1 to 10 (...) next

    A legtöbb esetben for és while ciklust is lehet alkalmazni, legfeljebb a for (vagy éppen a while) feltétele, és a ciklusban szereplő eljárások lesznek nehezebbek. (pl 2 dátum között naponta végiglépkedni "while előbbi<= utóbbi", vagy "for i=1 to datediff("d",..,..)", és akkor a forban kell az adott napnál a dateadd("d",i,kezdo)-re hivatkozni...
    Ilyen helyzetekben nem tudom egyértelműen eldönteni melyik a jobb (átláthatóságban talán a while, de épp ezért merült fel bennem a kérdésem).
    Mutasd a teljes hozzászólást!
  • Köszönöm, javítom akkor ezeket.

    Az Excel programozása (2008-as kiadás, illetve 2007-es, Computerbooks)
    Micu a 2005-öst lektorálta. Van valami jelentősége melyik kiadás?


    Illetve egyéb gyakori hiba, amitől a senior programozók a falra tudnának mászni? (így a for each ciklussal is 6-7 mp alatt dolgoz fel 110x3-as táblázatból collectionbe, majd ehhez párosítja a másik excelből az 1200x10 táblázatot, illetve ezekkel végez számolásokat. nem tűnik soknak, de szeretek újakat tanulni, gondolom ebben a könyv is segíteni fog, ma be is szerzem ezt a könyvet)
    Mutasd a teljes hozzászólást!
  • Csak adatok tárolására objektumot nem nagyon érdemes létrehozni. A type-ot meg teheted tömbbe is. A keresést meg inkább az excel match függvényével végezném és nem collection-ökön végigiterálva.
    Mutasd a teljes hozzászólást!
  • Szia

    Egyébként a computerbooks-nak van excel vba-s könyve (2003-as kiadását még asszem Micu lektorálta), azt ugye már beszerezted?

    Ezidáig nem tudtam róla (ELTE-n nem tanítanak VBA-t, hobbiként kezdtem el vele foglalkozni és megtetszett, ezért írom ebben a szakdogámat). De legfontosabb feladataim közé tartozik mostmár.


    Az osztályok egyéb lehetőségeiről tudok, ezért kérdeztem, hogyha csak adatokat tárolnék benne (semmi sub és function), akkor van-e értelme ennek, vagy típus. Az OOP nem ismeretlen számomra, ezért csináltam megszokásból egy string+int tárolására is osztályt, amire elég lenne a típus is. Ezért merült fel bennem a kérdés a kettő tárolására vonatkozó különbségekről (melyik a "szebb" ilyen esetben)


    A kérdés az, hogy miért készítenél belőlük külön collection-t

    A collection-ben egy létrehozott osztály objektumait pakolom, aminek egyik adattagja (név, tehát lényegében a kulcs, ha fogalmazhatunk így) a munkalap A oszlopában vannak. Elnézést, az előbbi
    collection(1) = cells(1,1))
    félrevezető volt, a helyes így lenne:
    collection(i).név = cells(i,1).value

    A konkrét meg az lenne, hogy első lépésben feltöltöm az objektumok név paramétereit az A oszlopból, utána egy másik "rendezetlen neveket tartalmazó excelből" keresném meg azt az objektumot aminek a név adattagja egyezik. Most for each ciklussal szedem ki az objektumokat és ha ugyanaz a név, akkor töltöm ki az objektum többi adattagját is az új excel többi oszlopának adataival.
    Ellenben beépített függvényekkel úgy is meg lehetne oldani, hogy a másik excel nevet tartalmazó celláját megkeresni az eredeti excel A oszlopából, és ahanyadik sorban szerepel, az lesz a collection indexe.
    for each ciklus helyett egy beépített keresés függvényt használnék (kihasználva, hogy menet közben nem módosul a sorrend, így a program futásának minden pillanatában igaz rá az elsőként feltett egyenlőség)


    Sajnos az ELTE-n nem tanítanak ilyen technikákat (most VBA nyelvtől függetlenül), több c++ alapú kötelező órám is volt már, de meg se említettek ilyeneket. Bár aki ebben a szakmában akar elhelyezkedni, annak lehet nem csak a kötelező órákat kéne elvégeznie
    Mutasd a teljes hozzászólást!
  • ha csak pár string/int/alap típus "összefogása" kell nekem, akkor osztály vagy típus? egyáltalán mi a különbség azon kívül köztük, hogy osztályt lehet collection-be rakni, típust meg nem?


    A különbség a kettő között ég és föld! A type csak adatok tárolására szolgál. Osztályokba meg az adatokon kívül a rajtuk végzendő műveleteket is bele lehet tenni, eseményeket válthat ki, interfészeket valósíthat meg, meg úgy általában objektum orientált programozást tesz lehetővé (persze a VBA-ban az OOP csak megszorításokkal van jelen). Egészen más programtervezési szemléletre van szükség, ha saját osztályokat kezdesz el használni.

    - ha van a munkalapon egy listám amiből alkotok egy collection-t (így ugyebár a collection(1) = cells(1,1)), akkor ciklussal keressem, vagy a beépített excel függvények a gyorsabbak?


    Ha már collection-t készítettél ,akkor az excel függvényei nagyon nem játszanak. A kérdés az, hogy miért készítenél belőlük külön collection-t, ha a megfelelő range megadásával ott van már az a collection (range("akarmi").cells). Egyébként egy range adatait az excel beépített függvényei gyorsabban dolgozzák általában fel. Robi80 által leírtakat még annyival egészíteném ki, hogy application.excel_függvény_neve vagy worksheetfunction.excel_függvény_neve (a 2 hívási forma működése némileg eltér a hibakezelésben) formában közvetlenül vba-ból is használhatod az excel munkalap függvényeit.

    Egyébként a computerbooks-nak van excel vba-s könyve (2003-as kiadását még asszem Micu lektorálta), azt ugye már beszerezted?
    Mutasd a teljes hozzászólást!
  • Amit dióhéjban elmondhatok az annyi, hogy a ciklusokból a For Each a leglassabb.

    Viszont ciklust is mindig úgy érdemes választani, hogy mi az, amin végig kell menni, milyen feltételnek kell teljesülni.

    Viszont ha lehet, akkor kerülni kell a ciklusok használatát, helyette célszerű az Excel beépített függvényeit használni (pl. keresésnél a Find vagy Match használata ahelyett, hogy ciklussal végiglépkedünk az összes cellán).
    Illetve használhatjuk a munkalap képleteket is, úgy, hogy megadjuk a képletet (mintha csak egy cellába írnánk bele, de magyar helyett angolul, pontosvessző helyett vessző, a szimpla macskaköröm helyett dupla), majd ezt a képletet egy tartomány Formula tulajdonságához rendeljük.

    pl. a B oszlop elemeiből rendre kivonjuk az A oszlop elemeit, az eredményt pedig a C oszlopban szeretnénk:


    Dim keplet As String keplet = "=B1-A1" Range("C1:C10").Formula = keplet


    persze lehetne ciklussal is, de lassabb lenne...


    Dim i As Integer For i = 1 To 10 Cells(i, 3).Value = Cells(i, 2).Value - Cells(i, 1).Value Next



    A set objcet = Nothing célszerű tenni, ha már nincs szükségünk az objektumra, hogy a memóriából felszabaduljon. Mondjuk a program legvégén lehet nem annyira szükséges, mert a program bezárásával amúgy is felszabadulnak, de jól bevált dolog, ha odateszed. Főleg akkor is érdemes, hibakezelésnél a hibás ágnál, mert ha megszakad a program, akkor még maradhat bent szemét.

    (de majd kijavítják az okosabbak, ha nem így van. )

    Mutasd a teljes hozzászólást!
  • Sziasztok

    Azért írok inkább ide a tudástár helyett, mert elég összetett dologban kérném a segítségeteket. Szakdogámat kezdtem el írni (VBA alatt), és (bár tudtommal nem kekeckednek ilyeneken) szeretném minél precízebben megoldani, hogy később referenciaként is jobban funkcionáljon.

    A kérdésem az lenne, hogy hogyan lehet általában javítani egy kódon, mik azok, amiket egy kezdők elrontanak?
    fel is merült bennem pár kérdés:
    - ha csak pár string/int/alap típus "összefogása" kell nekem, akkor osztály vagy típus? egyáltalán mi a különbség azon kívül köztük, hogy osztályt lehet collection-be rakni, típust meg nem?
    - a makrók alapból törlik-e az osztályokat, vagy mindenképpen kell a végére minden objektumhoz egy set ... = nothing?
    - ha van a munkalapon egy listám amiből alkotok egy collection-t (így ugyebár a collection(1) = cells(1,1)), akkor ciklussal keressem, vagy a beépített excel függvények a gyorsabbak?
    - van-e különbség for, for each, while ciklus között?

    Meg hasonlóak, valami könyvet, vagy google keresőszavakat is szívesen vennék, hogy fejleszthessem a tudásomat (magyarnak jobban örülnék, mert ez nem éppen olyan téma, aminél erős az angolom).
    Illetve bármi más kezdők által gyakran hibára való felhívást szívesen vennék (nyelvtől függetlenül is akár), mert elég kényes vagyok a kódjaimra, és nem akarok egy összehányt kódot kiadni a kezemből.
    Köszönöm előre is
    Mutasd a teljes hozzászólást!
abcd