Office Guru

Egy egyszerű csapda a For ciklusban, amibe könnyedén belefuthatunk

2016. szeptember 02. - Office Guru

Bármilyen apró VBA-kódunk megírása során kétfajta hibát követhetünk el, egyrészt véthetünk szintaktikai (alaki) hibát, amikor a program nem felel meg a VBA szabályainak, illetve véthetünk szemantikai (tartalmi) hibát, amikor a program lefut, de rossz eredménnyel, vagy futás közben le is áll. Ezeknek vannak könnyen és kevésbé könnyen felismerhető előfordulásai, a mai posztban megnézünk egy roppant egyszerű kis kódszeletet, az általa tartalmazott hibát és persze a megoldásról is ejtünk szót.

Adott a következő roppant egyszerű kis tábla (a példa egyszerűsége ne tévesszen meg minket, sokkal komolyabb tábláknál és programoknál is belefuthatunk ebbe a hibába):

debug1.jpgValamilyen komplexebb programunkba beépítve vagy akár önmagában is azt szeretnénk elérni, hogy ha a felhasználó megad egy cellaértéket és megnyom egy gombot, akkor a megadott cellaértéknek megfelelő sorok kerüljenek törlésre.

Erre elkészítjük a következő egyszerű kis kódot:

Sub sortorles()
Dim Tartomany As Range
Set Tartomany = ActiveSheet.Range("A1:A10")
For Each cell In Tartomany
If cell.Value = "Haza" Then
cell.EntireRow.Delete
End If
Next cell
End Sub

debug2.jpgBoldogok is vagyunk, ott van szépen a For ciklusunk, ami a megadott tartomány összes celláján fog végigmenni és megnézi a feltétel teljesülését majd ennek megfelelően jár el, ha szükséges - az összes soron már nem megyek végig, az eddigi posztok alapján feltételezem, hogy ez már senkinek nem okoz komoly problémát. Futtassuk hát le! Előzetes becslésünk alapján a példánál azt várnánk, hogy maradjon két darab Otthon értékünk, semmi más, ehelyett a következőt kapjuk:

debug3.jpgVajon hol mehettünk félre? Hiszen szépen lefutott a program, nem is dobott hibát, mégsem az elvárt eredményt kaptuk. Azért a probléma önmagában egy tapasztalt VBA-felhasználónak nem okoz gondot, sőt valószínűleg elő sem idézi, de ettől függetlenül érdemes megvizsgálni ezt a kérdést.

A probléma a For ciklus "előrehaladásában" rejlik, ugyanis a ciklus mindig csak a következő sort vizsgálja meg a feltételnek megfelelően, tehát ha a kettes sort törölte, akkor újra már nem vizsgálja meg, miközben pedig a törlés miatt a hármas sorunk beugrott a kettes helyére és ez a sor vizsgálatlan maradt.

Jópár különféle megoldás van ennek a problémának a kiküszöbölésére, talán a legegyszerűbb, ha nem is megyünk bele ebbe a ciklusba, hanem egyszerűen tartományként meghatározzuk a törlendő cellákat és úgy hajtjuk végre azt a lépést, akár ki is színezhetjük a cellák hátterét, majd szín alapján törölhetünk, de akár csinálhatjuk azt is, hogy a For ciklust visszafelé futtatjuk (hiszen akkor nem lesz "előrehaladási" probléma), mondjuk így:

Sub sortorles()
Dim Tartomany As Range
Set Tartomany = ActiveSheet.Range("A1:A10")
For i = 10 To 1 Step -1
If ActiveSheet.Cells(i, 1) = "Haza" Then
ActiveSheet.Cells(i, 1).EntireRow.Delete
End If
Next i
End Sub

debug4.jpg

debug5.jpg

Ez sem túl bonyolult kód, ahogy látható, annyit változtattunk az előzőhöz képest, hogy az aktív sheetünk első oszlopában indulunk el a 10. cellától egyesével visszafelé az első celláig, és minden esetben megvizsgáljuk a ciklus éppen aktív cellájában a feltétel teljesülését majd ennek megfelelően törlünk.

Mondjuk ez 50 ezer sornál már nem lesz annyira szupergyors, úgyhogy inkább váltsunk ilyen esetekben egy másik megoldásra. Ötletek, javaslatok jöhetnek kommentben vagy akár Facebookon is.

Módszerek Pivot-táblák Értékoszlopaiban való szűrésre

Teljesen átlagos Pivot-táblákkal való ügyködéseink során könnyedén belefuthatunk olyan kérdésekbe, amelyeknek válaszai elsőre triviálisnak tűnhetnek, pedig mégsem azok. Ilyen például az itt már korábban megvitatott Pivot-tábla alapbeállítás, azaz értékeink alapból történő összegzése, amelyre nem is sikerült túl jó megoldást találnunk (itt az eredeti poszt) vagy itt van a mai posztunk témája, a Pivot-táblánk Value oszlopában való szűrés kérdése.

Adott tehát egy adathalmazunk:

ballada1.jpgEbből készítsünk most egy egyszerű Pivot-táblát, semmi extra, csak amit feltehetően rendszeresen csinálunk:

ballada2.jpgPéldánkban most nincs nagy jelentősége a Pivot-felépítésének, egyszerűen szükségünk van egy Value oszlopra is, ami jelen esetben az elköltött ausztrál dollárok értéke lesz falvakra lebontva:

ballada3.jpgÉs itt jön a poszt tényleges kérdése, azaz hogyan tudunk a Pivotban úgy szűrni, hogy kilistázzuk a 215-nél nagyobb értékeket például. A Pivot alapból Value oszlopban nem kínál fel nekünk szűrési lehetőséget:

ballada4.jpgA Ribbonunk Data fülének Sort & Filter szekciójából tudunk szűrőt varázsolni a Value oszlopra is és így simán elérhetjük azt, amit akarunk:

ballada5.jpgItt már mehet a szűrés a megszokott módon, kisebb, nagyobb, átlag stb. feltételek mellett listázhatjuk értékeinket.

ballada6.jpgViszont érdemes próbálgatni a Pivot által alapból felkínált szűrőre kattintva a Value Filters opciót is, mert ennek segítségével a Row címkékhez tartozó értékekre vonatkozó szűréseket tudunk beépíteni:

ballada7.jpgCsak egy a sok példából, a Value Filters segítségével könnyedén tudunk kisebb-nagyobb szűréseket végrehajtani a Value oszlop tartalmán, ami jelen példánk esetében talán nem egyértelműen mutatja meg hasznosságát, hiszen most Dátum szerint már csoportosítunk (Group) egyet a Pivotban és így a Subtotalra megy a szűrésünk, de ha nem csoportosított oszlopon szűrünk, akkor simán megy soronként a dolog. Ráadásul működik count és sum együttes használata esetén is (mi választhatjuk ki, mire szűrünk), sőt Column Labelre is rá tudjuk dobni, akkor pedig függőleges Total értékekre is szűrhetünk.

ballada8.jpg

Pie of Pie diagram alapfelhasználása és további trükközési lehetőségei

Valószínűleg annak ellenére, hogy tisztában vannak a kördiagramok hasznossági fokával, elég sokan ismerik a pie of pie kördiagramos megoldást, ami ugyebár egy kördiagramunk egyik cikkét segít tovább részletezni egy másik körrel, ahogy azt a következő példán is meg fogom mutatni.

Adott a következő két táblázat:

szaz1.jpgEzen az egyszerű példán nagyjából annyit szeretnénk elérni, hogy legyen egy kördiagramunk két szelettel, az egyik a belföldet, a másik a külföldet mutatná, majd a külföldi cikkely egyértelmű kapcsolattal további bontásra kerülne országokra.

Első körben ehhez alakítsuk kicsit át a két táblát ilyen formára:

szaz2.jpgAhogy látható, a külföldi 4%-ot a megfelelő arányban szétdobáltuk, de még mindig százalékos formátumban, azaz mondjuk Ausztria nem 20%-kal került kimutatásra, hanem az eredeti 4% ötödével.

Innen pedig már egyszerű lépés jön:

szaz3.jpgA Ribbonunk Insert füle alatt található Charts szekció kördiagram ikonjára kattintva válasszunk ki egy Pie of Pie chartot, aztán formázzuk olyanra, amilyenek az igényeink.

A legfontosabb beállításokat a diagramra való kattintás után a jobb oldalon érhetjük el, itt tudjuk beállítani, hogy mi alapján ossza tovább a második diagramra az értékeinket (határértéket is tudunk beállítani, hogy milyen érték alatt kerüljenek át az alábontások a második körre) és méretezni is tudjuk értelemszerűen a második, kisebb körünket.

szaz4.jpgEzzel tehát meg is lennénk, de hangsúlyozni kell, hogy ahogy minden kördiagram esetén, úgy most is igaz, hogy a hasznossági fok csak nagyon kevés körszelet esetén jelentősebb, komolyabb chartok vagy táblák esetén mindenképpen célszerű oszlopdiagramra váltani.

De más célokra is felhasználhatjuk a Pie of Pie típusú kördiagramokat, méghozzá komplexebb kördiagramjaink egyszerűsítésére. Például nézzük a következő chartot:

szaz5.jpgTekintsünk most el attól, hogy lehetne ezt másképp is, a lényeg, hogy van egy szinte átláthatatlan kördiagramunk, ahol ráadásul még az értékek között is jelentős szórás áll fenn. Ennek tisztítására is felhasználhatjuk a Pie of Pie megoldást, méghozzá nagyjából úgy, hogy csinálunk a táblánkból először egy Pie of Pie diagramot, csak a kis értékeket megjelenítő másik kört elrejtjük és helyette egy összesített, EGYÉB kategória alatt futtatjuk végig a kis értékeket.

Elsőként tehát csináljunk egy Pie of Pie diagramot az eredeti táblánkból:

szaz6.jpgKövetkező lépésként egyesével végigkattintgatjuk a kis kördiagramunk cikkelyeit majd a kitöltést (FILL) és a keretet (BORDER) NONE-ra állítjuk, ezzel szépen el is tűnik majd a második diagram, de az első kördiagramban az apró értékek egyetlen cikkelybe tömörülnek továbbra is.

szaz7.jpgEzután már nem kell mást tennünk, mint egyrészt a jelenleg már nem látszó második kördiagram méretét lekicsinyítenünk, hogy az első diagram középre kerüljön, másrészt a Legendet kell megformáznunk még egy kicsit, méghozzá úgy, hogy a már nem látható körcikkelyekre mutató címkéket eltávolítjuk és az apró értékeket tömörítő körcikkelyhez hozzáadunk egy, mondjuk "Other" névre hallgató címkét.

szaz8.jpgDe hát ez a felhasználási mód nem igazán a legegyszerűbb módja ennek a megjelenítésnek, hiszen jóval egyszerűbb lett volna egy új táblázatot készíteni és "Other" sorba tömöríteni a megfelelő értékeket, deóe ettől függetlenül a lehetőségeinket próbálgatni tökéletes.

Cellák színének felhasználása formulákban

Annak ellenére, hogy egyes Olvasói kérdések feldolgozásával és megválaszolásával még el vagyok maradva, a mai posztban egy egészen friss kérdésre próbálom megadni a választ vagyis inkább az egyik lehetséges választ.

Nem túlságosan nehéz elmagyarázni, hogy mi a felvetés, azt szeretnénk elérni a lenti példatáblában, hogy azon cella értéke, amelyet megjelölünk valamilyen színnel, jelenjen meg a Megjelölt összeg névre hallgató oszlop adott celláiban.

Kiinduló tábla:

cuba1.jpgElérendő állapot:

cuba2.jpgSajnálatos módon az általam ismert lehetséges megoldások egyikével sem lehet ezt csak formulából megoldani, mindenképpen szükség van VBA-ra, bár túl hosszú kódra nem kell gondolnunk, szimplán csak a meghatározott cellánk színét szeretnénk visszanyerni.

Ehhez egy funkciót fogunk létrehozni VBA-editorban, úgyhogy most ALT+F11 lenyomásával menjünk is át arra a felületre. Mivel funkcióról van szó, itt hozzunk létre egy új Modult:

cuba3.jpgEbben a modulban fogjuk felépíteni a kis kódunkat, ami három részből áll. Először is nevezzük el a funkciónkat valamilyen néven és adjunk neki paramétereket is - a név segítségével tudjuk a formulák közül előszedni ezt a funkciót, a paraméterek pedig a formulák többségénél megszokott inputokat jelentik.

A mi esetünkben legyen a funkció neve CellColor, paramétere pedig a cella, amelynek színére vagyunk kíváncsiak:

cuba4.jpgAnnak érdekében, hogy legalább akkor újrakalkulálódjon a funkciónk, ha bármilyen cella értéke megváltozik a munkalapon vagy a munkafüzetben, esetleg újra megnyitjuk a fájlunkat, be kell szúrnunk egy Application.Volatile névre hallgató metódust, amelynek segítségével ezt elérhetjük. Fontos kiemelni, hogy még ez sem garantálja a tökéletes megoldást, hiszen ha majd csak szimplán színt változtatunk bármi egyéb módosítása nélkül, akkor még nem változik meg az eredményünk!

Biztonsági okokból sokan szoktak alkalmazni egy olyan kitételt, hogy ha esetleg tartományt adna meg a felhasználó akkor álljon le a funkció és kizárólag csak cellára legyen érvényes az elemzés. Ezt egy sima IF segítségével érjük el, azaz ha a megadott Range celláinak száma nagyobb mint 1, álljon le a funkció:

If r.Cells.Count > 1 Then Exit Function

Utolsó lépésünk pedig értelemszerűen a cella színének kinyerése, ehhez könnyedén használjuk csak fel a Microsoft oldalán is szépen listázott és bemutatott Interior.ColorIndex objektumtulajdonságot, ami az Interior objektum (a cella színe, pl. a Font objektum a Font színe lenne) színét fogja visszaadni eredményként.

CellColor = r.Interior.ColorIndex

cuba5.jpgEzután pedig ezt a formulát könnyedén felhasználhatjuk egy elemzésre, most már az eredeti munkalapon. Többféle megoldást el bírok képzelni, de a mostani példánál én három darab IF függvényt fogok CellColor funkcióval együtt egybeágyazni, hogy elérjem a kívánt eredményt:

=IF(CellColor(E4)>0,E4,IF(CellColor(F4)>0,F4,IF(CellColor(G4)>0,G4,"")))

Azaz megnézzük, hogy az első cella színkódja nagyobb-e mint nulla (-4142 a "színnélküliséget" jelenti, de akár nullára is írhatjuk ezt a feltételt), ha igen, akkor az első cella értékét adja vissza, ha nem nagyobb mint nulla, tehát nincs színe, akkor nézze meg a következő cellát a sorban, majd a következőt. Ezzel a megoldással én feltételeztem azt, hogy nem lesz több színes cella a sorban, de igazából azt már nem nagy kunszt beletenni.

cuba6.jpgAhogy korábban, minden építő jellegű kritikának, ötletnek, javaslatnak és főként más megoldásnak nagyon örülök!

Function CellColor(r As Range)
Application.Volatile
If r.Cells.Count > 1 Then Exit Function
CellColor = r.Interior.ColorIndex
End Function

Folytatódik a SUMPRODUCT-kaland: kizárás egy SUM függvényből

A következő posztban egy Exceles, feltételek alapján történő összegzés problémakörét fogjuk körbejárni egy lehetséges megoldás alapján és remélhetőleg ez sokak számára segítség lehet majd, hiszen a most felvázolandó kérdéssel sokan-sokszor szembesülhetnek a legegyszerűbb napi Exceles feladatok során is.

Adott a következő két táblázat, amely komolyabb leírás nélkül is magáért beszél:

sumo0.jpgA célunk egyetlen képlettel annak elérése, hogy a Nem összegzendő táblázatban szereplő települések nélkül összegezzük a teljes táblánk értékeit. Ez tipikusan az a probléma, amelyre rengeteg megoldás létezik, nagyon favágó módszerrel készíthetünk például egy hatalmas, IF és SUM függvények egymásba ágyazásából álló formulát, de nyomhatunk egy PIVOT-Slicer megoldást is, kissé manuálisabb SUMIF felhasználás is szóba jöhet, de még akár a DSUM formulával is próbálkozhatunk. Ettől függetlenül a mostani megoldásban maradunk két függvénynél, az egyik az egyértelműen szükséges SUM, a másik pedig az Excel sokat megélt, titkos szuperfegyvere, a SUMPRODUCT.

Ennek a válasznak a kulcsa abban a logikában rejlik, hogy nem kizárni akarunk bizonyos településeket az összegzésünkből, hanem a teljes szummánkból vonjuk ki a Nem összegzendő települések értékének szummáját. Azaz a formulánk első része kérdés nélkül:

=SUM($E$3:$E$17)

sumo1.jpgNa de hogyan összesítsük a kizárandó településeink értékeit? Ehhez hívjuk segítségül a COUNTIFS függvényt első körben, amely egy megadott tartományban megadja, hogy hány, az adott feltételnek megfelelő cellánk van, de ellentétben a COUNTIF formulával, ez több feltétel és tartomány elemzésére is képes.

Például a következő képlet megadja, hogy összegeink között mennyi 200-nál kisebb és 195-nél nagyobb érték található:

=COUNTIFS(E3:E17,"<200",E3:E17,">195")

Ha most ezt a mi táblánkra átvetítjük és beleerőltetjük egy cellába, hogy számolja meg településeink között hány olyan van, ami Nem összegzendő, akkor értelemszerűen a lenti képen látható függvénynek nulla lesz az eredménye:

sumo2.jpgHiszen nincs olyan cella, ami megfelelne mindhárom feltételnek. De még ne temessük a COUNTIFS-t, hiszen ezt a nulla szám ellenére még felhasználhatjuk egy SUMPRODUCT egyik paramétereként, mert azt már az itteni tucatnyi poszt után tudhatjuk, hogy ez a rendkívül sokoldalú tömbfüggvény (itt bővebben róla) összehasonlítást és ez alapján történő összegzést is lehetővé tesz.

Azaz egyszerűen megfogjuk az előző képen felvázolt COUNTIFS függvényünket, beágyazzuk egy SUMPRODUCT-ba, mint a formula első paramétereként meghivatkozott tömb, majd a formula második paramétereként meghivatkozzuk az összegeinket a teljes táblában, így pedig szépen a SUMPRODUCT azt fogja nekünk kiszámolni, hogy mennyi a COUNTIFS függvényrészben meghatározott feltételeknek megfelelő cellákhoz tartozó összeg.

=SUMPRODUCT(COUNTIFS(H4:H6,$D$3:$D$17),$E$3:$E$17)

sumo3.jpg

sumo4.jpgEzután meg már csak ki kell vonnunk a legelső SUM-ból a az előbbi SUMPRODUCT-ot és meg is kapjuk az eredményünket:

=SUM($E$3:$E$17)-SUMPRODUCT(COUNTIFS($H$4:$H$6,$D$3:$D$17),$E$3:$E$17)

sumo5.jpgPersze ezt a hibák elkerülése érdekében átalakíthatjuk elnevezett tartományokra is, sokkal jobban szétszedhetjük és nagyobb táblákra optimalizálhatjuk a képletet, de alapvetően kiindulópontnak tökéletes. De jöhetnek kommentben más megoldások is, hiszen nekem sem a fenti volt az első, ami eszembe jutott ennél a kérdésnél, másrészt nem is biztos, hogy ez a legegyszerűbb válasz.

SharePoint listák másolgatása balról-jobbra

Folytatva SharePointos elmélkedéseimet, a mai posztban arra fogunk egy gyors, csattanós választ adni, hogyan lehet különféle listáinkat egy az egyben másolgatni különböző SP-oldalaink között, anélkül, hogy bármit veszítenénk a tartalomból. Ennek többféle oka is lehet, például archiválni szeretnénk az eddigieket vagy éppen más-más célközönséggel akarjuk majd folytatni a munkát a későbbiekben.

A lényeg, hogy szerveroldalról is elérhető a szükséges eredmény, de egyszerűbb felhasználói oldalról is végrehajtható a másolás, amelynek legelső lépéséből már valószínűleg rutinosabb SP-felhasználók tudni is fogják, hogy mit fogunk tenni.

Első körben az érintett listánkon állva, a Ribbonon a List fül alatt a List Settings menüpontot válasszuk ki, majd a megnyíló beállítási lehetőségek ablakában válasszuk a Save list as template opciót:

una0.bmpEzután értelemszerűen következnek a template mentésének beállításai, úgy mint név, fájlnév és leírás, illetve a legfontosabb lehetőség, az Include Content opció:

una1.bmpEzt szépen leokézzuk és a következő ablakkal szembesülünk:

una11.jpgAz előbb megadott néven lementésre került a template-ünk az adott oldal List template könyvtárába, amely könyvtárat a megjelölt linken el is érhetünk és tegyünk is így, hiszen abból a könyvtárból fogjuk majd saját gépünkre lementeni ezt a templatet.

Ahogy a kis képen is látható, ebben a List template könyvtárban egyszerűen csak kijelöljük az újonnan létrehozott fájlunkat, majd a Download a Copy opciót választjuk és lementjük a gépünkre:

una12.jpgHol is tartunk most a folyamatban? Fogtunk egy létező SP-listánkat, majd tartalommal együtt templateként lementettük valahova a saját gépünkre.

A továbbiak már egyszerűen kitalálhatóak, hiszen most jön az a lépés, hogy átmegyünk a másik SP-oldalunkra, ahol a listának a másolatát létre akarjuk hozni és feltöltjük a korábban lementett templatet a List template librarybe.

Ezt a könyvtárat a Site Actions -> Site Settings menüből érjük el a Galleries menüpont alatt.

una3.bmpBelépve a könyvtárba, egyszerűen csak Upload Documenttel feltöltjük a kész listánkat:

una4.bmpEzután pedig hozzunk létre egy új listát az oldalon, a lista template-jeként válasszuk ki a korábban feltöltöttet és láss csodát, kész is vagyunk.

Kényszerítsük a VLOOKUP függvényt a megfelelő formátum kiválasztására

Aki már legalább egy-két alkalommal foglalkozott a VLOOKUP függvénnyel feladatai során, az biztos, hogy találkozott azzal a problémával, amikor a formula minden látszólagos egyezés ellenére sem hozza ki a várt eredményt, hanem egy csúfos #N/A kíséretében újbóli nekifutásra késztet bennünket.

Lássuk ezt egy kis példán. Adott a következő táblázat:

vlookup1_1.jpgCsináljunk egy egyszerű VLOOKUP függvényt az Azonosító mezőnk alapján a Település felkeresésére:

vlookup2_1.jpgÉs lám, ott is a dühítő kis #N/A.

vlookup3_1.jpgPersze erre nagyjából szinte mindenki azonnal rávágja, hogy formátumprobléma van, hiszen ahogy a kis zöld jelzésből látszik is az Azonosító mezőnk sarkában, ebben a mezőben Textként tárolunk számot, míg a táblánkban az azonosító számok Number formátumúak.

Gyorsan rohanunk is a Home ribbonfül Number szekciójában található formátum legördülő mezőre, hogy átállítsuk az Azonosító mezőnk formátumát Numberre:

vlookup4_1.jpgDe hiába, nem történt semmi. Akkor mi is a probléma? Ha most viszont belekattintunk a hármas szám cellájába, akkor a formátum azonnal átvált ténylegesen Numberre és máris jó lesz a VLOOKUPunk eredménye:

vlookup5_1.jpgNa de ez most csak egyetlen cella, mi a helyzet ha több ezer soros tábláról van szó? Nem kattintgathatunk bele minden egyes cellába, hiszen arra senkinek nincs ideje.

Elég ha simán rákattintunk a kis zöld jelre a sarokban és így konvertáljuk át számra a cellánk formátumát, amit aztán sokkal többnél is meg tudunk csinálni.

vlookup6_1.jpgKicsivel másabb a helyzet, ha fordítva nem működik a függvény, azaz a Lookup Value szám, a táblában szereplő azonosítók viszont Text formátumúak. Lásd lentebb:

vlookup8.jpgA sima átállítgatás itt még annyira sem működik, mint a másik esetben, ezért inkább megpróbáljuk a VLOOKUP formulát arra kényszeríteni, hogy már automatikusan alakítsa át a Lookup Valuet Text formátumra. Ezt pedig úgy tesszük meg, hogy a formulába, a Lookup Value mögé hozzáfűzünk egy szóközt, ezzel "kényszerítve" a kódot a bekeresendő érték textté való alakítására.

vlookup9.jpg

Fájlbeolvastatás a felhasználóval VBA segítségével

A felmerült kérdések okán még mindig parkolópályán van a kis makrós sorozatunk következő része, de a mai posztban is VBA-val fogunk foglalkozni, méghozzá egy olyan megoldással, amely nagyjából a makrók jelentős százalékában felhasználható funkcionalitás.

A valószínűleg sokak által már sok makróban látott fájlkiválasztós, felugrós kis ablakról van szó, amellyel mi választhatjuk ki a foldereinkből azt a fájlt, amit később a makrónk majd átalakít, továbbküld, feldolgoz stb.

file1.jpgA megoldás nem túl komplex és nem is igényel iszonyú nagy tudást sem, hiszen mindössze az Application.GetOpenFilename metódus ismerete (megspékelve persze azért alapvető VBA ismeretekkel is) elégséges ahhoz, hogy egy ilyen felugró ablakot összehozzunk.

Olyannyira, hogy az én következő 10 soros kódom akár fele hosszúságúra is redukálható lenne, de azért ennyire ne minimalizáljunk most. Szóval ALT+F11 segítségével szépen átlépünk a Visual Basic Editorba, majd elkezdjük szépen felépíteni a kódot.

Két változót fogunk most definiálni, FileName elnevezéssel egy Variant típusút (ami nagyjából bármi lehet tehát) és egyet Response néven Integer típussal, amit arra fogunk használni, hogy valamiféle választ azért adjunk a felhasználónak, ha esetleg nem választott ki egyetlen fájlt sem:

file2.jpgKövetkező lépésként aztán szépen meghatározzuk egy ChDrive utasítás segítségével az alapértelmezett meghajtónkat illetve könyvtárunkat:

ChDrive "C:\Temp"

Ezután pedig következik maga a kis kód lelke, azaz FileName változónk vegye fel az Application.GetOpenFilename utasítás által megadott fájlnevet. A GetOpenFilename metódusnak van öt lehetséges paramétere, a Title a felugró kis ablak fejlécének szövegét határozza meg, FileFilter és FilterIndex segítségével azt tudjuk definiálni, hogy mi legyen az alapértelmezett szűrés a fájlokra az adott könyvtárban, MultiSelecttel pedig több fájlt is be tudunk olvastatni.

file3.jpg

Nem szükséges, de beépíthetünk egy apró kis feltételt arra vonatkozóan, hogy ha a user nem választ ki egyetlen fájlt sem, akkor kapjon erre vonatkozóan egy figyelmeztetést. Ez szépen leírva úgy nézne ki, hogy ha a FileName = False (tehát üres), akkor a Response változónk vegyen fel egy MsgBox üzenetet értékként. És kész is vagyunk.

file4.jpgSzövegként:

Sub Felugroablak()
Dim FileName As Variant
Dim Response As Integer
ChDrive "C:\Temp"
FileName = Application.GetOpenFilename(Title:="Válaszd ki a fájlt!")
If FileName = False Then
Response = MsgBox("Nem választottál ki fájlt!", vbOKOnly & vbCritical, "Hiba")
Exit Sub
End If
End Sub

Frusztráló beillesztési probléma Wordben

A következő posztban egy Excelt és Wordot is érintő, roppantul idegesítő problémáról lesz szó, amelyet valószínűleg mindenki tapasztalt már, aki sűrűn használ beágyazott Excel-fájlokat (vagy más beágyazásokat) Word dokumentumokban. A szerencsésebb helyzet az, amikor saját maga által készített fájlokról van szó.

Adott egy egyszerű Word-fájl, amelybe be szeretnénk ágyazni egy Excel-fájlt. Tehetjük ezt úgy is, hogy az Excelben az adatokat kijelöljük majd Copy után Paste Speciallel objektumként beillesztjük, de szimplán Wordből az Insert ribbonfül alatt a Text szekció Objektum parancsát használjuk.

object1.jpgAkárhogy is tesszük, Word dokumentumunk lementése majd újbóli megnyitása után előfordulhat, hogy hiába próbáljuk megnyitni az Excel doksit, a következő hibaüzenettel szembesülünk:

object.bmp

Fontos megjegyezni, hogy ez csak az én példámban Excel-csatolmány, ugyanez reprodukálható például Visio vagy PowerPoint fájlok esetén is. Az alapvetően legradikálisabbnak számító egyik megoldás erre a problémára az lehet, ha a fájlok megnyitása előtt Excelben az összes COM (Component Object Model) add-int kikapcsoljuk. Nagyon röviden, ezek az add-inek az Excel funkcióinak kibővítését támogatják, például egy specifikus formra való kattintással.

Ezeket a File menü - Options almenüjéből érhetjük el, ahol a felugró Excel Options ablakban az Add-Ins fülre kell kattintanunk.

object2.jpgEnnek az ablaknak az alján válasszuk a Manage Add-insnél a COM Add-ineket:

object3.jpgMajd kapcsoljunk ki mindent:

object4.jpgSokan kizárólag a PowerPivot Add-in kikapcsolásában hisznek, de az összes add-in kikapcsolása alapvetően a biztos, ám radikális út. Viszont jómagam tudtam olyan helyzetet reprodukálni, amelyben ez a fentebb felvázolt megoldás sem segített, ott egyszerűen a Microsoft Office bezárása után a csatolmány újrabeillesztése segített csak.

Ettől függetlenül elég kacifántos kis problémával állunk szemben, szóval ha valakinek van más ötlete/javaslata a fenti hibaüzenet egyszerű felszámolására, az jelezze.

Filterek alkalmazása slicereken Excelben

Valószínűleg a legtöbb látogató tisztában van az Excelben a slicerek jelentőségével, azok hasznosságával, így egyszerű használatuk bemutatásával nincs is igazán értelme vesződni, amiért ezt most mégis megteszem röviden, az az a tény, hogy még többet ki lehet ebből hozni annál, mint ahogy sejtenénk.

A következő hosszú, az összes magyar települést tartalmazó listát fogjuk példaként felhasználni:

slicer1.jpgTehetnék bele több oszlopot is, de a lényeg megértéséhez alapvetően elégséges lesz ennyi. Szóval első lépésként készítünk egy egyszerű Pivot-táblát:

slicer2.jpgErre aztán szúrjunk be egy Slicert az Insert ribbonfül Filters szekciójában található Slicer menüpontból:

slicer3.jpgAhogy látjuk, szépen meg is van az eredményünk, de ez a slicer már önmagában is rendkívül hosszú, nagyjából semmit nem nyertünk vele:

slicer4.jpg

slicer5.jpgDe ne essünk kétségbe, van arra mód, hogy egy slicerre egy másik slicert ráhúzva, kialakítsunk egy "slicer-szűrőt".

Ehhez lépjünk kicsit vissza az eredeti táblához, szúrjunk be egy oszlopot, amelybe a Település oszlopunk első betűjét tegyük - erre használhatunk többféle függvényt, én most a MID formulát alkalmaztam.

slicer6.jpgEzután visszalépve a Pivothoz, a Pivottable Tools Analyze ribbonfül alatt válasszuk a Change Data Source funkciót és terjesszük ki a pivotunk forrásadatának területét:

slicer7.jpg

slicer8.jpgEzután pedig a Slicer menüpontból szúrjunk be egy Slicert a kezdőbetűkre is:

slicer9.jpgAz eredmény magáért beszél, a kezdőbetűkre kattintva a Település slicer már magától szűrésre kerül, tehát jóval kisebb listával kell dolgoznunk:

slicer10.jpg

slicer11.jpgÉrtelemszerűen tekintsünk el most példám egyszerűségétől, a valódi értékét ennek a megoldásnak jóval komplikáltabb táblák esetén tudjuk értékelni igazán.

 

süti beállítások módosítása
Mobil