secara otomatis menjalankan makro Excel pada perubahan sel

91

Bagaimana saya bisa secara otomatis menjalankan makro Excel setiap kali nilai dalam sel tertentu berubah?

Saat ini, kode kerja saya adalah:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Range("H5")) Is Nothing Then Macro
End Sub

di mana "H5"sel tertentu sedang dipantau dan Macromerupakan nama makro.

Apakah ada cara yang lebih baik?

namin
sumber
Apakah RunMacroWhenValueChanges UDF di FormulaDesk memenuhi kebutuhan Anda? formuladesk.com
Gareth Hayter

Jawaban:

108

Kode Anda terlihat cukup bagus.

Berhati-hatilah, karena panggilan Anda ke Range("H5")adalah perintah pintasan ke Application.Range("H5"), yang setara dengan Application.ActiveSheet.Range("H5"). Ini bisa baik-baik saja, jika satu-satunya perubahan adalah perubahan pengguna - yang paling umum - tetapi nilai sel lembar kerja mungkin berubah jika bukan lembar aktif melalui perubahan programatik, misalnya VBA.

Dengan pemikiran ini, saya akan memanfaatkan 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

Atau Anda bisa menggunakan Me.Range("H5"), jika event handler ada di halaman kode untuk lembar kerja yang dimaksud (biasanya):

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Me.Range("H5")) Is Nothing Then Macro
End Sub

Semoga ini membantu...

Mike Rosenblum
sumber
4
bagaimana jika sel H5diubah dari lembar lain, katakanlah sheet2 maka fungsi di atas tidak berfungsi. tolong bantu dalam hal ini.
dhpratik
2
Untuk siapa pun yang datang ke sini dari pencarian google, pastikan Anda menempelkan kode ini ke lembar di vba, bukan modul seperti yang saya lakukan. lihat stackoverflow.com/questions/15337008/…
hammythepig
Application.ActiveSheet.Range ("H5"). ==> target.parent.range ("H5") bahkan lebih aman
Pierre
1
@WillEdiger Setiap kali Anda tidak secara eksplisit menentukan referensi lembar, Excel mengasumsikan ActiveSheetdan kapan pun Anda tidak secara eksplisit menentukan bahwa itu adalah Excel yang Anda kerjakan, Excel mengasumsikan Application.
Scott Marcus
1
Perhatikan bahwa, dalam modul kode lembar kerja (di mana Worksheet_Changeacara harus ditempatkan), yang Rangetidak memenuhi syarat tidak default ActiveSheettetapi merujuk ke lembar yang berisi kode. Oleh karena itu, kode dalam jawaban ini secara efektif sama dengan kode dalam pertanyaan. (Catatan: Kembali pada tahun 2009 ketika jawaban ini ditulis, mungkin berbeda, tapi saya cukup yakin tidak.)
YowE3K
7

Tangani Worksheet_Changeacara atau Workbook_SheetChangeacara tersebut.

Penangan kejadian mengambil argumen "Target As Range", sehingga Anda dapat memeriksa apakah rentang yang berubah termasuk sel yang Anda minati.

Joe
sumber
Terima kasih, ini berhasil. Saya memeriksa kisaran dengan, katakanlah Target.Address = Range("H5").Address,. Apakah ada cara yang lebih mudah?
namin
Alternatif: Not (Intersect(Target, Range("H5")) Is Nothing) . Apakah ini cara Anda melakukannya?
namin
2
Komentar pertama ( Target.Address = Range("H5").Address) tidak akan berfungsi jika sel Anda hanya bagian dari rentang yang diubah. Komentar kedua masih mengalami masalah yang dijelaskan oleh Mike Rosenblum.
Semut
5

Saya menghabiskan banyak waktu untuk meneliti ini dan mempelajari cara kerjanya, setelah benar-benar mengacaukan pemicu acara. Karena ada begitu banyak info yang tersebar, saya memutuskan untuk membagikan apa yang menurut saya berfungsi semua di satu tempat, langkah demi langkah sebagai berikut:

1) Buka VBA Editor, di bawah Proyek VBA (YourWorkBookName.xlsm) buka Objek Microsoft Excel dan pilih Lembar yang akan terkait dengan peristiwa perubahan.

2) Tampilan kode default adalah "Umum". Dari daftar drop-down di tengah atas, pilih "Worksheet."

3) Private Sub Worksheet_SelectionChange sudah ada sebagaimana mestinya, biarkan saja. Salin / Tempel kode Mike Rosenblum dari atas dan ubah referensi .Range ke sel yang Anda perhatikan perubahannya (B3, dalam kasus saya). Namun, jangan letakkan Makro Anda (saya menghapus kata "Makro" setelah "Lalu"):

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Me.Range("H5")) Is Nothing Then
End Sub

atau dari daftar tarik-turun di kiri atas, pilih "Ubah" dan di ruang antara Sub Pribadi dan Sub Akhir, tempel If Not Intersect(Target, Me.Range("H5")) Is Nothing Then

4) Pada baris setelah "Kemudian" matikan acara sehingga ketika Anda memanggil makro Anda, itu tidak memicu kejadian dan mencoba menjalankan Worksheet_Change ini lagi dalam siklus yang tidak pernah berakhir yang membuat Excel crash dan / atau mengacaukan semuanya:

Application.EnableEvents = False

5) Panggil makro Anda

Call YourMacroName

6) Hidupkan kembali peristiwa sehingga perubahan berikutnya (dan setiap / semua peristiwa lainnya) memicu:

Application.EnableEvents = True

7) Akhiri blok If dan Sub:

    End If
End Sub

Seluruh kode:

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

Ini akan mengaktifkan / menonaktifkan peristiwa dari Modul yang menciptakan masalah dan memungkinkan pemicu perubahan, menonaktifkan peristiwa, menjalankan makro Anda, dan mengaktifkan kembali peristiwa.

Eric Vaughn-Shobey
sumber
3

Saya lebih suka cara ini, tidak menggunakan sel tetapi rentang

    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
Javier Torón
sumber
Itu sama dengan satu sel. Anda dapat menetapkan rentang sebagai satu sel, rentang sel kontinu, atau bahkan sel tersebar (semua dipisahkan dengan koma).
Shai Alon
0

Saya memiliki sel yang ditautkan ke database saham online dan sering diperbarui. Saya ingin memicu makro setiap kali nilai sel diperbarui.

Saya percaya ini mirip dengan perubahan nilai sel oleh program atau pembaruan data eksternal apa pun tetapi contoh di atas entah bagaimana tidak berfungsi untuk saya. Saya pikir masalahnya adalah karena kejadian internal excel tidak dipicu, tapi itu dugaan saya.

Saya melakukan hal berikut,

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
Juan Garcia
sumber
1
Saya tidak bisa membuat ini bekerja karena beberapa alasan. Ketika saya memberi tahu kode untuk dijalankan di VBA itu menarik menu pop up dan menanyakan apakah saya ingin menjalankan makro daripada menjalankan makro secara otomatis?
David Van der Vieren