Saya menulis sebuah fungsi di VBA dan telah menyediakan versi yang disederhanakan di bawah ini. Pada dasarnya, dibutuhkan argumen, membentuk sebelumnya vlookup
pada rentang bernama dalam lembar menggunakan nilai argumen, meneruskan nilai vlookedup ke fungsi lain, dan akhirnya mengembalikan hasilnya.
Saya menggunakan fungsi ini banyak .. seperti 50.000 kali di buku kerja saya. Akibatnya, buku kerja saya cukup lambat untuk dihitung.
Apakah ada beberapa perubahan sederhana yang dapat saya lakukan pada fungsi ini untuk mengoptimalkannya untuk kecepatan?
Keterbacaan bukan masalah, saya hanya ingin membuat hal ini berjalan lebih cepat. Kode harus tetap di VBA.
Public Function Yield(Name As String, Price As Double)
Dim DDate As Double
Dim ConversionFactor As Double
DDate = Application.WorksheetFunction.VLookup(Name, Range("LookupRange"), 3, 0)
ConversionFactor = Application.WorksheetFunction.VLookup(Name, Range("LookupRange"), 7, 0)
Yield = 100 * Application.Run("otherCustomFunction",DDate,ConversionFactor,Price)
End Function
microsoft-excel
worksheet-function
vba
optimize
rvictordelta
sumber
sumber
Jawaban:
Strategi pertama: optimalkan fungsi itu sendiri
Seharusnya menggandakan kecepatan
Ini karena Anda hanya mencari rentang dengan nama "LookupRange" sekali bukan dua kali dan Anda hanya mencari garis yang tepat satu kali, bukan dua kali.
Strategi kedua: ambil rentang hanya sekali di muka
Mungkin 4 kali lebih cepat
Jika kita mengambil rentang dalam kode yang menggunakan
yield
fungsi, kita hanya perlu melakukannya sekaliAda varian dari strategi ini di mana Anda menyatakan Pencarian di luar semua rutinitas, seperti yang saya lakukan dengan kamus di bawah ini ..
Strategi ketiga: Masukkan semua nilai yang relevan dalam kamus
Urutan besarnya lebih cepat jika Anda menelepon
Yield
SANGAT sering.Name
s dalam kamus, yang jauh lebih efisien daripada mencari dalam kisaranIni kodenya:
sumber
Name
yang biasanya Anda lihat dalam satu siklus pemrosesan.Beberapa hal yang akan saya lakukan -
Ketika Anda melewati argumen Anda, secara default, berikan mereka ByRef yang lebih lambat dari ByVal dan melihat bagaimana Anda tidak perlu referensi, hanya berikan saja
ByVal
.Saya tidak yakin
match
jauh lebih cepat daripadavlookup
tetapi dengan menggunakanmatch
Anda memotong proses Anda setengah dan hanya referensi baris yang Anda butuhkan.Saya juga mengonversi variabel ke nama konvensi penamaan VBA Standar .
Anda juga tidak perlu
Application.run
untuk memanggil makro Anda. Pastikan itu juga melewati argumen ByValsumber
LookupRange
agar cocok untuk bekerja ketika mendefinisikanfoundRow