Jak mogę automatycznie wykonać makro programu Excel za każdym razem, gdy zmienia się wartość w określonej komórce?
W tej chwili mój działający kod to:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("H5")) Is Nothing Then Macro
End Sub
gdzie "H5"
jest konkretna monitorowana komórka i Macro
jest nazwą makra.
Czy jest lepszy sposób?
excel
vba
automation
namin
źródło
źródło
Odpowiedzi:
Twój kod wygląda całkiem nieźle.
Uważaj jednak, ponieważ wywołanie to
Range("H5")
jest poleceniem skrótu doApplication.Range("H5")
, które jest równoważne zApplication.ActiveSheet.Range("H5")
. Może to być w porządku, jeśli jedynymi zmianami są zmiany użytkownika - co jest najbardziej typowe - ale wartości komórek arkusza roboczego mogą się zmieniać, gdy nie jest to aktywny arkusz poprzez zmiany programistyczne, np. VBA.Mając to na uwadze, użyłbym
Target.Worksheet.Range("H5")
:Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Target.Worksheet.Range("H5")) Is Nothing Then Macro End Sub
Lub możesz użyć
Me.Range("H5")
, jeśli program obsługi zdarzeń znajduje się na stronie kodowej dla danego arkusza roboczego (zwykle jest):Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Me.Range("H5")) Is Nothing Then Macro End Sub
Mam nadzieję że to pomoże...
źródło
H5
zostanie zmieniona z innego arkusza, powiedzmy, żesheet2
powyższa funkcja nie działa. proszę o pomoc w tym.ActiveSheet
a gdy nie określisz wyraźnie, że jest to program Excel, z którym pracujesz, zakłada program ExcelApplication
.Worksheet_Change
zdarzenie musi być zlokalizowane), niekwalifikowanyRange
nie jest domyślnie,ActiveSheet
ale zamiast tego odwołuje się do arkusza zawierającego kod. Kod w tej odpowiedzi jest zatem w rzeczywistości taki sam jak kod w pytaniu. (Uwaga: w 2009 roku, kiedy napisano tę odpowiedź, mogła być inna, ale jestem prawie pewien, że tak nie było).Obsługuj
Worksheet_Change
wydarzenie lubWorkbook_SheetChange
wydarzenie.Procedury obsługi zdarzeń przyjmują argument „Docelowy jako zakres”, więc możesz sprawdzić, czy zmieniany zakres obejmuje komórkę, która Cię interesuje.
źródło
Target.Address = Range("H5").Address
. Czy istnieje prostszy sposób?Not (Intersect(Target, Range("H5")) Is Nothing)
. Czy tak byś to zrobił?Target.Address = Range("H5").Address
) nie działałby, gdyby komórka była tylko częścią zmienionego zakresu. Drugi komentarz wciąż cierpi na problemy opisane przez Mike'a Rosenbluma.Spędziłem dużo czasu na badaniu tego i uczeniu się, jak to wszystko działa, po tym, jak naprawdę zepsułem wyzwalacze zdarzeń. Ponieważ było tak wiele rozproszonych informacji, postanowiłem podzielić się tym, co znalazłem, aby działać w jednym miejscu, krok po kroku w następujący sposób:
1) Otwórz Edytor VBA, pod Projektem VBA (NazwaTwojejKsiążki.xlsm) otwórz obiekt Microsoft Excel i wybierz arkusz, którego będzie dotyczyło zdarzenie zmiany.
2) Domyślny widok kodu to „Ogólne”. Z rozwijanej listy w górnej środkowej części wybierz „Arkusz”.
3) Private Sub Worksheet_SelectionChange już tam jest tak, jak powinno, zostaw to w spokoju. Skopiuj / Wklej kod Mike'a Rosenbluma z góry i zmień odwołanie .Range do komórki, dla której szukasz zmiany (B3, w moim przypadku). Nie umieszczaj jednak jeszcze swojego makra (usunąłem słowo „makro” po „to”):
Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Me.Range("H5")) Is Nothing Then End Sub
lub z listy rozwijanej w lewym górnym rogu wybierz „Zmień” i w miejscu między Private Sub i End Sub wklej
If Not Intersect(Target, Me.Range("H5")) Is Nothing Then
4) W wierszu po „Następnie” wyłącz zdarzenia, aby wywołanie makra nie wywoływało zdarzeń i spróbuj ponownie uruchomić ten arkusz roboczy_Zmień w niekończącym się cyklu, który powoduje awarię programu Excel i / lub w inny sposób wszystko psuje:
Application.EnableEvents = False
5) Wywołaj swoje makro
Call YourMacroName
6) Włącz wydarzenia z powrotem, aby następna zmiana (i wszystkie / wszystkie inne zdarzenia) zostały uruchomione:
Application.EnableEvents = True
7) Zakończ blok If i Sub:
End If End Sub
Cały kod:
Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Me.Range("B3")) Is Nothing Then Application.EnableEvents = False Call UpdateAndViewOnly Application.EnableEvents = True End If End Sub
Powoduje to włączanie / wyłączanie zdarzeń z modułów, co stwarza problemy i po prostu pozwala wyzwalaczowi zmiany, wyłącza zdarzenia, uruchamia makro i ponownie włącza zdarzenia.
źródło
Wolę ten sposób, nie używając komórki, ale zakresu
Dim cell_to_test As Range, cells_changed As Range Set cells_changed = Target(1, 1) Set cell_to_test = Range( RANGE_OF_CELLS_TO_DETECT ) If Not Intersect(cells_changed, cell_to_test) Is Nothing Then Macro End If
źródło
Mam komórkę połączoną z bazą danych online i często aktualizowaną. Chcę wyzwalać makro za każdym razem, gdy wartość komórki jest aktualizowana.
Uważam, że jest to podobne do zmiany wartości komórki przez program lub jakąkolwiek aktualizację danych zewnętrznych, ale powyższe przykłady jakoś nie działają dla mnie. Myślę, że problem polega na tym, że wewnętrzne zdarzenia programu Excel nie są wyzwalane, ale tak przypuszczam.
Wykonałem następujące czynności,
Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Target.Worksheets("Symbols").Range("$C$3")) Is Nothing Then 'Run Macro End Sub
źródło