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.
Kösz! Múködik. De lenne 2 kérdésem: Miért kell a transpose? Ugyanis ha kiiktatom az Option Explicitet ami szükséges a makródhoz, akkor beolvassa a ranget anélkül is. Másrészt meg itt mit transzponál?
Ami neked kell az a "Data Validation" avagy adatérvényesítés. Ha ezt használod, be lehet állítani, hogy egy adott cella (vagy tartomány) csak egy lista értékeit vehesse fel. Nem ablakban ugrik fel, hanem lenyíló listából lehet választani.
1. jelöld ki azt a cellát/tartományt, ahol be akarod kapcsolni az adatérvényesítést
2. data / data validation (valami ilyesmi, csak angol 2003-as excelben tudom)
3. válaszd ki, hogy listából akarod, itt meg lehet adni, hogy az a lista hol van
4. OK
Kb. ennyi, itt van egy részletesebb magyar leírás:
A beírás korlátozását az Adatok->Érvényesítés menüpontban tudod elvégezni. Itt beállítod, hogy megengedve lista. Forrásnak csak azonos munkafüzetben levő adatokra hivatkozhatsz, de az adatok lehetnek másik munkalapon. A listát elnevezed, pl gyümölcsök.
Akkor a forrásban hivatkozhatsz így: =gyümölcsök.
Akár az egész oszlopot is kijelölheted érvényesítésre, akkor minden egyes cellára igaz lesz az, hogy csak a megadott értékek közül lehet választani.
Megpróbálom egy kicsit átfogalmazni a kérdésem, bár lehet hogy a válasz egyszerű, de mint mondtam, még kezdő vagyok! :)
Adott egy munkafüzet melyben az A oszlop soraiban ezek szerepelnek:
Alma Körte Banán Narancs
...és adott egy másik munkafüzet, ahol ha rákattintok az A oszlop bármelyik sorára, egy lista jelenik meg (Alma, Körte, Banán, Narancs) és csak ezek közül tudok választani, szóval mást beírni nem rudok!
Hogyan tudnám ezt megcsinálni? Ismétlem kezdő vagyok ezért kicsit a szájbarágósság segítene! Ha valakinek van erre kis ideje és segítene, annak nagyon hálás lennék!
Az első azért akad ki, mert egy statikus tömböt hozol létre, amihez egy lépésben nem lehet hozzárendelni egy Range objektumot - ha jól tudom. Amikor egy dinamikus tömbhöz rendelsz Range-et, akkor egy kétdimenziós tömb jön létre. Még akkor is, ha egy egy oszlopot vagy sort (ekkor az egyik dimenzió értéke mindig 1 lesz).
A második makróban dinamikus tömbként deklarálod a H() változót. Hiába a Redim, ez akkor is fel fogja venni bármilyen Range tartomány értékét.
A harmadik makróban egyenként adsz értéket egy egydimenziós statikus tömb elemeinek, ez működik.
@ Delila 22782 Ha kikommenteled azt a sort, ahol a változót hozod létre, akkor a következő sor:
tmb = Application.transpose(Range("h11:h19"))
fogja létrehozni a tmb változót Variantként - ami ugye bármi lehet - és ehhez is lehet bármilyen Range-et hozzárendelni. A transpose-ra nem is lenne szükség, ez is simán működne:
Sub tmbinput1() 'Dim tmb(8) tmb = Application.Range("h11:h19") End Sub
Ok, persze, ha végignézed a történetet, én is ezt javasoltam neki (scrollrow). A magyarázat is alapvetően nem neked szólt, csak kifejtettem a "tömörebb" megjegyzésedet.
Még nagyon kezdő vagyok az excel-ben és érdekel, ezért itthon próbálkozom! Lehet többször is teszek majd fel kérdéseket, persze csak akkor, ha nem gond!
Szóval a mai napi: Van egy munkalapom ahol szeretnék egy oszlopot úgy kialakítani, hogy a sorait ne szerkeszteni lehessen hanem rákattintva egy adott listát dob ki, amit egy másik munkalapon készítek el és csak ebből lehet kiválasztani az adott sor tartalmát!
PL: Munkalap1 / A3 ra katt és ott a választási lehetőségem 1, 5, 15, 55, stb... ! Munkalap2-őn az a oszlop számai ezek! Szóval semmi mást ne lehessen bevinni, csak az adott számokat! Van ilyenre lehetőségem?
Lenne egy fogós kérdésem: Az alábbi 3 makró közül a tmbinput1 miért akad ki "Can't assign to array" hibaüzenettel, amikor a többi meg tök normálisan lefut?
Sub tmbinput1() 'KIAKAD Dim tmb(8) tmb = Application.Range("h11:h19")
End Sub
Sub tmbinput2() 'OK Dim H() ReDim H(8) H = Application.Range("h11:h19") End Sub
Sub tmbinput3() 'OK
Dim H(8), k
For k = 0 To 8 H(k) = Range("h11").Offset(k, 0) Next k
Azt jelenti, hogy most az áttöltést után a tábla elsősorától látszik a táblázat már pedig normál szituációban a tábla végén folytatódik a munka ezért a betöltés után manuálisan scrollozni kell. Apró, bosszantó kényelmetlenség.
A tábla vége megtalálására a Te módszered jó.
Most a javitás után egy kicsit megbolondult és nem mindig pozicionál a tábla végére. Majd holnap végig bogarászom miért tesz ezt.
- Azt mondod, ez egy leegyszerűsített kód, ami nyilván azt jelenti, hogy nem látjuk a lényegi funkciót. Ha látnánk, akkor talán tudnánk egyszerűbb, jobb módszert javasolni, így azonban csak az eredetileg megkezdett irányba tartó utat tudjuk kiegyenesíteni. Ha az eleve rossz, úgy is marad, hiába igyekszünk.
- Elhangzott itt már több megoldásféle, amiket én nem próbáltam, de a beküldők bizonyára igen, és valószínűleg működnek. Ezért nekem most nem az a célom, hogy elmondjam a tuti módszert, hanem csak két hibás gyakorlatra hívnám fel a figyelmed.
Az egyik ez:
Range(c.Address).Select
Helyette így kellene (ha már szelektálni akarsz):
c.Select
Mert ugye a Select ebben az esetben a Range típusú objektum metódusa, tehát direktben ki lehet adni. A Te verziód először előállítja a c tartomány címét, aztán azt konvertálja vissza tartománnyá. Olyan, mintha egy számot először megszoroznál 6-tal, aztán elosztanád 2-vel, aztán elosztanád 3-mal, hogy elvégezhesd rajta a tulajdonképpeni műveletet.
A másik a Select használata, ami az esetek döntő többségében tök fölösleges, csak mindenki azért használja, mert a makrórögzítőből ez jön ki. (Ahogy Fferi is mondta.)
Valójában a Select használata pont olyan redundáns, mint a *6/2/3 a fenti példában. Aktiválsz egy cellát pusztán azért, hogy aztán az aktív cellán hajthass végre egy műveletet. Nem lenne egyszerűbb eleve az adott cellán végrehajtani azt a műveletet?
volna helyesebb, és beépítve az első észrevételemet, így volna a legjobb:
arrIndex(arrIndexAdress) = c.Row
Ismétlem, ez nem válasz a kérdésedre, hanem két kódolási típushibának a kijavítása.
A kérdésedre azt mondanám, hogy van a kódodban egy algoritmushiba is. A FindNext utasításnak közvetlenül a Loop While előtt kellene lennie. A jelenlegi formában az első találat feldolgozása kimarad, ehelyett rögtön ugrik a második találatra, és az elsőt csak akkor dolgozza fel, amikor újra megtalálta. Pedig akkor már nem kellene.
Bocsi a közbekotyogás miatt, de nem tömörebb, hanem egészen mást csinál.
smallscroll (metódus/method) az adott pozíciótól lép le,fel,jobbra,balra x egységet (sort, vagy oszlopot) - relatív a meghatározás, attól függ, honnan indulsz és a lépés nagyságát határozod meg az adott értékkel, ami akár negatív is lehet.
scrollrow, scrollcolumn (tulajdonság/property) konkrétan az adott sort, oszlopot helyezi az ablak legfelső sorába/bal oldalába, vagyis mindegy, hogy éppen hol van a pozíció az utasítás kiadásakor. (És vigyázni kell rá,hogy 0-nál nagyobb legyen a megadott érték.)
Hát igen, minden excell makróval foglalkozónak legelőször azt kellene megtanulni, hogyan távolítsa el a makrórögzítő select-jeit, mivel azok csak azért vannak benne, mert úgy van a természete megfogalmazva, hogy az objektumot először kijelöli selecttel.(Na meg a sok scroll is remek szokott lenni benne...)
De minden objektumra lehet közvetlenül hivatkozni, ráadásul az biztosan be is talál (már persze, ha nem írtam el a nevét...). Ezért én még az "activecell, activesheet, stb." hivatkozásokat is csak nagyon-nagyon módjával használom.
Set c = .Find("keresett string", LookIn:=xlValues,lookat:=xlwhole,searchdirection:=xlprevious)
Ez szerintem a legutolsó előfordulást fogja adni, és nem kell hozzá ciklus sem - ha nem akarod megszámolni, hányszor fordul elő.
(A lookat paramétert azért érdemes megadni mindig, mert egyébként megőrzi az előző értékét. Tehát, ha csak szövegrészletet keresel akkor =xlpart, egyébként =xlwhole.)
A probléma miatt a cursor mindig az elsősorban van ezért van az, hogy smallscroll igy paraméterezve hibátlanul működik. Ez a megoldás azonban a jelenség megkerülését jelenti. A probléma okát már kezdem sejteni.
Leegyszerűsítve a következő folyamat után van ez a gond:
With Sheets("sheet").Range("A1:A65000") Set c = .Find("keresett string", LookIn:=xlValues) If Not c Is Nothing Then 'elso sor keresese firstAddress = c.Address Range(c.Address).Select Do 'tovabbi sorkereses Set c = .FindNext(c) Range(c.Address).Select arrIndex(arrIndexAdress) = ActiveCell.Row Loop While Not c Is Nothing And c.Address <> firstAddress End If
A "do" ciklusban az utolsó találat ujra az első sor ezért a pozicionálás is ide történik. Ha ezt megtudnám akadályozni akkor nem lenne szükség erre a hókusz pókuszra és azonnal az utolsó sorra pozicionálna
Mivel az excel sorainak száma 1-től kezdődik, így természetesen negatív számú sorra nem tud rápozicionálni a scrollrow. Ez komoly hibája, ezért nekünk kell erre figyelni, pl. így:
Activewindow.scrollrow=iif(arrIndexMax - 25<1,activewindow.scrollrow de ide írhatod ezt is: 1,arrIndexMax - 25)
Ebben az esetben vagy marad az ablak tetején az a sor, ami eredetileg is volt, vagy az első sor kerül oda, attól függően, mit írtál középre.
A smallscroll ezek szerint "intelligensebb", tudja kezelni, hogy negatívba nem viszi a sorszámot, hanem marad az első sorban.
Kipróbáltad amit azzal kapcsolatban írtam? (Nyilván a 25 sor az elméleti, az a kérdés, mennyi látszik az ablakodban.) De nézd meg nagyított nézetnél is lsz (amikor az ablakban pl. 10-12 sor látszik csak).
Valószínű, hogy amikor behívod a táblázatot, akkor az első sor kerül az ablak legfelső részébe, ezért múködik a smallscroll jónak tűnően.
Mégegyszer hangsúlyozom, a fontos különbség, hogy a smallscroll relatív - az aktuális helytől számol, a scrollrow pedig abszolut, konkrétan megadott sort ugratja az ablak tetejére.