Về tốc độ xử lý của hàm Select Case trong VBA

Liên hệ QC

70211119

Thành viên mới
Tham gia
10/10/12
Bài viết
27
Được thích
5
Em kính chào Anh chị trọng diễn dàn ạ.
Em đang cố xây dựng 1 function() tự tạo trong vba kiểu như sau ạ. Do hàm cũng đơn giản nên em không up file. Nội dung thì sẽ lấy 2 ký tự đầu của chuỗi, đối chiếu với các trường hợp để trả kết quả tương ứng.
Mã:
Function giatien (chuoi as string) as string
Temp = Left(chuoi,2)
Select Case temp
Case "01"
Giatien = 240000
Case "02"
Giatien =320000
Case "18"
Giatien = 110000
[...20 case khác...]
Case else
Giatien = 0
End Celect
End Function
Cấu trúc hàm thưc tế của em có khoảng 20 case kiểu vậy.
Dữ liệu của e khoảng 50.000 dòng nên khi chạy hàm thì xử lý khá là chậm.
Em nhờ anh chị trong diễn dàn góp ý giúp em xây dựng một hàm có chức năng tương tự mà nhanh hơn được không ạ?
Em xin chân thành cảm ơn.
 
Select Case là đúng quy định của trường hợp xét các trị số khác nhau của một biểu thức.
Cũng như If-ElseIF-Else người viết code biết dực liệu của mình rơi vào trị nào nhiều thì đưia trị ấy lên trước. Khả năng "trúng/hit" các trị ấy cao hơn và sẽ cải tiến tốc độ.

Tuy nhiên, nếu giá trị của biểu thức là số thì có thể dùng bảng tra bằng Array để cải tiến tốc độ.

Chú ý: hàm UDF luôn luôn chậm đối với bảng dữ liệu lớn. Nếu cải tiến thì chỉ đến mức nào đó thôi.
 
Select Case là đúng quy định của trường hợp xét các trị số khác nhau của một biểu thức.
Cũng như If-ElseIF-Else người viết code biết dực liệu của mình rơi vào trị nào nhiều thì đưia trị ấy lên trước. Khả năng "trúng/hit" các trị ấy cao hơn và sẽ cải tiến tốc độ.

Tuy nhiên, nếu giá trị của biểu thức là số thì có thể dùng bảng tra bằng Array để cải tiến tốc độ.

Chú ý: hàm UDF luôn luôn chậm đối với bảng dữ liệu lớn. Nếu cải tiến thì chỉ đến mức nào đó thôi.
Nói thật sự anh thông cảm! Tôi biết trình độ của anh là cao thủ rồi.
Nhưng thật sự chúng tôi không biết viết câu từ gì trong VBA
Vậy mong anh chỉ bảo.
Và mong anh viết từ (A-Z)
Chứ mù tịt như chúng tôi thì biết đâu mà mo
 
Em kính chào Anh chị trọng diễn dàn ạ.
Em đang cố xây dựng 1 function() tự tạo trong vba kiểu như sau ạ. Do hàm cũng đơn giản nên em không up file. Nội dung thì sẽ lấy 2 ký tự đầu của chuỗi, đối chiếu với các trường hợp để trả kết quả tương ứng.
Mã:
Function giatien (chuoi as string) as string
Temp = Left(chuoi,2)
Select Case temp
Case "01"
Giatien = 240000
Case "02"
Giatien =320000
Case "18"
Giatien = 110000
[...20 case khác...]
Case else
Giatien = 0
End Celect
End Function
Cấu trúc hàm thưc tế của em có khoảng 20 case kiểu vậy.
Dữ liệu của e khoảng 50.000 dòng nên khi chạy hàm thì xử lý khá là chậm.
Em nhờ anh chị trong diễn dàn góp ý giúp em xây dựng một hàm có chức năng tương tự mà nhanh hơn được không ạ?
Em xin chân thành cảm ơn.
Đặt 1 mảng arrGia = Array(240000, 320000, 110000,...) và mảng arrTemp = Array("01", "02", "18", ...). Dùng vòng lặp for i ... next, nếu arrTemp(i) = Left(chuoi, 2) thì Giatien = arrGia(i): Exit For. Nếu chạy hết mảng mà không tìm thấy thì Giatien = 0.
 
Code hết thì cũng có cái hay, nhưng dữ liệu nó không cơ động lắm, chỉnh mà trật số thì dò chắc @@ hơi bị mệt.
+ Một là nạp thẳng Array bằng tay. Hoặc dùng dictionary nạp key vào, nhưng cảm giác thấy vầy thì đang phức tạp hóa lên.
+ Hai là mình cứ để trong sheet, dùng Vlookup là nhanh :D dễ dò tìm, quản lý.
 
Đặt 1 mảng arrGia = Array(240000, 320000, 110000,...) và mảng arrTemp = Array("01", "02", "18", ...). Dùng vòng lặp for i ... next, nếu arrTemp(i) = Left(chuoi, 2) thì Giatien = arrGia(i): Exit For. Nếu chạy hết mảng mà không tìm thấy thì Giatien = 0.
Không đúng. Đúng kỹ thuật tôi nói là lập một mảng tầm vực toàn cục hằng ngàn phần tử (chả tốn bao nhiêu bộ nhớ).
Và dùng con số làm chỉ số mảng.
Private mang(0 To 1000) As Long
Private mangSet As Boolean ' tham số dùng để nạp trị cho mảng lần đầu tiên

Code bên trong hàm:
...
If Not mangSet Then
mang(2) = 24000
mang(3) = 32000
... ' chỉ có 20 số mà cũng sợ khó quản lý thì đúng là lập luận dân lười.
mangSet = True
End If
GiaTien = mang(CLng(chuoi), 2)) ' đừng có nói với tôi là nếu không phải là số thì code tỏi nghe. Với trình của bạn thì phải biết tự bẫy lỗi hay xét trước khi chuyển số.

Lập luận của bài #6 là lập luận dân lười. Có lẽ do chưa đủ kinh nghiệm về mảng (*1). Đáng ra tôi để mặc nhưng thấy bạn xen vào thì có lẽ lời của tôi sẽ giúp ích cho vài người:
1. làm bằng dictionary cũng đại khái vây. Nhưng dictionary thì không bỏ công cho 20 keys, chỉ nên dùng cho trường hợp trị không phải là số thôi (*2). Dẫu bạn có phải là dân "mê" dictionary hay không thì cũng cần nên biết là không có cách nạp/tra nào nhanh hơn mảng đâu.
Bài toán này quá đặc thù. Không xứng đáng viết dài dòng cho khả năng phát triển rộng hơn.
2. tác giả bài #6 không biết gì về cách sử dụng WorksheetFunction gọi trong VBA nên mới có đề nghị VLookup. Như trên tôi đã nói, không có kỹ thuật nào tra nhanh hơn chỉ số mảng đâu. Nếu bạn có cách test được thời gian thì đó chỉ là trường hợp "sweet spots" thôi.

(*1) nếu để ý thấy mấy hàm chuyển đổi tiếng Việt (đánh dấu/bỏ dấu) người ta đâu có ngại nạp hằng số cho mảng bao gi2. Bài này mới 20 cái đã sợ sai?

(*2) ngày xưa tôi đã từng nói: đừng có tâng bốc dictionary nhiều hơn địa vị của nó. Những người chạy theo hào quang đít sần thường bỏ sót chân giá trị của mảng. Tân thời đương nhiên là đẹp hơn chân quê rồi. Nhưng con người biết tìmm\ hiểu chân quê trước tân thời hầu hết là người khôn ngoan.
 
Hà hà. Bác nói lớn nghĩ sâu, tôi chưa theo kịp. Tôi chỉ đề ra giải thuật lâu nay hay dùng, chưa biết có cải thiện được gì cho thớt không. Thớt mà không test, không phản hồi thì hạ hồi chưa phân giải.
 
Web KT

Bài viết mới nhất

Back
Top Bottom