headerbanner

VBA - Excel - zjištění naposled aktivní buňky neaktivního listu

The active cell in a sheet other than the active sheet (VBA Excel)

 Jak zjistit naposledy aktivovanou buňku listu z makra bez aktivace daného listu.
How can I determine what is the active cell in a sheet other than the active sheet.

Běžný postup s aktivací:

Sheets('jmeno').Activate
alfabeta = Activecell.value ...

Pro získání Activecell musí být sešit aktivován, protože Activecell je vlastností třídy Application a nikoli vlastností sešitu, nelze ji získat z Sheets("jmeno"). Přepínání mezi listy ale kromě jiného prodlužuje trvání makra. Lepší postup je vytvoření třídy, jejíž instance zachytává událost SheetSelectionChange. Zachytí každé kliknutí na kteroukoli buňku, kterým se buňka vybere.

Následující třída EventAppClass při inicializaci přiřadí do proměnné XLApp objekt Application. V tom okamžiku můžeme obsluhovat události objektu Application, tedy například zjišťovat změnu selektované (aktivní) buňky - událost XLApp_SheetSelectionChange.

Třída EventAppClass (Class EventAppClass):

'Deklarujeme proměnnou XLApp jako objekt "zpracovávající události" z Application
Private WithEvents XLApp As Application
 
'Přiřadíme "aplikaci" do proměnné
Private Sub Class_Initialize()
  Set XLApp = Application
End Sub
 
'Obsluha události při změně selektované buňky v kterémkoli sešitu
Private Sub XLApp_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
'Při chybě bude pokračovat následujícím řádkem 
On Error Resume Next
If Sheets(Sh.Name).curcell = "" And False Then
        'Pokud v některém modulu sešitu zapomeneme deklarovat proměnnou curcell, 
        'předchozí řádek generuje chybu. 
        'Díky "And False" nemůže být podmínka splněna nikdy 
        'a tento prázdný řádek je výsledkem pouze v případě chyby 
Else 'když curcell existuje - tedy nedošlo k chybě
  On Error GoTo 0 'vrácení reakce na chybu do původního stavu   
  Set Sheets(Sh.Name).curcell = ActiveCell
        'Pokud bychom chtěli místo ActiveCell dostat selektovanou oblast
        'pak místo předchozího řádku použijeme následující:
        'Set Sheets(Sh.Name).curcell = Target
End If
End Sub

 

Do modulů všech sešitů vložit (sheet modules)

'Aktivní buňka daného listu
Public curcell As Range
 
'Při aktivaci sešitu
Private Sub Worksheet_Activate()
        'Když veřejná proměnná není inicializována
        If ExcelEvents Is Nothing Then Set ExcelEvents = New EventAppClass
  Set Me.curcell = ActiveCell 'první nastavení aktivní buňky
End Sub

Do kteréhokoli standardního modulu (Modul1, Modul2 atd. - ale pouze do jediného) vložit:

Public ExcelEvents As EventAppClass 'Deklaraci vložit do jediného standardního modulu

Ze kteréhokoli modulu pak mohu zjistit naposled aktivovanou buňku kteréhokoli sešitu

Private Sub example () 'může být i Public
Dim she as worksheet
for each she in Worksheets
MsgBox "Active cell in sheet: " & Sheets(she.Name).Name & " is " & Sheets(she.Name).curcell.Address
next
end sub

Příklad ke stažení.