Saya telah mendengar banyak tentang kebencian yang dapat dimengerti tentang penggunaan .Select
di Excel VBA, tetapi saya tidak yakin bagaimana cara menghindari menggunakannya. Saya menemukan bahwa kode saya akan lebih dapat digunakan kembali jika saya dapat menggunakan variabel daripada Select
fungsi. Namun, saya tidak yakin bagaimana merujuk pada hal-hal (seperti yang ActiveCell
lain - lain) jika tidak menggunakan Select
.
Saya telah menemukan artikel ini pada rentang dan contoh ini tentang manfaat tidak menggunakan pilih tetapi tidak dapat menemukan apa pun tentang caranya ?
Select
dan / atauActiveSheet
etc dll benar-benar tidak dapat dihindari. Berikut adalah contoh yang saya temukan: stackoverflow.com/questions/22796286/….Select / .Selection
diperlukan.Jawaban:
Beberapa contoh cara menghindari pilih
Gunakan
Dim
variabel dSet
variabel ke rentang yang diperlukan. Ada banyak cara untuk merujuk ke rentang sel tunggalatau rentang multi-sel
Anda dapat menggunakan cara pintas ke
Evaluate
metode, tetapi ini kurang efisien dan umumnya harus dihindari dalam kode produksi.Semua contoh di atas merujuk ke sel di lembar aktif . Kecuali Anda secara khusus ingin bekerja hanya dengan lembar aktif, lebih baik untuk Dim
Worksheet
variabel jugaJika Anda tidak ingin bekerja dengan
ActiveSheet
, untuk kejelasan yang terbaik untuk menjadi eksplisit. Tetapi berhati-hatilah, karena beberapaWorksheet
metode mengubah lembar aktif.Sekali lagi, ini merujuk pada buku kerja aktif . Kecuali jika Anda secara khusus ingin bekerja hanya dengan
ActiveWorkbook
atauThisWorkbook
, lebih baik untuk DimWorkbook
variabel juga.Jika Anda tidak ingin bekerja dengan
ActiveWorkbook
, untuk kejelasan yang terbaik untuk menjadi eksplisit. Tapi hati-hati, karena banyakWorkBook
metode mengubah buku aktif.Anda juga dapat menggunakan
ThisWorkbook
objek untuk merujuk ke buku yang berisi kode yang sedang berjalan.Sepotong kode yang umum (buruk) adalah membuka buku, mendapatkan beberapa data lalu tutup kembali
Ini buruk:
Dan akan lebih baik seperti:
Pass rentang ke
Sub
danFunction
sebagai variabel RangeAnda juga harus menerapkan Metode (seperti
Find
danCopy
) ke variabelJika Anda mengulangi rentang sel, seringkali lebih baik (lebih cepat) untuk menyalin nilai rentang ke array varian terlebih dahulu dan mengulanginya.
Ini adalah pengecap kecil untuk apa yang mungkin.
sumber
rng1(12, 12)
akan bekerja meskipun rng1 ditetapkan[A1:A10]
hanya.Range
seperti ini:ActiveSheet.[a1:a4]
atauws.[b6]
.variant
variabel tidak memerlukanSet
sampai Anda menetapkan sebuah objek untuk itu. Misalnya,Dim x: x = 1
boleh saja, tetapiDim x: x = Sheets("Sheet1")
akan menghasilkan Kesalahan 438. Namun hanya untuk membingungkan / mengklarifikasi tidakDim x: x = Range("A1")
akan membuat kesalahan. Mengapa? ... karena itu menetapkan nilai objek ke variabel, bukan referensi ke objek itu sendiri (karena itu setara dengan )Dim x: x = Range("A1").Value
Dua alasan utama mengapa
.Select
/.Activate
/Selection
/Activecell
/Activesheet
/Activeworkbook
etc ... harus dihindariBagaimana kita menghindarinya?
1) Langsung bekerja dengan objek yang relevan
Pertimbangkan kode ini
Kode ini juga dapat ditulis sebagai
2) Jika perlu mendeklarasikan variabel Anda. Kode yang sama di atas dapat ditulis sebagai
sumber
Sheets(2).[C10:D12].Value = Sheets(1).[A1:B3].Value
.Activate
untuk pindah ke lembar asli, cukup gunakanApplication.Goto
Satu titik kecil penekanan saya akan menambahkan ke semua jawaban luar biasa yang diberikan di atas:
Mungkin hal terbesar yang dapat Anda lakukan untuk menghindari penggunaan Select adalah sebanyak mungkin, gunakan rentang bernama (dikombinasikan dengan nama variabel yang bermakna) dalam kode VBA Anda . Poin ini disebutkan di atas, tetapi sedikit ditutup-tutupi; Namun, itu patut mendapat perhatian khusus.
Berikut adalah beberapa alasan tambahan untuk menggunakan rentang bernama secara liberal, namun saya yakin saya bisa memikirkan lebih banyak.
Rentang yang diberi nama membuat kode Anda lebih mudah dibaca dan dipahami.
Contoh:
Cukup jelas apa yang disebut rentang
Months
danMonthlySales
kandungannya, dan apa yang dilakukan prosedur ini.Mengapa ini penting? Sebagian karena lebih mudah bagi orang lain untuk memahaminya, tetapi bahkan jika Anda adalah satu-satunya orang yang akan pernah melihat atau menggunakan kode Anda, Anda masih harus menggunakan rentang bernama dan nama variabel yang baik karena ANDA AKAN LUPA apa yang Anda maksud dengan itu setahun kemudian, dan Anda akan menghabiskan 30 menit hanya mencari tahu apa yang dilakukan kode Anda.
Rentang yang diberi nama memastikan bahwa makro Anda tidak rusak saat (tidak jika!) Konfigurasi spreadsheet berubah.
Pertimbangkan, jika contoh di atas telah ditulis seperti ini:
Kode ini akan berfungsi dengan baik pada awalnya - yaitu sampai Anda atau pengguna yang akan datang memutuskan "gee wiz, saya pikir saya akan menambahkan kolom baru dengan tahun di Kolom
A
!", Atau meletakkan kolom pengeluaran antara bulan dan kolom penjualan, atau tambahkan tajuk ke setiap kolom. Sekarang, kode Anda rusak. Dan karena Anda menggunakan nama variabel yang mengerikan, Anda akan membutuhkan lebih banyak waktu untuk mencari tahu cara memperbaikinya daripada yang seharusnya.Jika Anda menggunakan rentang bernama untuk memulai, kolom
Months
danSales
dapat dipindahkan di sekitar yang Anda suka, dan kode Anda akan terus berfungsi dengan baik.sumber
Saya akan memberikan jawaban singkat karena semua orang memberikan jawaban yang panjang.
Anda akan mendapatkan .pilih dan. Aktifkan setiap kali Anda merekam makro dan gunakan kembali. Ketika Anda memilih sel atau sheet, itu hanya membuatnya aktif. Mulai saat itu setiap kali Anda menggunakan referensi yang tidak memenuhi syarat seperti
Range.Value
mereka hanya menggunakan sel dan lembar aktif. Ini juga bisa menjadi masalah jika Anda tidak melihat di mana kode Anda ditempatkan atau pengguna mengklik pada buku kerja.Jadi, Anda dapat menghilangkan masalah ini dengan merujuk langsung ke sel Anda. Yang terjadi:
Atau kamu bisa
Ada berbagai kombinasi metode ini, tetapi itu akan menjadi ide umum yang diungkapkan sesegera mungkin untuk orang-orang tidak sabar seperti saya.
sumber
Sementara saya tidak bisa memikirkan lebih dari segelintir situasi di mana
.Select
akan menjadi pilihan yang lebih baik daripada referensi sel langsung, saya akan bangkit untuk membelaSelection
dan menunjukkan bahwa itu tidak boleh dibuang karena alasan yang sama yang.Select
harus dihindari.Ada saat-saat ketika sub rutin makro yang pendek dan hemat waktu ditugaskan untuk kombinasi tombol-panas yang tersedia dengan ketukan beberapa tombol menghemat banyak waktu. Mampu memilih sekelompok sel untuk memberlakukan kode operasional pada karya-karya ajaib ketika berhadapan dengan data saku yang tidak sesuai dengan format data lebar-lembar kerja. Sama seperti Anda memilih grup sel dan menerapkan perubahan format, memilih grup sel untuk menjalankan kode makro khusus bisa menjadi penghemat waktu utama.
Contoh-contoh dari sub framework berbasis pemilihan:
Kode aktual untuk diproses dapat berupa apa saja dari satu baris hingga beberapa modul. Saya telah menggunakan metode ini untuk memulai rutinitas berjalan lama pada sel-sel pilihan yang berisi nama file buku kerja eksternal.
Singkatnya, jangan membuang
Selection
karena hubungannya yang dekat dengan.Select
danActiveCell
. Sebagai properti lembar kerja ia memiliki banyak tujuan lain.(Ya, saya tahu pertanyaan ini tentang
.Select
, bukanSelection
tapi saya ingin menghapus kesalahpahaman yang mungkin disimpulkan oleh coders VBA pemula.)sumber
Selection
bisa berupa apa saja di lembar kerja jadi sebaiknya uji terlebih dahulu jenis objek sebelum menetapkannya ke variabel karena Anda secara eksplisit menyatakannya sebagaiRange
.Harap perhatikan bahwa di bawah ini saya membandingkan pendekatan Select (salah satu yang ingin dihindari OP), dengan pendekatan Range (dan ini adalah jawaban untuk pertanyaan). Jadi jangan berhenti membaca ketika Anda melihat Pilih pertama.
Itu benar-benar tergantung pada apa yang Anda coba lakukan. Pokoknya contoh sederhana bisa bermanfaat. Misalkan Anda ingin mengatur nilai sel aktif menjadi "foo". Menggunakan ActiveCell Anda akan menulis sesuatu seperti ini:
Jika Anda ingin menggunakannya untuk sel yang bukan yang aktif, misalnya untuk "B2", Anda harus memilihnya terlebih dahulu, seperti ini:
Menggunakan Ranges Anda dapat menulis makro yang lebih umum yang dapat digunakan untuk mengatur nilai sel apa pun yang Anda inginkan untuk apa pun yang Anda inginkan:
Kemudian Anda dapat menulis ulang Macro2 sebagai:
Dan Macro1 sebagai:
Semoga ini bisa membantu menjernihkan semuanya.
sumber
Menghindari
Select
danActivate
merupakan langkah yang membuat Anda pengembang VBA sedikit lebih baik. Secara umum,Select
danActivate
digunakan saat makro direkam, dengan demikianParent
lembar kerja atau rentang selalu dianggap sebagai yang aktif.Ini adalah bagaimana Anda dapat menghindari
Select
danActivate
dalam kasus-kasus berikut:Menambahkan Lembar Kerja baru dan menyalin sel di atasnya:
Dari (kode yang dihasilkan dengan perekam makro):
Untuk:
Saat Anda ingin menyalin rentang antara lembar kerja:
Dari:
Untuk:
Menggunakan rentang bernama mewah
Anda dapat mengaksesnya bersama
[]
, yang benar-benar indah, dibandingkan dengan cara lain. Periksa diri Anda:Contoh dari atas akan terlihat seperti ini:
Bukan menyalin nilai, tetapi mengambilnya
Biasanya, jika Anda mau
select
, kemungkinan besar Anda sedang menyalin sesuatu. Jika Anda hanya tertarik pada nilai-nilai ini, ini adalah opsi yang baik untuk menghindari pilih:Range("B1:B6").Value = Range("A1:A6").Value
Coba selalu referensi lembar kerja juga
Ini mungkin kesalahan paling umum di vba. Setiap kali Anda menyalin rentang, kadang-kadang lembar kerja tidak direferensikan dan dengan demikian VBA menganggap lembar yang salah sebagai ActiveWorksheet.
Bisakah saya benar-benar tidak pernah menggunakan
.Select
atau.Activate
untuk apa pun?.Activate
dan.Select
ketika Anda ingin memastikan bahwa Lembar Kerja tertentu dipilih karena alasan visual. Misalnya, Excel Anda akan selalu terbuka dengan lembar kerja sampul yang dipilih terlebih dahulu, mengabaikan mana yang merupakan ActiveSheet ketika file ditutup.Jadi, sesuatu seperti kode di bawah ini benar-benar OK:
Contoh bagus lainnya adalah ketika Anda perlu mengekspor semua sheet ke dalam satu file PDF, seperti yang disebutkan dalam kasus ini - Bagaimana cara menghindari pernyataan pilih / aktif dalam VBA dalam contoh ini?
Ketika perintah hanya bekerja dengan
ActiveWindow
seperti ActiveWindow.Zoom atau ActiveWindow.FreezePanessumber
.Select
- dan juga pekerjaan saya - dapat ditemukan di Cara menulis informasi yang identik dengan semua lembar - @Vityata :).FillAcrossSheets
, jadi ini adalah di antara (setidaknya dalam ide saya tentang taksonomi VBA)Selalu nyatakan buku kerja, lembar kerja, dan sel / rentang.
Sebagai contoh:
Karena pengguna akhir akan selalu hanya mengklik tombol dan segera setelah fokus berpindah dari buku kerja kode ingin bekerja dengan itu maka semuanya menjadi salah.
Dan tidak pernah menggunakan indeks buku kerja.
Anda tidak tahu buku kerja apa yang akan dibuka saat pengguna menjalankan kode Anda.
sumber
Metode-metode ini agak distigmatisasi, jadi ambil pimpinan @Vityata dan @Jeeped demi menggambar garis di pasir:
Mengapa tidak memanggil
.Activate
,.Select
,Selection
,ActiveSomething
metode / propertiPada dasarnya karena mereka dipanggil terutama untuk menangani input pengguna melalui UI Aplikasi. Karena mereka adalah metode yang dipanggil ketika pengguna menangani objek melalui UI, mereka adalah yang direkam oleh makro-recorder, dan itulah sebabnya memanggil mereka rapuh atau berlebihan untuk sebagian besar situasi: Anda tidak harus memilih objek sehingga dapat melakukan suatu tindakan dengan
Selection
segera setelah itu.Namun, definisi ini mengatur situasi di mana mereka dipanggil untuk:
Ketika menelepon
.Activate
,.Select
,.Selection
,.ActiveSomething
metode / propertiPada dasarnya ketika Anda mengharapkan pengguna akhir untuk memainkan peran dalam eksekusi.
Jika Anda mengembangkan dan mengharapkan pengguna untuk memilih objek contoh untuk menangani kode Anda, maka
.Selection
atau.ActiveObject
sesuai.Di sisi lain,
.Select
dan.Activate
digunakan ketika Anda dapat menyimpulkan tindakan berikutnya pengguna dan Anda ingin kode Anda untuk memandu pengguna, mungkin menghemat beberapa waktu dan klik mouse. Misalnya, jika kode Anda baru saja membuat instance baru dari bagan atau yang diperbarui, pengguna mungkin ingin memeriksanya, dan Anda bisa memanggilnya.Activate
atau lembar untuk menghemat waktu pengguna mencarinya; atau jika Anda tahu pengguna perlu memperbarui beberapa nilai rentang, Anda dapat memilih rentang itu secara terprogram.sumber
Penggunaan IMHO
.select
berasal dari orang-orang, yang seperti saya mulai belajar VBA dengan kebutuhan melalui perekaman makro dan kemudian memodifikasi kode tanpa menyadari bahwa.select
dan selanjutnyaselection
hanyalah perantara yang tidak perlu..select
dapat dihindari, karena sudah banyak diposting, dengan langsung bekerja dengan objek yang sudah ada, yang memungkinkan berbagai referensi tidak langsung seperti menghitung i dan j dengan cara yang kompleks dan kemudian mengedit sel (i, j), dll.Kalau tidak, tidak ada yang salah secara implisit dengan
.select
dirinya sendiri dan Anda dapat menemukan kegunaan untuk ini dengan mudah, misalnya saya memiliki spreadsheet yang saya isi dengan tanggal, mengaktifkan makro yang melakukan sihir dengannya dan mengekspornya dalam format yang dapat diterima pada lembar terpisah, yang Namun, membutuhkan beberapa input manual akhir (tidak dapat diprediksi) ke dalam sel yang berdekatan. Jadi inilah saatnya untuk.select
menyelamatkan saya bahwa gerakan mouse tambahan dan klik.sumber
Jawaban cepat:
Untuk menghindari menggunakan
.Select
metode ini, Anda dapat menetapkan variabel yang sama dengan properti yang Anda inginkan.► Misalnya, jika Anda menginginkan nilai di dalamnya,
Cell A1
Anda bisa mengatur variabel yang sama dengan properti nilai sel itu.valOne = Range("A1").Value
► Misalnya, jika Anda ingin nama kode 'Sheet3` Anda bisa mengatur variabel sama dengan properti nama kode dari lembar kerja itu.
valTwo = Sheets("Sheet3").Codename
Saya harap itu membantu. Beri tahu saya jika Anda memiliki pertanyaan.
sumber
Saya perhatikan bahwa tidak ada jawaban yang menyebutkan Properti .Offset . Ini juga dapat digunakan untuk menghindari penggunaan
Select
aksi ketika memanipulasi sel tertentu, terutama dalam referensi ke sel yang dipilih (seperti OP dengan menyebutkanActiveCell
).Berikut adalah beberapa contoh.
Saya juga akan menganggap "ActiveCell" adalah J4 .
ActiveCell.Offset(2, 0).Value = 12
J6
menjadi nilai 12ActiveCell.Offset(0,1).Copy ActiveCell.Offset(,2)
k4
keL4
.i4
ActiveCell.Offset(, -1).EntireColumn.ClearContents
Ini bukan untuk mengatakan mereka "lebih baik" dari opsi di atas, tetapi hanya daftar alternatif.
sumber
Bekerja dengan fitur .Parent. Contoh ini menunjukkan bagaimana pengaturan hanya satu referensi myRng yang memungkinkan akses dinamis ke seluruh lingkungan tanpa. Pilih, .Aktifkan, .Aktifkan ponsel, .Aktifkan Buku Kerja, .Aktifkan Lembar Kerja dan sebagainya. (Tidak ada fitur .Anak genereik)
sumber
Alasan utama tidak pernah menggunakan Select atau Activesheet adalah karena kebanyakan orang akan memiliki setidaknya beberapa buku kerja terbuka (kadang-kadang lusinan) ketika mereka menjalankan makro Anda, dan jika mereka mengklik menjauh dari lembar Anda saat makro Anda berjalan dan klik beberapa lainnya buku yang telah mereka buka, lalu "Activesheet" berubah, dan buku kerja target untuk perintah "Select" yang tidak memenuhi syarat juga berubah.
Paling-paling, makro Anda akan macet, paling buruk Anda mungkin akhirnya menulis nilai atau mengubah sel di buku kerja yang salah tanpa cara untuk "Membatalkan" mereka.
Saya memiliki aturan emas sederhana yang saya ikuti: Tambahkan variabel bernama "wb" dan "ws" untuk objek Workbook dan objek Worksheet dan selalu gunakan itu untuk merujuk ke buku makro saya. Jika saya perlu merujuk lebih dari satu buku, atau lebih dari satu lembar, saya menambahkan lebih banyak variabel.
sebagai contoh
Perintah "Set wb = ThisWorkbook" benar-benar penting. "ThisWorkbook" adalah nilai khusus di Excel, dan itu berarti buku kerja tempat Anda menjalankan kode VBA . Pintasan yang sangat membantu untuk mengatur variabel Workbook Anda.
Setelah Anda melakukannya di bagian atas Sub Anda, menggunakannya tidak bisa lebih sederhana, cukup gunakan di mana saja Anda akan menggunakan "Pilihan":
Jadi untuk mengubah nilai sel "A1" di "Output" menjadi "Hello", alih-alih:
Kita sekarang dapat melakukan ini:
Yang tidak hanya jauh lebih andal dan kecil kemungkinannya macet jika pengguna bekerja dengan banyak spreadsheet, tetapi juga jauh lebih pendek, lebih cepat dan lebih mudah untuk menulis.
Sebagai bonus tambahan, jika Anda selalu memberi nama variabel "wb" dan "ws", Anda dapat menyalin dan menempelkan kode dari satu buku ke buku lainnya dan biasanya akan bekerja dengan perubahan minimal yang diperlukan, jika ada.
sumber
ThisWorkbook
... Saya tidak yakin komentar Anda akurat.Ini adalah contoh yang akan menghapus konten sel "A1" (atau lebih jika jenis pilihannya adalah xllastcell, dll). Semua dilakukan tanpa harus memilih sel.
Saya harap ini membantu seseorang.
sumber
Workbook(WorkbookName).Worksheets(WorksheetName).Range("A1").ClearContents
satu baris dan bukan dua, dan benar-benar berfungsi tanpa memilih sel.