Windows(ThisWorkbook.Name).Activate nem működik
2021-09-22T17:39:12+02:00
2021-09-27T18:34:38+02:00
2022-08-19T02:27:04+02:00
bpjotr
Sziasztok!

Egy excel táblázat makrója formot kezel, más táblákat megnyit, bezár, módosít.
A probléma akkor adódik, ha a júzer úgy nyitja meg ezt a munkafüzetet, hogy közben egy másik is nyitva van. Amikor ugyanis munkalapot kellene váltani, akkor nem fogja megtalálni, ha a másik munkafüzet az aktív.
Az volt az elképzelésem, hogy a címben említett sorral a makrót tartalmazó munkafüzetet teszem aktívvá, így már mehetne. De nem megy. Erről a pár sorról lenne szó:


Sub fosorszam_megallapitasa()  
Windows(ThisWorkbook.Name).Activate
MsgBox (ActiveWindow.Caption)
 Sheets("Modosito").Select
 usor = Range("B" & Rows.Count).End(xlUp).Row
.
.
.

Csak a próba kedvéért tettem bele az MsgBox sort, és valóban nem a makrót tartalmazó munkafüzet az aktív. És persze nem is tud a másikon az ott nem létező "Modosito" lapra váltani.
Meg is áll Runtime-error "9" hibakóddal.
(Egyébként valóban a másik táblázat látszik a képernyőn)

A dolog azért rejtélyes számomra, mert ugyanezen VBA másik rutinjában szépen működik.
Lehet, hogy köze van ahhoz, hogy egy form Combobox Change eseménye után következik ez a rutin?


Előre is köszönettel: Péter
Mutasd a teljes hozzászólást!
Szia!

A jelenlegi (még oly kezdetleges) megoldás vajon miért nem működik itt, ha amott rendben lefut?

Valószínűleg azért, mert itt mások a körülmények.
Próbáld meg a lépésenkénti futtatást, tegyél be töréspontokat (Stop utasítást), a kritikus helyeken megnézni a változókat, az aktív munkafüzetet, munkalapot stb. Erre a VBA Debug lehetőséget ad arra is, hogy megnézzük, honnan, melyik program sorokból került oda a makró, ahol most van.
Kapcsold be a View - Toolbars menüben a Debug toolbart. Itt megtalálod a Call Stack menüpontot.
Ha továbbra sem találod a probléma megoldását, akkor tegyél fel egy mintafájlt, amiben az érzékeny adatokat megváltoztatod. 
Látatlanban sajnos nincsenek már tippjeim.
Üdv.
Mutasd a teljes hozzászólást!

  • Szia!
    Talán a munkafüzetet kellene aktíválni és nem az ablakot.
    Próbáld meg úgy, hogy a makró elindulásakor a makrót tartalmazó munkafüzetet hozzárendeled egy változóhoz. 
    Dim actwb As Workbook
    Set actwb =Activeworkbook  vagy Thisworkbook
    actwb.Activate
    Még egy megjegyzés:
    Nem szükséges az adott munkalapot aktíválni, selectet csinálni rá. Direktben lehet hivatkozni az adott tartományra:tó
    usor=actwb.Sheets("Modosito").Range("B" & Rows.Count).End(xlUp).Row
    Célszerű a gyakran használt objektumokat változókhoz rendelni, sokkal egyszerűbb a használatuk.
    Dim sh =actwb.Sheets("Modosito")
    usor=sh.Range("B" & Rows.Count).End(xlUp).Row
    Az sh változóval mindenütt hivatkozhatsz az adott munkalapra, semmi más nem kell hozzá.
    Üdv.
    Ps. A Thisworkbook elvileg mindig a makrót indító munkafüzetet jelenti és nem az aktív munkafüzetet.
    Mutasd a teljes hozzászólást!
  • Kedves Fferi!

    Már azért megérte feltenni a kérdést, amiket eddig írtál. 
    Valóban jelentősen egyszerűsíthetni a munkámat az általad javasolt megoldás.
    Sajnos azonban a konkrét helyzeten nem segített.
    Először a Workbook_Open()-be tettem a deklarációt, de azt nem találta a Modul1.
    Ez után a Modul1 elejére publikus deklarációként. Így már lefut az alábbi változtatás:

    'Windows(ThisWorkbook.Name).Activate
    KitoltoWb.Activate
        Sheets("Modosito").Select
        usor = Range("B" & Rows.Count).End(xlUp).Row

    A hiba azonban a "Sheets("Modosito").Select" sorban ugyanúgy megmaradt.
    Értem, hogy select nélkül is operálhatok egy munkafüzetben, de igaz ez valamennyi műveletre?
    (szűrés, sortörlés, fkeres, stb)

    Voltaképp csak azt szeretném megoldani, hogy ne álljon le hibával a program, ha idegen excel tábla (táblák) is nyitva van (vannak).
    Mutasd a teljes hozzászólást!
  • Szia!
    Valószínűleg nem az a munkafüzet aktív, amiben a Modosito nevű munkalap van.
    Nézd meg, mi a KitoltoWb.Name értéke. Ha lépésenként hajtod végre a makrót, akkor az értékadás után megnézheted, jó értéket kapott-e a változód.
    Publikus változók használata esetén azonos nevű változót ne definiálj eljárásokon belül - mivel azok külön életet élnek, függetlenek a publikus változótól!!
    Itt találod a VBA angol nyelvű helpjét.
    Egyébként a direkt hivatkozások a Select "ugrálások" nélkül működnek az esetek 99 %-ában.
    Van néhány objektum, amelyikkel csak a Select után lehet műveletet végrehajtani, ilyen pl. a Megjegyzés (Comment), általában formázási utasítások működnek így. Ezeket sajnos meg kell tapasztalni, mert a leírásokban sehol nincs benne.
    Fontos még, hogy a Range hivatkozásokban pontosan meg kell adni a "teljes elérést", pl.
    Sheets(1).Range(Sheets(1).Cells(1,2),Sheets(1).Cells(4,5)), amennyiben nem a Sheets(1) az aktív munkalap. 
    Üdv.
    Mutasd a teljes hozzászólást!
  • Nos az eredmény helyes. Tehát a KitoltoWb.name annak a fájlnak a neve, amelyben a "Modosito" munkalap és a makro is van.
    Ennek ellenére a "Subscript out of range" hibát kapom a select sorában.
    Nem látom, mi lehet a hiba oka.
    Ha nem marad más, akkor persze lehet, hogy mindenütt átírom, hogy ne select után jöjjön valami művelet, de mégis jó lenn tudni a hiba okát.

    Egyébként akár ezt is írhatnám?
    KitoltoWb.Sheets("Modosito").Select
    Mutasd a teljes hozzászólást!
  • Szia!
    Ez a hibaüzenet akkor jön, ha nincs olyan objektum amire hivatkozunk.
    A hiba bekövetkezésekor érdemes lenne a Debug után megnézni, hogy honnan "érkezett" erre a sorra a makró.
    Ha nincs ilyen objektum, akkor hiába hagyod el a selectet....
    Biztos, hogy a munkalap nevét helyesen írtad a makróban?
    Nézd meg a VBAProject nézetben, hogy milyen munkalapok vannak.
    Egy kéretlen szóköz, nem látható karakter tud ám galibát csinálni.
    Üdv.
    Mutasd a teljes hozzászólást!
    Csatolt állomány
  • Szia!

    próbáld meg teljes elérési úttal a hivatkozást, ne a sheet(akármi)-vel, hanem a Workbooks(valami).worksheets(akármi)-vel.(ilyenkor kell az 's' a végükre)
    És igen, bármit csinálhatsz makróból a munkalapon anélkül, hogy az lenne az aktív.
    Viszont a sheet(akármi) mindig az adott munkafüzetben fogja keresni a munkalapot.
    A változónév.worksheets(akármi) nem járható, tedd a munkalapot is külön változónévbe.
    Sőt, a formokat és a rajtuk lévő objektumokat is lehet változóba rakni.
    PL: set Gomb1=Userform1.commandbutton1 (remélem jól írtam a hivatkozást)
    set munkalap=workbooks("kitolto").worksheets("Modosito")
    ha amunkalap elején az első sub vagy function előtt deklarálod a változót, akkor az egész munkalapon/munkafüzetben használhatod. Sima DIm csak a az adott modullapon elérhető, de ha Public Változó as akármi-ként írod, akkor más modullapokról is elérhető lesz a változó.
    Mutasd a teljes hozzászólást!
  • Nos, ez egy működő megoldás:
        usor = Workbooks(ThisWorkbook.Name).Sheets("Modosito").Range("B" & Rows.Count).End(xlUp).Row

    Nekem ez azt mutatja, hogy létezik az objektum, létezik a munkafüzet, hisz ha valamelyik összetevő hibás lenne, akkor  megint csak hibára futna.
    Így viszont a következő hasonló helyen  akad el.

    Ráadásul ez a metódus másik rutinban működik:
    A futás elején egyfajta szinkronizálás folyik, amelyben egy megnyitott táblázat adatait másolja át a makrót tartalmazó munkafüzet különböző munkalapjaiba. Itt többször is vált a megnyitott ablakok között, gond nélkül. (Ezt persze lehet, hogy érdemes lesz átírni az instrukcióid alapján).

    Ez tehát működik:
        Windows("alapadatok.xlsx").Activate
        Sheets("Felhasznalok").Select     
            Cells.Select
            Application.CutCopyMode = False
            Selection.Copy
        Windows(ThisWorkbook.Name).Activate
        Sheets("Felhasznalok").Select
            Cells.Select
            ActiveSheet.Paste


    A baj az, hogy az egész projekt tele van ehhez hasonló hivatkozásokkal.
    Mutasd a teljes hozzászólást!
  • Szia!
    Az utolsó példád egy db sorral megoldható:
    Windows helyett én továbbra is a Workbooks használatát javaslom:

    Workbooks("alapadatok").Sheets("Felhasznalok").Usedrange.Copy Destination:=Workbooks(ThisWorkbook.Name).Sheets("Felhasznalok").Range("A1")
    Ez a forrás munkafüzet minden celláját átmásolja a cél munkafüzetbe az A1 cellától kezdve. Ha csak részterületet másolsz, akkor Usedrange helyett pl. Range("A1:X5"), a cél munkafüzetnél pedig az első cellát kell megadni.
    Ráadásul ebben az esetben teljesen mindegy, hogy melyik munkafüzet melyik munkalapja aktív!!!
    Üdv.
    PS. Tudom, hogy a makrórögzítő a Windows használja - amiben neki igaza is van, hiszen ablakok között navigálsz -, de a közvetlen címzéshez szerintem a Workbooks a logikus.
    Mutasd a teljes hozzászólást!
  • Valóban! A következő projektben biztos, hogy ezt a megoldást fogom választani, mert egyszerűbb, tömörebb, kevesebb hibalehetőséget rejt.. Az a bánatom, hogy a jelenlegi már hemzseg a hasonló műveletektől és attól félek, hogy aránytalanul nagy ráfordítást igényelne az egész kódot átírni.

    Nyilván, ha nem találok más megoldást, akkor a javaslataitok szerint elkezdem átalakítani, csak félek, hogy kicsúszok az időből.

    Szóval: A jelenlegi (még oly kezdetleges) megoldás vajon miért nem működik itt, ha amott rendben lefut?
    Mutasd a teljes hozzászólást!
  • Szia!

    A jelenlegi (még oly kezdetleges) megoldás vajon miért nem működik itt, ha amott rendben lefut?

    Valószínűleg azért, mert itt mások a körülmények.
    Próbáld meg a lépésenkénti futtatást, tegyél be töréspontokat (Stop utasítást), a kritikus helyeken megnézni a változókat, az aktív munkafüzetet, munkalapot stb. Erre a VBA Debug lehetőséget ad arra is, hogy megnézzük, honnan, melyik program sorokból került oda a makró, ahol most van.
    Kapcsold be a View - Toolbars menüben a Debug toolbart. Itt megtalálod a Call Stack menüpontot.
    Ha továbbra sem találod a probléma megoldását, akkor tegyél fel egy mintafájlt, amiben az érzékeny adatokat megváltoztatod. 
    Látatlanban sajnos nincsenek már tippjeim.
    Üdv.
    Mutasd a teljes hozzászólást!
  • Köszönöm a tanácsodat! Rég szemezgetek a Debug funkcióval, de mivel nem ismerem, nem is nagyon merem használni.

    Hogyan oldható meg az például, hogy a program azon része, amely  kifogástalanul működik és sok fájlt megnyit, olvas, bezár (egy szóval, ami nagyon sokáig tartana lépésenkénti futtatással) egyben lemenjen, és csak ott kezdjen egyesével lépdelni, ahol a hiba előfordulhat?
    Mutasd a teljes hozzászólást!
  • szia
    f9et nyomsz arra a sorra, ahonnét vizsgálni akarsz. 

    f5el elfut addig, aztán utána f8al léptetheted egyesével.
    Mutasd a teljes hozzászólást!
  • Köszönöm, mindjárt kipróbálom!
    Mutasd a teljes hozzászólást!
  • Hááát.... Végig néztem a kódot, de nem találtam indokot erre a hibára. Viszont, ha már úgyis végig néztem, kipurgáltam az összes szükségtelenek ítélt Windows....select sort az instrukcióitok alapján.
    Most úgy tűnik működik, de nem tudom mitől. Kicsit bosszantó, hogy nem találtam meg, de a végeredmény számít. Köszönöm a tanácsaitokat Na de most kinek adjam a pontot?

    Talán Fferi segített a legtöbbet. Senki sem sértődik meg, ha Ő kapja?

    Jut eszembe: Közben bele akadtam egy még idegesítőbb hibába, de azt majd egy következő témában...

    Köszönök minden segítséget!
    Mutasd a teljes hozzászólást!
abcd