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.
Picit kekeckednék azért, mert jobb ma egy véreb, mint holnap kettő.
A form kódjának áttekinthetősége egy dolog, más dolog a hordozhatósága. Van úgy, hogy az ember csinál egy formot egy adott feladatra, aztán pár hónappal később jön egy másik feladat, ahol hajszálra ugyanaz a form jó lenne, vagy csak minimális változtatásokkal. Ha az első feladatnál hordozhatóra írtad meg, akkor könnyű átvinni. Ha nem, akkor nem annyira.
A hordozhatóságnak (vagy más szóval újrafelhasználhatóságnak) ebben a kontextusban ilyen kritériumai vannak:
1) A form jól definiált bemenetekkel és kimenetekkel rendelkezik.
2) A form tartalmazza az összes kódot, ami ahhoz kell, hogy a felhasználóval kommunikáljon, illetve a bemenetekből a kimeneteket előálltsa.
Ha a formról olyan függvényeket hívsz meg, amelyek külső modulon vannak, a 2. feltétel nem teljesül. Ez nem feltétlenül probléma, csak fel kell jegyezni valahová (célszerűen a form kódlapjának tetejére commentben), hogy a form csak az ilyen-olyan külső modullal együtt használható. Aztán ha kell, akkor együtt vinni mindkettőt a következő alkalmazásba.
De különben, ha csak egy adott form használ egy adott függvényt, akkor azt a form saját kódlapján is el lehet helyezni, Private megjelöléssel. Akkor kívül esik az eseménykezelő rutinokon, és nem zavarja az áttekinthetőségüket, de mégis a form része marad.
Még annyit a függvények önálló modulba gyűjtéséről, hogy nagyon nagy segítség. Kiválóan áttekinthetővé tudom ezzel tenni a formok eseményeinek programozását. Mert nem csak azokat feladatokat teszem ki, amelyeket több form is használ, hanem áttekinthetőbbé tudom tenni az egyes események vezérlését. Érthetőbbé tudom tenni az események vezérlését és csökkenteni tudom a kódjaik méretét. Nagyon jó!!!
Köszönöm. Egyelőre csak meg akarom érteni. Mert egyelőre látva, hogy mennyire bonyolult, feladtam ezt az elképzelést, és inkább létrehozok egy "átmeneti" munkalapot. Ide írom a módosult adatokat az eredeti munkalappal azonos szerkezetben, és mentéskor csak bemásolom ezt a sort az eredeti munkalapra. Egyébként adatnyilvántartásról van szó, tételenként mintegy 50 adattal. És a felhasználókat meg szeretném kímélni attól, hogy az Excel táblázatban bogarászva kelljen azt kitölteniük.
1) Userform2-n deklarálni publikus változókat, és azoknak értéket adni
2) Property-k használata.
Most nem írnám le részletesen őket, inkább mondd el, mi a célja, mire akarod használni.
Függvények:
Alapvetően azt kel sztem bekódolni egy Userform-ba, ami logikailag oda tartozik. Ha van egy függvényed, amit több form-ból is szeretnél elérni, az nem tartozik logikailag egyikbe sem. Az ilyen függvényeket én kiiraknám egy normál modulba, publikusan. Akkoraztán akárhonnan meghívhatóak.
Köszönöm. Szép kifejtés volt. Az túlzás, hogy értem, mindenesetre kipróbáltam és működik. És most próbálom értelmezni.
A mintapélda rról szól, hogy a meghívott Userform át tud adni adatokat a meghívónak. Azt viszont nem tudom kibogozni, hogy ez működik-e úgy is, hogy ez oda-vissza megtörténjen? Mert olyasmiben gondolkozom, mint a klasszikus funkcióknál. Hogy a hívó átad egy paramétert a meghívottnak, az pedig módosítja az értéket és azt visszaadja. Ehhez a mintában nem találtam meg a kulcsot.
A másik - tegnap késő esti - kérdésem azt hiszem, megoldódott a leírásod alapján. "...az adatok átadását a Form-ok között ... eseményekhez kötjük." Ebből az következik számomra, hogy a Formok között a függvények nem átjárhatók, tehát nem oldható meg, hogy egy adott függvényt csak az egyik form kódjában szerepeltessek, és azt a másik form kódjából is meg tudjam hívni. Jól értem?
sziasztok, teljesen tanácstalan vagyok, kellene csinálnom egy excelt, amiben legordülö menük vannak.
es van hozzá egy táblázatom, amiben benne vannak az adatok, a cel az lenne hogy a végén ha a legördulö menuben mindent kivalasztottam akkor egy eredmény kijöjjön.
pl kiválasztom, egy oszlopban melyik ország akkor azt szeretném ha odaírná mellé a pénznemét, de az országnak van egy szorzó száma is, meg egy kódja is es azt is odaírná. fkeressel próbáltam, de az egy cállát ir csak mellé.
Ajánlom mindazok figyelmébe, akik a "Class Module = megfejthetetlen talány" című műsorban érdekeltek.
Alapvetően a Userform a Class Module-hoz hasonlóan egy objektumosztályt jelent. Amikor azt mondjuk, hogy Userform1.Show akkor valójában az Excel létrehozza a Userform1 nevű objektumosztály egy példányát, amit alapértelmezés szerint ugyanúgy ("Userform1") hívnak, és azt jeleníti meg. Tehát a konkrét műveletet sosem az objektumosztállyal, hanem annak egy példányával végezzük. Legalábbis ezt gondolom, mert leírva nem találtam sehol. Mindenesetre egy Userform1 típusú form megjelenítésének szabályos módja az alábbi lenne:
Dim UF As Userform1 Set UF = New Userform1 UF.Show
Ez azért lényeges, mert ugyanabból az objektumosztályból tetszőleges számú példányt létrehozhatunk, és ez igaz a "Userform1" nevű objektumosztályra is:
Dim UF1 As Userform1, UF2 As Userform1 Set UF1 = New Userform1 Set UF2 = New Userform1 UF1.Show UF2.Show
(Mindkettő egyszerre csak akkor jeleníthető meg, ha a Userform1 osztály ShowModal tulajdonsága False.)
Na most. Az objektumorientált programozásban az egyes ineraktív objektumok történéseit, felhasználói beavatkozásra adott reakcióit az objektum eseményein keresztül lehet kezelni. Ilyet már mindenki látott, pl. a Munkalap típusú objentum Worksheet_Change eseménye személyében.
Kézenfekvő, és szerintem elegáns és konzisztens megoldás az, ha az adatok átadását a Form-ok között ilyen eseményekhez kötjük.
Ehhez szükséges, hogy az adatot átadni szándékozó Userform-on definiáljunk egy publikus eseményt. Ez nem olyan esemény lesz, ami a felhasználó kattintgatásaira reagál. Ezt az eseményt programból váltjuk ki, de a formon belül. Ugyanakkor a formot meghívó külső egység fogja érzékelni, hogy itt esemény történt, és kezelni azt.
A gyakorlatban hogy néz ez ki.
Van 2-féle Form tervező üzemmódban összerakva: Userform1 és Userform2. Userform1 az elsődleges űrlap, ez hívja meg majdana másodlagos űrlapot. Userform1-en legyen - egy gomb, amelynek neve Btn1 - egy textbox, aminek neve TextBox1
Userform2 a másdolagos űrlap, ebbe kell a felhasználónak adatokat beírni, és ez adja majd vissza az adatokat az elsődleges űrlapnak. Ezen az űrlapon legyen - 4 db Textbox, amelyeknek neve: Txt1, Txt2, Txt3, Txt4 - egy gomb, amelynek neve btnReturn
Userform2 kódlapján, lehetőleg a lap tetején definiáljuk a "Visszatérés" nevű eseményünket:
Public Event Visszatérés(Érték1 As String, Érték2 As String, Érték3 As String, Érték4 As String) Lényeges, hogy Public legyen, mert csak ekkor látszik kifelé, a létrehozó felé. A Userform2 összes többi, gyárilag definiált eseménye Private, ezért nem is látszik kintről.
Szintén Userform2 kódlapján definiáljuk, hogy a btnReturn gomb megnyomása kiváltsa ezt a bizonyos űrlapeseményt: Private Sub btnReturn_Click() RaiseEvent Visszatérés(Me.Txt1, Me.Txt2, Me.Txt3, Me.Txt4) End Sub
Userform1 kódlapján (legfelül) először is deklarálunk egy Userform2 típusú változót.
Private WithEvents UF As UserForm2
A WithEvents kapcsoló kötelező, ellenkező esetben nem tudjuk Userform1-ről kezelni az UF objektum eseményeit.
Aztán Btn1-hetz rendeljük az űrlap megjelenítését: Private Sub btn1_Click() Set UF = New UserForm2 UF.Show End Sub
Amint a Private WithEvents UF As UserForm2 deklarációt beírjuk, a kód-ablak fölötti, bal oldali lenyílóban megjelenik az UF objektum, amit ha kiválasztunk, a jobb oldali lenyílóból ki lehet választani az UF valamely eseményét. Mivel UF-nek csak egy eseménye van definiálva, jelenleg nincs sok választási lehetőség, de amúgy lehetne.
Leprogramozzuk az eseményt: Private Sub UF_Visszatérés(Érték1 As String, Érték2 As String, Érték3 As String, Érték4 As String) Me.TextBox1 = Érték1 & "-" & Érték2 & "-" & Érték3 & "-" & Érték4 Unload UF End Sub
Használat közben akkor mi is történik? Usefrom1 létrehoz és megnyit egy Userform2 típusú objektumot, mely utóbbi neve UF. A felhasználó az UF-en beírja az adatokat a 4 szövegdobozba, aztán megnyomja a gombot. A gombnyomás (mert így programoztuk le a gomb eseményét) kiváltja az UF űrlap Visszatérés nevű eseményét, amely magában foglalja 4 paraméter átadását. A Userform1 érzékeli, hogy az UF-en publikus esemény történt, és mivel van hozzá eseménykezelő rutin írva (Private Sub UF_Visszatérés), azt végrehajtja, és ennek keretében beírja a TextBox1-be a UF által visszaadott 4 sztringet kötőjellel elválastzva. Aztán bezárja az UF űrlapot. (De akár nyitva is hagyhatja, ha éppen arra van szükség.)
Az adatok visszadása bármilyen lehet. Sok adat esetében érdemes tömböket összeállítani, és/vagy egyéni típusokat használni, és akkor egy-két változóban többszáz vagy többezer adat átadható a másik űrlapnak.
Ha simán megosztok egy táblázatot, akkor ugye bárki más is le tudja venni a megosztást, nem csak az eredeti megosztó személyiség?
Valamint ha van egy megosztott táblázatban egy szürke pipa a megosztásnál, és senki nem tudja levenni, annak mi lehet az oka, és hogy lehet gyógyítani?
Előre is köszönöm. És ha nem vagyok nagyon telhetetlen, akkor ugyanez függvények vonatkozásában is érdekelne, hogy ne kelljen több helyre bemásolnom az ismétlődő függvényeket. Nem mintha nagy munka lenne, de hát az igényes, struktúrált programozás kritériumainak nem igazán felel meg.
Nagy gondban vagyok. Hogyan lehetséges a különböző UserFormok között változókat továbbadni. Reménytelenül keresgélea google-ban. Olyan tanácsokat látok, amire magam is gondoltam, csak éppen nem működnek.
- Próbáltam az első használt UserFormnál (ahonnan a többieket hívom) Public-nak deklarálni, de nem segített.
- A másik tanács az volt, hogy a General Deklarációknál kellene Public-ba tenni, de nekem az sem működött.
- Volt olyan tanács is, hogy az egyes vezérlőelemek tag-jébe kell írni. De ez sem jött be, mert a vezérlőelemet nem tudom elérni egy olyan UserFormban, amelyikben nem szerepel.
Végső soron megoldás lesz, hogy egy átmeneti munkalapon tárolom a kb. 50 változómat, de valahogy nehézkesnek érzem, és semmiképpen sem elegánsnak.
Mellesleg a végleges helyükre azért nem akarom kiírni, mert erre csak akkor kerítenék sort, mikor az operátor kéri a mentést. Minél kevesebb esélyt szeretnék adni félbemaradt mentésre.
A tegnap lementett fájlom ma azzal az üzenettel örvendeztett meg, hogy a beolvasáskor az Excel olvashatatlan tartalmat talált a benne és akarom-e hogy kijavítsa. Akartam. Kijavította. A problémám csak az, hogy a hibajelentésből nem derűlt ki, hogy melyik rekordot törölte (látszólag semelyiket).
Tudna valaki segíteni a hibaüzenet értelmezésében?
Szóval az a probléma, hogy másnap reggel 2 filet is találsz a mappában? Egy készlet.xlsx-t és egy készlet(ütközés).xlsx-t? Még ilyennel nem találkoztam.
Lövésem sincs mi lehet a háttérben. Egy ötlet: Végig gondolnám a 29 munkafüzet kereszthivatkozásait. Hátha azok okozzák az ütközést.
Eddig még semmilyen kérdésbe nem futottam bele. Egyszer csak (többnyire másnap reggel) látom, hogy készlet.xlsx és készlet[ütközés].xlsx. Természetesen jó dolog, hogy nem irogat random mód felül dolgokat! :) De jelenleg 29 MF-ből áll és tartok tőle hogy valami fontos változtatás az egyik excel-be a másik fontos változtatás az üzközésesben hajtom végre... Ezért szeretném valahogy megoldani hogy rákérd mielőtt létrehozza. Vagy legalább abban a pillanatban figyelmeztet és nem egy egész napi munkát kell összehasonlítani, hogy mi is az eltérés.
Én inkább úgy gondolkodnék, hogy létezik-e olyan vezérlőelem, amivel ez a feladat megoldható. Ha van, akkor azt Excelből is lehet használni. Rengeteg custom vezérlő van. Ezek úgy készülnek, hogy valaki leül és megírja pl. C++ vagy Delphi nyelven, aztán közzéteszi. Nem biztos, hogy a MicroSoftra kell várni ez ügyben. Aztán persze lehet, hogy meg kell venni, de ez van.
Ha meg nincs olyan, ami kell, még mindig meg lehet írni SK. Príma lehetőség a Class Modulok felhasználására :)
Hát, a pivot jó is meg nem is. Próbálkozom vele még mindig. Nem igazán erre találták ki. Egy nagy faszerkezet karbantartása/módosítása nehézkes.
A Microsoft Treeview Control-nak utánanézek.
Kell hogy legyen valami, szerintem alap. Excelben nincs ilyen funkció, nem is erre való egy táblázatkezelő, de valamilyen más környezettel együtt kell hogy legyen valami. (Pl. MS Visio, vagy valamilyen xml-es lehetőség excelen belül akár)
Szintén kötelességemnek tartom közkinccsé tenni, mert ez is nagyon jól használható a UserForm vezérlőelemek megismerésében. És ez azokat is elmagyarázza, amelyek a korábban belinkelt ozgrid féle anyagban (http://www.ozgrid.com/Excel/free-training/ExcelVBA2/excel-vba2-index.htm) nincsenek részletezve.
Az AfterUpdate akkor indul, mikor bevitted az adatot, és a következő objektumra lépsz. Ha nincs a formon következő objektum, nem indul az eseménykezelő makró. Valószínűleg ez történt.
A ControlSource feladatát jól értelmezed. Egy ComboBoxnak legegyszerűbben így adhatod meg a listát a RowSource tulajdonságnál, amiből majd választhat a júzer.
A lentebb említett VL, VT, FL és FT Visible tulajdonságait eleve False-ra állítottam.
A wiki egy általános fogalom, kb. mint a táblázatkezelő. Én a konkrét wikiszoftverek közül a MediaWikire esküszöm, amelyik a Wikipédiát is hajtja. Szabad szoftver, kell alá PHP meg MySQL, ha egyébként nincs a gépeden, akkor egy pár perces XAMPP-telepítés segít. Nagy a támogatottsága és az ismertsége. Szerepel azon a listán, amit linkeltél.
Az imént azt írtam, hogy "Ez meg csak kiírta, de nem jegyezte meg." Időközben rájöttem, hogy én értettem félre valamit. Hiszen a TextBox, mint objektum, nem "jegyez meg" semmilyen adatot. Hanem a ControlSource gondoskodik arról, hogy a munkafüzetbe kiírt adat megjelenjen kedőértékként az objektum használatakor.