Excel và VBA: Các tips về cải tiến tốc độ, memory...

Liên hệ QC

ThangCuAnh

Mới rờ Ét xeo
Tham gia
1/12/17
Bài viết
896
Được thích
792
Giới tính
Nam
Nghề nghiệp
Coder nghỉ hưu, RCE dạo
Lang thang MSDN, tìm hiểu về viết xll file cho Ét xeo, thấy có bài này hay hay, nên post lên đây chia sẽ cho bà con đọc khi rảnh rỗi.
Không bổ bề dọc cũng bổ bề ngang, chịu khó Gấu gồ Translate chút :)
Mình thì biết được thêm về vụ Value2, trước giờ ít để ý tới nó, cứ dùng Value
https://docs.microsoft.com/en-us/of...-tips-for-optimizing-performance-obstructions
 
Những cái không nên tối ưu hóa trong VBA

Tối ưu hóa không phải là chuyện đơn giản, dễ làm. Nó đòi hỏi thời gian, kinh nghiệm, đo tới đo lui, kiên nhẫn.
Nhưng nhiều khi chúng ta dễ sai trong các vấn đề sau, nó không optimize lên được chút nào cả.
Hì hì, nói chung là nhiều vấn đề "nắm nuôn", nhưng cu anh tui nhớ gì viết đó thôi nhen.

1. Vòng lặp For
VD:
Mã:
For i = LBound(arr) To UBound(arr)
    Total = Total + arr(i)
Next i
Có bạn sẽ optimize lại thành:
Mã:
Dim LB As Long, UB As Long
LB = LBound(arr)
UB = UBound(arr)
For i = LB To UB
   Total = Total + arr(i)
Next
Hì hì, không nhanh hơn chút nào đâu. VB/VBA hơi stupid, nhưng nó đủ thông minh để tính toán, xác định cận dưới, cận trên của vòng For chỉ 1 lần duy nhất, ở bắt đầu vòng For, chứ không tính toán lại với mỗi lần lặp.
Tuy nhiên, nếu trong vòng For, bạn phải truy xuất UBound hay LBound của arr vài lần, thì mới nên dùng cách 2, lợi được vài mã Assembly

2. If:
Mã:
A
If condition Then statement
Và:
Mã:
B
If condition Then
   statement
End If
Cái nào nhìn ngắn hơn, ừ, cái trên, A, nhưng cái nào nhanh hơn, à: Như nhau cả, A B như nhau. Viết như B thì dễ đọc, dễ hiểu hơn.
Tương tư như:
Mã:
If A Then If B Then If C Then ....
Nên viết If Then... End If tường minh ra từng dòng riêng biệt.
Và nhiều bạn hay viết : A : B : C... trên 1 dòng, nhìn cho code nó ngắn ;). Hì hì, cũng vậy à, mà thêm khó đọc, khó hiểu, khó bảo trì, nâng cấp.... Nó chả mang lại cho bạn hơn chút tốc độ nào đâu. Nên viết A B C trên từng dòng riêng biệt, để các bạn dể đọc, dễ debug, đặt breakpoint, run to cursor hay set next statement....

3. Không dùng Like hay TypeName:
2 cái này thấy hay, tiện dụng, nhưng cái gì cũng có giá của nó, không ai cho không ai cái gì. Càng đa năng thì nó càng chậm, phải làm đủ mọi thứ trong ruột của nó. Nên dùng InStr hay các hàm string khác thay thế cho Like, VarType thay thế cho TypeName.

4. Hàm StrComp với Option Comapre Text hay parameter vbTextCompare:
Tương tự, StrComp không chỉ đơn thuần là compare text ignore case, nó dùng trong ruột rất nhiều hàm API liên quan tới locales, languages của Windows, thì dĩ nhiên, nó phải hy sinh tốc độ.
Vì vậy nên dùng vbBinaryCompare, cấp thiết lắm mới dùng vbTextCompare.

5. Không dùng khai báo kiểu Dim xxx As New yyyy
Nhìn thì thấy nó ngắn hơn đấy, chỉ mất có 1 dòng à, vừa khai báo, vừa khởi tạo "nuôn". Sướng ;)
So với:
Mã:
Dim obj As MyClass
Set obj = New MyClass
Hì hì, nhưng nên dùng khai báo, khởi tạo trên 2 dòng riêng biệt. Không bao giờ được dùng Dim obj As New MyClass.
Lý do là nếu biến obj khai báo kiểu đó, nó sẽ được VBA đưa vào dạng biến auto-instantiated (tự động khởi tạo). Về sau, bất kỳ khi nào bạn truy xuất, dùng biến obj, VBA sẽ sinh ra thêm code kiểm tra xem biến obj đã được khởi tạo chưa, nếu chưa thì tự khởi tạo lại. Điều này sẽ làm chậm đáng kể tốc độ của code.
Vd:
Mã:
Dim obj as xxx
obj.yyy = zzz
Set obj = Nothing
obj.aaa = bbb
Thì obj lại được VBA tự động khởi tạo lại. Bug logic của chúng ta có thể sẽ phát sinh ở đây.

6. Kiểu dữ liệu số:
Thường ta thấy size Byte, Boolean and Integer nhỏ hơn biến Long (32bit) hay LongLong (64bit), ta nghĩ dùng nó sẽ được lợi hơn về memory, chắc sẽ lợi hơn về speed. Tuy nhiên, chả có lợi hơn gì cả. Tốc độ truy xuất, thao tác với kiểu dữ liệu Long (32bit) hay LongLong (64bit) nhanh hơn nhiều so với các kiểu data kia. Do tập lện của CPU mà thôi. Truy xuất kiểu nhỏ hơn bắt VBA phải compile ra code and, or, shl, shr... tá lã âm binh để lấy phần nhỏ. Và các biến đó được VBA cấp phát theo memory align, 4 byte, 8 byte hay 16 byte. Nên chả lợi được memory bao nhiêu cả.

7. Dùng biến Static:
Biến Static và biến Dim không có thằng nào hơn thằng nào về speed. Static thì được cấp phát ở memory chung, Dim thì ở stack. Truy xuất biến ở stack thì nhanh hơn vài xung CPU so với trên memory. Nhưng không đáng kể, nên chúng ta không cần quan tâm. Chỉ nên dùng Static khi chẳng đặng đừng. Kiểu tương đương trong Delphi là assign-able type constant.

8. Redim Preserve
Chúng ta thường có xu hướng viết như vầy, nghĩ là sẽ tiết kiệm được memory:
Mã:
ReDim Preserve myarray(UBound(myarray) + 1)
Chỉ cấp phát thêm + 1 phần tử (4, 8, 12 hay 16 byte). Nhưng nếu lệnh đó lặp đi lặp lại trong vòng For, While... thì code của chúng ta sẽ cực kỳ chậm. Nếu array có size nhỏ thì coi như không đáng kể, bỏ qua, nhưng nếu array có size phình ra lớn, VBA và OS phải làm việc mệt mõi để thỏa cái yêu cầu phình ra có chút xíu chút xiu đó của bạn.
Chúng ta nên cấp phát phình ra từng block lớn, ví dụ double size lên, sau cùng cần thiết thì Redim Preserve lại, không cần thiết thì thôi. Dùng xong Erase luôn để giải phóng memory
Mã:
For xxx
    If arrayindex > UBound(myarray) Then
        ReDim Preserve myarray(UBound(myarray) + 1000)
    End If

9. Dùng With
Nhiều bạn lầm tưởng dùng With để truy xuất tới các properties, methods của object sẽ nhanh hơn nhiều nếu không dùng With. Thật ra thì khác nhau không đáng kể. Nếu chỉ dùng With với truy xuất 1, 2 properties, methods của object thì không cần.

10. Dùng !
Nhiều bạn tui thấy hay dùng cái này. Nhìn thì thấy code ngắn và optimize. Nhưng thực ra thì cuối cùng nó lại làm code chậm hơn. Nó liên quan đến late-binding (liên kết trễ). Chi tiết thì dài dòng, biết vậy được rồi ;)

11. Dùng DLL hay OCX viết bằng ngôn ngữ khác trong Excel/VBA
Mới thì thấy có vẻ chắc sẽ nhanh hơn rất nhiều đấy. Nhưng "chia buồm" là chưa chắc. VBA đã phát triển nhiều tới nay, code ASM nó sinh ra trong quá trình thông dịch (interpreter) đã rất thông minh và rất nhanh rồi, không thua các compiler hiện đại bây giờ đâu.
Nhiều tác vụ thực thi trực tiếp bằng VBA code còn nhanh hơn native code của 3rd party DLL, OCX nếu coder của 3rd party DLL OCX đó viết không tốt, không optimize.
.....
Phù, tạm dừng ở đây, gõ mỏi cả tay. Kỳ sau viết tiếp. Nhớ gì, thấy gì viết đó. Mong bà con vào đọc, phê phán, tranh luận, chỉ trích, chê bai...và cả chửi bới ;)
 
Lần chỉnh sửa cuối:
Nói thì nghe vậy chứ ông nội tui cũng chả biết trình dịch Vi bi ê đưa ra cốt Ê ét em như thế nào đâu mà tranh với luận.
 
Và mấy bài hỏi trên GPE toàn bé tẹo teo, tối ưu có khi làm chậm hơn
 
Gạt ngoài cái vụ Ê ét em, chúng ta nói chuyện thực tiễn trước mắt đi.
Thực tiễn trước mắt tức là ngữ cảnh GPE

1. Vòng lặp For:
VB/VBA hơi stupid, nhưng nó đủ thông minh để tính toán, xác định cận dưới, cận trên của vòng For chỉ 1 lần duy nhất
Có lẽ bạn lầm với C/C++ rồi mới có chuyện "thông minh". Vòng lặp For đối với các ngôn ngữ cổ điển như Basic thì nó chỉ tính đích 1 lần. Luật định vậy. Dẫu bên trong vòng lặp cái đích có bị dời thì nó cũng không màng.
(Đối với GPE, cái vụ tính UBound trước chẳng qua là tại vì người ta hay lồng nhiều vòng lặp vào nhau. Nếu không tính trước thì quả là mỗ̃i lần lặp phải tính lại))

2. If :
If condition Then statement
Và:

If condition Then
statement
End If

Cái nào nhìn ngắn hơn, ừ, cái trên, A, nhưng cái nào nhanh hơn, à: Như nhau cả, A B như nhau. Viết như B thì dễ đọc, dễ hiểu hơn.
"Dễ đọc, dễ hiểu" tùy theo cái "condition" kia nó dài hay ngắn - common sense thôi
Theo chủ quan tôi thì
If (bool1) Then If (bool2) Then If (bool3) Then Call ABC
dễ đọc hơn. Bởi vì vài cái If-End If là thấy cái câu Call ABC nó thụt tuốt luốt vô trong. Và đi mò số End If cực bỏ bố.
Tuy nhiên, nếu ba cái mớ bool1/2/3 nó dài thòng lòng thì thằng Call ABC cũng bị thụt không còn chỗ đứng.
(Đố́i với GPE, có lẽ bạn nên phê phán cái vụ dùng ":" để nói dòng kép thì có lẽ thực tế hơn)

3. Không dùng TypeName:
TypeName là legacy code. Giản dị hơn VarType.
Vả lại, hai cái này có công dụng khác nhau.
(Đói với GPE, hầu hết các trường hợp TypeName được dùng để tìm dạng Control Object)

4. Hàm StrComp với Option Comapre Text hay parameter vbTextCompare:
(Hàm này ở đâyt ít dùng lắm, khỏi phải lo)

5. Không dùng khai báo kiểu Dim xxx As New yyyy
(Lệnh này ở đây ít dùng vô cùng, khỏi lo)

6. Kiểu dữ liệu số:
Hiểu chết liền. Thôi thì khỏi bàn.

7. Dùng biến static:
Chịu thua. Hồ̀i nào giờ tôi cứ ngỡ biến static chỉ dùng vào những trường hợp đặc biệt mà ta muốn giữ nó lại sau khi thoát khỏi hàm, ví dụ kết nối CSDL. Ai hơi đâu so sánh tốc độ stack và heap.
(Ở GPE người ta dùng biến toàn cục/global. Khong có mấy người nắm bắt được kỹ thuật của static đâu, khỏi lo)

8. Redim Preserve
Block allocation là kỹ thuật cao, cần hiểu rõ về bản chất của nó.
(Ở GPE không có mấy người nắm vững luật chỉ số mảng đâu, nói đến cái này xa vời quá)

9. Dùng With
Nó chỉ là phép khai báo namespace thôi chứ đâu có liên quan gì đến tốc độ? Hay là có gì ngoài kiến thức của tôi?

10. Dùng ! (Bang notation)
VBA có cả đống kiểu viết tắt như vầy. Chả quan trọng mấy
(GPE chả có ai dùng cái này cả)

11. Dùng DLL hay OCX viết bằng ngôn ngữ khác trong Excel/VBA
Cái này thì ngoài vòng hiểu biết của tôi.
(Nhưng với GPE thì nó là cả một hứng thú, bảo họ đừng dùng thì ác quá)

-----

Túm lại, cái quan trọng là sử dụng ngầm Evaluate thì chả thấy nói tới.
[A1] thay cho Range("A1")
 
1. Vòng lặp For:
VB/VBA hơi stupid, nhưng nó đủ thông minh để tính toán, xác định cận dưới, cận trên của vòng For chỉ 1 lần duy nhất
Có lẽ bạn lầm với C/C++ rồi mới có chuyện "thông minh". Vòng lặp For đối với các ngôn ngữ cổ điển như Basic thì nó chỉ tính đích 1 lần. Luật định vậy. Dẫu bên trong vòng lặp cái đích có bị dời thì nó cũng không màng.
Nhất trí.
Nếu cho là thông minh thì Delphi cũng thông minh. Trong Delphi cận dưới, cận trên cũng chỉ được tính 1 lần trước khi vào vòng lặp
3. Không dùng TypeName:
TypeName là legacy code. Giản dị hơn VarType.
Vả lại, hai cái này có công dụng khác nhau.
(Đói với GPE, hầu hết các trường hợp TypeName được dùng để tìm dạng Control Object)
Nhất trí.
Vd. nếu Dim a As Variant và hiện thời a đang "chứa" Range thì TypeName trả về "Range" trong khi VarType trả về 8204. Chả biết nó là cái gì.
7. Dùng biến static:
Chịu thua. Hồ̀i nào giờ tôi cứ ngỡ biến static chỉ dùng vào những trường hợp đặc biệt mà ta muốn giữ nó lại sau khi thoát khỏi hàm, ví dụ kết nối CSDL. Ai hơi đâu so sánh tốc độ stack và heap.
(Ở GPE người ta dùng biến toàn cục/global. Khong có mấy người nắm bắt được kỹ thuật của static đâu, khỏi lo)
Nhất trí.
Khi người ta dùng Static thay Dim không phải là do cái nào hơn thua về tốc độ. Dùng Static là do nhu cầu thôi. Nếu không có nhu cầu như bác chỉ ra thì cũng hiếm ai dùng Static. Ở đây cơ sở mà người ta quyết định dùng hay không đó là nhu cầu chứ chả ai bàn tới tốc độ.
9. Dùng With
Nó chỉ là phép khai báo namespace thôi chứ đâu có liên quan gì đến tốc độ? Hay là có gì ngoài kiến thức của tôi?
Theo tôi có nhanh hơn. Vd.

Tới Hà Nội, phố Hàm Long, số nhà 4.Cô Nga.Mầu mắt
Tới Hà Nội, phố Hàm Long, số nhà 4.Cô Phương.Mầu tóc
Tới Hà Nội, phố Hàm Long, số nhà 4.Cô Phương.Đi cắt mí
Tới Hà Nội, phố Hàm Long, số nhà 4.Cô Lan.Đi chợ

Ông A phải thực hiện 4 lần các bước: Đi tới Hà Nội, từ đó đi tới Hàm Long, tiếp theo đi tới số 4.

Nếu
With Tới Hà Nội, phố Hàm Long, số nhà 4
.Cô Nga.Mầu mắt
.Cô Phương.Mầu tóc
.Cô Phương.Đi cắt mí
.Cô Lan.Đi chợ
End With

Thì ông A chỉ Đi tới Hà Nội, từ đó đi tới Hàm Long, tiếp theo đi tới số 4một lần rồi từ chỗ ấy thực hiện 4 việc.

Như vậy có nhanh hơn. Nhưng nếu các việc kia ít thì nhanh hơn chả là bao nhiêu. Tất nhiên nếu việc ít nhưng ở trong vòng lặp lớn thì Tổng(chả đáng là bao) sẽ lớn. Tức lúc đó dùng With cũng nhanh hơn đáng kể.
 
Những cái không nên tối ưu hóa trong VBA
...
...

Bài viết rất bổ ích đó bạn ..CuAnh.
Nếu có thời gian bạn phân tích luôn giùm 2 cái này nhe:
- If ... else .. then so với Select Case. (giải thuật giống nhau, chỉ là liệt kê, chọn điều kiện nào thì code xử lý theo điều kiện đó thôi)
- Dùng kiểu dữ liệu Yes/No so với kiểu Number dùng 0 và 1.

Cảm ơn.
 
Túm lại, cái quan trọng là sử dụng ngầm Evaluate thì chả thấy nói tới.
[A1] thay cho Range("A1")
Cái này nhiều người còn tự hào vì mình biết sử dụng đấy anh, Cái này em ít sài lém, dùng nó cứ như dùng dao hai lưỡi, chưa điệu nghệ nên không dám sài.
 
2 bạn ongke0711:
- Về mặt mã máy thì kiểu dữ liệu Boolean và kiểu Number 0, 1 nó xem như là tương đương nhau bạn. Compiler nó không biết True/False là gì đâu, nó chỉ biết 0, 1, -1 thôi và thao tác trên các number đó thôi.
- Case bình thường thì không nói, chứ Case Is, Case Like... thì rõ ràng phải khác If Else rồi, còn khác như thế nào thì tùy trường hợp.
Về mặt ASM thì If, Case gì cũng chỉ là nhưng lệnh compare và jump. Case thì có thêm Case Jump Table, tốn thêm 1 chút memory.

Giờ cu anh tui đi ăn sáng đã, chút về viết tiếp, trả lời cho 2 bác VetMini và batman.
Ăn sáng xong nặng bụng, lười, hết hứng viết tiếp rồi ;)
 
Lần chỉnh sửa cuối:
Giải thích thì dài dòng, lòng vòng "nắm nuôn", nên mình gợi ý cho các bạn tự tìm hiểu.
Đầu tiên các bạn vào trang này:
Upload file VBEx.dll trên máy bạn lên, vào xem phần Export.
rtc là viết tắt của chữ Runtime Code, bỏ chữ rtc đi, các bạn nhìn có thấy quen quen không. Đó chính là các hàm thực sự VBA mà các bạn hay dùng, hay code đấy.
Ví dụ trong hình:
rtcLeftBstr = Left$()
rtcLeftVar = Left()
rtcRightBstr = Right$()
rtcRightVar = Right()
rctTrimBstr = Trim$()
rctTrimVar = Trim()
....
Bài sau tui sẽ nói rõ hơn, chi tiết hơn về cái vụ có $ với không có $ này. Tốc độ khác nhau đáng kể đó.
Còn nhiều hàm internal, không được export của VBA nữa, nhưng các bạn không cần quan tâm. Nếu có tool và get MS pdb symbol của VBExxx.dll về, các bạn sẽ thấy rõ hơn.
Giờ muốn xem mã ASM hay pesuedo C/C++ code của các hàm này, thì các bạn cần các tool chuyên về debug, diassembly, discompile... như OllyDbg, WinDbg, x64dbg, IDA, Ghidra... (nhiều mênh mông). Nhưng thôi đụng tới đống tool này phiền phức, nhức đầu "nắm nắm nuôn".
Code VBA của các bạn sẽ được VBA thông dịch, dịch ra assembly code, gọi các hàm export này và các hàm internal khác để thực thi.
Kéo xuống dưới chút các bạn sẽ thấy hàm rtcTypeName và rtcVarType. Đây chính là hàm VarType và TypeName đó.
 

File đính kèm

  • 1.png
    1.png
    69.1 KB · Đọc: 17
Lần chỉnh sửa cuối:
Xin lỗi lộn bài...................
 
Lần chỉnh sửa cuối:
Đang nói về VBA dll, bạn Mạnh lại nhảy vào với cái VBLibrary chi vậy. Qua bên kia ;)
Đã nói là các hàm được dll export ra ngoài mà, chứ có phải các hàm internal đâu mà "thét mét"
 
Những gì tôi nói ở bài #5 là đã tới giới hạn tình độ của tôi rồi. Trên nữa thì tôi chịu thua, ai muốn vẽ rồng vẽ rắn thì vẽ, mười ngón tay của tôi chỉ biết bắt chước Trạng Quỳnh vẽ giun thôi.

Chú thích: hồi nào mình cứ ngỡ Microsoft viết lại mấy cái hàm (điển hình, nhóm không có $) là để phù hợp với phong trào hướng đối tượng chứ. Mà đã hướng đối tượng thì chịu khó chậm 1 chút cũng chả sao. Té ra mình bị mấy thằng developers của MS nó gạt.
 
Lần chỉnh sửa cuối:
Hì hì, được cái này phải mất cái kia thôi, nhận biến ông nội variant đa mang, mang đủ thứ được thì phải chịu hy sinh tốc độ chứ ;)
Đã nói là không có gì miễn phí, cho không mà,
 
Nói thẳng là tôi lười lắm. Tốc độ là cái xếp cuối bảng của tôi.
Đi xe nóng thì cứ việc mở máy lạnh. Ai hơi đâu đế ý đến việc máy lạnh làm xe chạy yếu đi.
 
Bác không quan tâm thì thôi, bỏ qua topic này đi. Chứ tui thấy vẫn có người khác quan tâm mà. Khi nào ai cũng chê chán, dỏm thì tui mới không viết nữa ;)
KKK, vẫn còn người like thấy chưa bác VetMini ;)
Hì hì, còn cười thì không biết tính sao, xếp vô loại nào.
 
Lần chỉnh sửa cuối:
Tôi cũng nghĩ là tốc độ thường không phải là mục đích.
Có những code đặc biệt nó bắt buộc phải chạy nhanh do tính chất công việc đòi hỏi. Nhưng đại đa số không đòi hỏi bắt buộc về tốc độ. Lúc đó tốc độ cũng quan trọng nhưng không phải quan trọng nhất. Quan trọng hơn cả là code đơn giản, dễ hiểu, dễ bảo trì, dễ kiểm soát v...v Nếu được thế rồi mà có thể cải tiến thêm tốc độ thì quá tốt. Nhưng khi có xung đột, tức khi phải hi sinh một trong 2, thì thường người ta hi sinh tốc độ. Viết một code chạy nhanh hơn nhưng phức tạp, rất có thể ngay cả tác giả sau một thời gian đọc lại cũng không hiểu, thì nhanh hơn chút để làm gì.
 
Hì hì, từ từ tui viết ra hết. Không phải "no". Nó không phải là những cái optimize phức tạp, rối rắm về mặt mã máy hay thuật toán đâu. Chỉ là sữa đổi code bình thường thôi. Ví dụ: Left thành Left$ chẵng hạn, có chết thằng tây nào đâu ;)
Mấy bác cứ bàn ra, làm nản lòng chiến sĩ không à.
 
Bài viết rất bổ ích đó bạn ..CuAnh.
Nếu có thời gian bạn phân tích luôn giùm 2 cái này nhe:
- If ... else .. then so với Select Case. (giải thuật giống nhau, chỉ là liệt kê, chọn điều kiện nào thì code xử lý theo điều kiện đó thôi)
- Dùng kiểu dữ liệu Yes/No so với kiểu Number dùng 0 và 1.

Cảm ơn.
Ở bài #5 tôi có nói về "code cổ điển" và vòng lặp For. (*)
Khi ấy tôi đoán là sẽ có bạn thắc mắc.
Thớt, như lời tự xưng, là người chuyên về cải tiến tốc độ code cho nên không có thì giờ để giải thích cho bạn về căn bản code đâu.

Trên căn bản, phạm vi và nhiệm vụ của lệnh quan trọng hơn tốc độ của nó.
Điển hình, If/Then/Else không hẳn là giải thuật giống với Select/Case.
Hầu hết các ngôn ngữ, If/Then/Else có phạm trù giống nhau. Nhưng Select/Case thì chưa chắc. Điển hình là trong C/C++ thì đường chạy tự động tuột từ Case này sang Case kế tiếp, (C# rắc rối hơn một chút). Nhưng VBA thì không, bắt đầu của một Case là chấm dứt Case xếp trước nó.

Trong VBA, nếu một Case chưa thỏa thì Case kế tiếp sẽ được xét, nếu thỏa rồi thì các Case kế sẽ bị bỏ qua, tương đối giống Else If. Điều này rất quan trọng cần phải biết khi bạn dùng hàm để tính giá trị của Case.
Chay thử code này để biết tôi nói gì:
Sub t()
For a = 1 To 3
MsgBox "a = " & a
Select Case a
Case fff(1)
MsgBox "inside case " & a
Case fff(2)
MsgBox "inside case " & a
Case Else
MsgBox "inside case else"
End Select
Next a
End Sub
' ----
Function fff(a)
MsgBox "function run at case " & a
fff = a
End Function

Select/Case và If/Then/Else cái nào nhanh hơn? Câu này chỉ giành cho dân bàn nhậu đánh cá nhau.
Trường hợp nào thì cái nào ưu thế hơn mới là câu hỏi bạn cần đặt ra.
Câu trả lời điển hình nhất là dùng Select/Case khi:
1. trị cần xét là một biểu thức mà bạn không muốn tính nhiều lần (với If thì phải cho vào mộ̣t biến rồi so sánh nhiều lần)
2. trị cần xét được so với nhiều trị, nhiều đoạn, và dùng biểu thức lô gic của If rất dài dòng.
Điển hình
Select Case a+b+c
Case 1, 2, 100 to 999
...
Case ...
End Select
Nếu dùng If/Then/Else sẽ thấy khá luộm thuộm.

(*) cách hoạt đọng của For toi đã từng nói khá rõ trong mọt thớt cách đây vài năm. Tưởng khong cần lập lại.
 
Lần chỉnh sửa cuối:
Web KT

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

Back
Top Bottom