Az „Excel” fórum célja, hogy keretet adjon az Excel felhasználók széles táborának tapasztalataik megosztására, és lehetőséget a segítséget kérőknek. Az alábbi összefoglaló azért készült, hogy segítse a helyes kérdésfeltevést.
– Írd le szabatosan a problémát. Úgy fogalmazz, hogy ne csak te magad, de a szakértő is megértse, mire szeretnél választ kapni.
– Írd le, hogy milyen verziójú Excellel dolgozol. (Vagy ha nem – ill. nem csak – Excel, akkor micsoda?)
– Írd le, hogy milyen úton indultál el, és hol akadtál el rajta.
– A kérdés megértése szempontjából sokat segíthet, ha feltölteszt egy képet, amin látszik, hogy mit szeretnél, vagy illusztrálja azt.
– Még jobb, ha feltöltesz egy minta munkafüzetet valahová (pl. data.hu). Feltöltés előtt távolítsd el belőle a nem publikus adatokat.
– Ha a feladat jellege olyan, célszerű az "előtte" és "utána" állapotokat bemutatni. (Miből kellene csinálni mit?)
– Ha VBA kódon kell javítani, másold be a releváns kódrészt. Rövid kód mehet hozzászólásba, hosszú kód inkább ide: http://pastebin.com/
– Ha valami nem úgy működik, ahogy kellene, add meg a rendellenes viselkedés jellemzőit, a hibaüzenetet, és a hibát okozó programsort.
Lefuttattam a 791-es hsz-ben látható adatokon, kb. 75 perc alatt 130874875 lépésből az jött ki, hogy nincs egyezés. Ha ez a teljes adatsorod volt, akkor vagy tényleg nincs egyezés, vagy nem jó a program...
Feltöltöttem két képet. Igyekszem elmondani, mit szeretnék. Az 1-es munkalapon van egy táblázat, benne számlák. A második munkalapon pedig ki lehet íratni, hogy adott időszakban mennyi lett kifizetve. Amit szeretnék az az, hogy legyen egy gomb, aminek a klikk eseménye (remélem jól írom) az, hogy átmásolja és beilleszti azokat a sorokat, amelyek tartalmazzák az adott időszak számláit (és így lehetne látni, hogy miből is áll össze a szumma összeg). A mellékelt képen a gomb még semmit nem csinál és a számlákat tartalmazó sorokat is én másoltam oda, hogy lehessen látni mit is szeretnék. Előre is köszönöm, ha tudsz/tudtok adni egy olyan kódot, amit hozzá tudnék rendelni a gombhoz.
Sub kombi() Dim Rng As Range, hit As Range Dim ix As Long, Lvl As Long, Cnt As Long, iter As Long Dim LvlAct, LvlSel Dim BaseSum As Double, TestSum As Double Dim Dest As Double, small_ix As Double
Dest = Range("c3") Set Rng = Range("A3:A29") Cnt = Rng.Cells.Count ReDim LvlAct(1 To Cnt) ReDim LvlSel(1 To Cnt)
For ix = 1 To Cnt LvlAct(ix) = ix LvlSel(ix) = 0 Next
Lvl = 1 Do iter = iter + 1 Application.StatusBar = iter small_ix = Application.WorksheetFunction.Small(Rng, LvlAct(Lvl)) TestSum = BaseSum + small_ix If (Round(TestSum, 5) < Round(Dest, 5)) Then If LvlAct(Lvl) < Cnt Then LvlSel(Lvl) = small_ix BaseSum = BaseSum + LvlSel(Lvl) Lvl = Lvl + 1 LvlAct(Lvl) = LvlAct(Lvl - 1) + 1 ElseIf LvlAct(Lvl) = Cnt Then Lvl = Lvl - 1 BaseSum = BaseSum - LvlSel(Lvl) LvlAct(Lvl) = LvlAct(Lvl) + 1 LvlSel(Lvl) = 0 End If ElseIf (Round(TestSum, 5) > Round(Dest, 5)) Then Lvl = Lvl - 1 BaseSum = BaseSum - LvlSel(Lvl) LvlAct(Lvl) = LvlAct(Lvl) + 1 LvlSel(Lvl) = 0 ElseIf (Round(TestSum, 5) = Round(Dest, 5)) Then MsgBox "heuréka" For ix = 1 To Cnt If LvlSel(ix) = 0 Then Exit For Set hit = Rng.Find(what:=LvlSel(ix), lookat:=xlWhole, LookIn:=xlValues) If hit Is Nothing Then MsgBox "bibi van" Stop Else hit.Interior.ColorIndex = ix + 2 End If Next Set hit = Rng.Find(what:=small_ix, lookat:=xlWhole, LookIn:=xlValues) If hit Is Nothing Then MsgBox "bibi van" Stop Else hit.Interior.ColorIndex = ix + 2 End If Application.StatusBar = False Exit Sub End If Loop End Sub
Fordíts különös figyelmet a vastag betűkkel kiemelt részekre:
1) a C3 cellahivatkozás a keresett összeg, az A3:A29 a lehetséges értékek tartománya. Ezeket módosítsd, ahogy neked kell.
2) a Round() függvény alkalmazását azért építettem be, mert a makró tesztelése során, tizedes tört értékek esetén rendszeresen előfordult, hogy amikor a program futása arra a pontra ér, hogy éppen a megfelelő számokat vizsgálja, és azok összegének meg kellene egyezni a keresett végösszeggel, mégsem egyeznek meg, hanem valahol a 10. tizedesjegy környékén eltérés van, és így a keresés eredménytelen lesz. Ha tudod, hogy az értékeid legfeljebb hány tizedesjegyet tartalmaznak, azt írd be a makróban az összes Round 2. paraméterének.
A makró a korábban említett Brute Force módszer kicsit intelligensebb változatát használja, tehát lényegében elkezdi sorra venni a lehetséges kombinációkat. Ez azt jelenti, hogy ha a bemeneti adatok száma néhánnyal megnő, akkor a futási idő akár nagyságrendet is emelkedhet. Érdemes tehát minden lehetséges módon lecsökkenteni a bemeneti adatok számát. (pl. számlák dátum szerinti szűrésével)
Ha a program nem talál egyezést, akkor hibaüzenettel fog leállni. Ha talál, akkor a megtalált értékek celláit különböző színekkel kifesti. Menet közben a Statusbar jelzi, hogy hányadik kombinációnál járunk. (Erre igazából nincs szükség, csak azért tettem bele, hogy lássuk, valamit csinál a program, és nem csak lefagyott az Excel.)
Természetesen, ha egy adott összeg több helyen is szerepel, akkor a program nem fogja tudni, hogy melyik utalás az igazi.
Egyéb apró hibák is lehetnek benne. Alkalmazása csak saját felelősségedre.
A kimutatásodban kattints az dátumot tartalmazó címre. Adatok/Tagolás és részletek/Csoportba foglalás. Add meg a kezdő, és záró dátumot, a felkínált listában jelöld be a napokat. A két szélső érték közötti napokat részletesen mutatja majd, a többit összefoglalva, pl. >2010.06.30.
Nos, az igazság az, hogy az exceles ismereteim nem túl szerteágazóak, így fogalmam sincs mi az a pivot. Azonban úgy érzem, érdemes utánaolvasnom a témának :) Ha nem boldogulok vele, akkor jövök és kérdezek. Köszönöm!
Felétételezem, hogy az általad írt "kimutatás" tényleg kimutatástábla (pivot)
Azért támadtak ezzel kapcsolatban kétségeim, mert ha az tényleg kimutatástábla, akkor miéárt nem húzkodod össze úgy, hogy a részleteket látni lehessen?
Forró délutánt kívánok a tisztelt Fórumozóknak! A következő probléma megoldásában kérném a segítségeteket. Adott két munkalap. Az egyiken táblázat, a másikon egy kimutatás. A táblázatban számlák szerepelnek a hozzájuk tartozó kifizetési időpontokkal. Azt már sikerült megoldani, hogy ha a kimutatás oldalon megadok egy idő intervallumot, akkor kiírja, hogy adott időszakban összesen mennyi lett kifizetve. Viszont szeretném ha nem csak egy szumma összeget lehetne látni, hanem azt is, milyen tételekből áll össze a végeredmény. Hogyan lehetne megoldani, hogy amikor megadom a –tól –ig dátumokat, akkor automatikusan felsorolja azokat a tételeket, amelyek az adott időszakban lettek fizetve? Előre is hálásan köszönöm a javaslatokat, ötleteket.
Madbazsi itt vagy még? Most jött egy ötletem, hogy hogy lehet esetleg egyszerűbben megoldani a problémát, lehet a jövőhét elején rá tudok szánni egy v. két órát a kisérletezgetésre.
Nem, mert a 11527-ben pont azt írod, hogy a feltételeket össze kell szorozni. Az én - nagy sokaságon futtatott - tesztjeim viszont azt mutatják, hogy jobb ha nem szorozgatunk a SUMPRODUCT-on belül, hanem odaadjuk neki a számolás minden elemét önálló vektorként.
Persze azt se felejtsük el, hogy 1 millió rekord esetén is csak tizedmásodpercekről beszélünk ;-)
Ha "csak" százezer sorból áll a tábla, akkor viszont hol a SUM hol a SUMPRODUCT a gyorsabb. 10 kisérletből: - a SUM gyorsabb 4 esetben (legnagyobb eltérés 14%) - pontosan azonos időt fut mindkét függvény 4 esetben - a SUMPRODUCT gyorsabb két esetben (7% legnagyobb eltérés).
Szóval úgy tűnik, hogy "kis" adattábláknál a SUM a jobb megoldás, nagy tábláknál a SUMPRODUCT annyira szétbontva amennyire csak lehet.
Persze jobb lett volna nagyobb mintán kisérletezni, úgy hogy csak egy oprendszer meg az excel fut, de sajnos a világ nem tökéletes :-)
Ha a SUMPRODUCT-ot szétbontottam úgy, hogy minden egyes elem önálló tömb a számolásban (vagyis nincs szorzásjel a SUMPRODUCT-on belül), akkor egy kicsit még gyorsabb lett.
A függvény amit futtattam: =SUMPRODUCT(--(YEAR(A2:A1000002)=2010), --(MONTH(A2:A1000002)>=7), --(MONTH(A2:A1000002)<=9), --(C2:C1000002="IGEN"),(B2:B1000002))