Tại sao dùng một biến Variant để thay thế một biến Variant trong biến của hàm tự tạo? (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Hoàng Trọng Nghĩa

Chuyên gia GPE
Thành viên BQT
Moderator
Tham gia
17/8/08
Bài viết
8,662
Được thích
16,725
Giới tính
Nam
Tôi thấy các cao thủ thường viết hàm mà trong đó có biến Variant (có thể là biến dành cho một mảng) và tôi cũng thường làm như thế (tôi chưa phải là nhà logic toán học như Thầy siwtom nên thấy các cao thủ làm sao thì mình làm vậy).

Chẳng hạn hàm này:

Mã:
Function Unique2D(ByVal [COLOR=#ff0000][B]Expression [/B][/COLOR]As Variant) As Variant
    Dim SourceArray As Variant
    [COLOR=#ff0000]SourceArray = Expression[/COLOR]
    
    '......
    '......
    '......
End Function

Vậy xin vui lòng cho hỏi, ta không thay thế được không, ta làm trực tiếp bằng biến đó được không? Nếu không làm thế thì tiềm ẩn những lỗi gì?

Tôi hỏi như vậy vì có lý do khách quan cho việc thử nghiệm 2 thủ tục dưới đây (test với Excel 2007 trở lên):

Mã:
Sub Macro1()
    Dim FirstArray, LastArray, T As Double
    T = Timer
    [COLOR=#ff0000]FirstArray = Sheet1.Range("A1:H500000").Value[/COLOR]
    MsgBox Timer - T
    'Erase FirstArray
End Sub
'---------------------------------------------------
Sub Macro2()
    Dim FirstArray, LastArray, T As Double
    T = Timer
[COLOR=#ff0000]    FirstArray = Sheet1.Range("A1:H500000").Value
   [/COLOR][COLOR=#0000ff] LastArray = FirstArray[/COLOR]
    MsgBox Timer - T
    'Erase FirstArray, LastArray
End Sub

Thời gian "nhận" giá trị của biến, và thời gian biến khác "nhận" lại giá trị của biến này quả thật đã chiếm thời gian rất nhiều.

Xin được giải thích và chỉ rõ những vấn đề trên giúp tôi nhé!

Cảm ơn rất nhiều.
 

File đính kèm

Lần chỉnh sửa cuối:
Tôi thấy các cao thủ thường viết hàm mà trong đó có biến Variant (có thể là biến dành cho một mảng) và tôi cũng thường làm như thế (tôi chưa phải là nhà logic toán học như Thầy siwtom nên thấy các cao thủ làm sao thì mình làm vậy).

Chẳng hạn hàm này:

Mã:
Function Unique2D(ByVal [COLOR=#ff0000][B]Expression [/B][/COLOR]As Variant) As Variant
    Dim SourceArray As Variant
    [COLOR=#ff0000]SourceArray = Expression[/COLOR]
    
    '......
    '......
    '......
End Function

Xin được giải thích và chỉ rõ những vấn đề trên giúp tôi nhé!

Cảm ơn rất nhiều.
Vụ này nói từ đời nào rồi, giờ lại hỏi sao trời
Chuyển mọi thứ sang biến phụ là để phòng trường hợp biến đầu vào là 1 Range
Ví dụ khi sử dụng ta viết Unique2D(Range("B2:E100")) ----> Khi ấy sẽ không lường được những rắc rối có thể xảy ra
Vậy nên SourceArray = Expression, xong xử lý mọi thứ từ biến tạm là yên tâm nhất
(Nhớ đã đố trong mục Đố vui về VBA rồi thì phải)
 
Lần chỉnh sửa cuối:
Upvote 0
Vụ này nói từ đời nào rồi, giờ lại hỏi sao trời
Chuyển mọi thứ sang biến phụ là để phòng trường hợp biến đầu vào là 1 Range
Ví dụ khi sử dụng ta viết Unique2D(Range("B2:E100")) ----> Khi ấy sẽ không lường được những rắc rối có thể xảy ra
Vậy nên SourceArray = Expression, xong xử lý mọi thứ từ biến tạm là yên tâm nhất
(Nhớ đã đố trong mục Đố vui về VBA rồi thì phải)

Chính vì thế em mới hỏi đấy!

Cho nên hàm bị chậm là do 3 công đoạn!

Công đoạn đầu là biến trong hàm nhận giá trị từ công thức

Công đoạn hai là biến phụ nhận giá trị từ biến hàm

Công đoạn cuối là Tên hàm nhận lại giá trị từ một biến khác sau xử lý.

Chính vì thế, để tăng tốc, ta loại trừ bớt công đoạn nào được không?

Với số lượng hàng ít thì không thấy, với vài trăm ngàn đến cả triệu dòng thì mới thấy biến nó nhận giá trị lâu đến cỡ nào!
 
Upvote 0
Ta thử dùng cách của Anh Duyệt xem có nhanh hơn không?

Anh ơi,
Mã:
With CreateObject("Scripting.Dictionary")
        [COLOR=#ff0000][B]If Not TypeOf SrcArray Is Range Then[/B][/COLOR]
            For Each Item In SrcArray
                If Not .Exists(Item) And Item <> "" Then .Add Item, ""
            Next
        Else
            For Each Item In SrcArray.Value
                If Not .Exists(Item) And Item <> "" Then .Add Item, ""
            Next
        End If
        UniqueList = .Keys
End With

PS: Anh ơi làm hoài không có thưởng gì hết. Hu hu hu !

Mà nghĩ cũng lạ, tại sao phủ định của TypeOf trong khi có Else nhỉ?

Thay vì như ở dưới cũng bớt đi một chút tính toán. (kiến tha lâu đầy tổ)

Mã:
With CreateObject("Scripting.Dictionary")
        If TypeOf SrcArray Is Range Then
            For Each Item In SrcArray.Value
                If Not .Exists(Item) And Item <> "" Then .Add Item, ""
            Next
        Else
            For Each Item In SrcArray
                If Not .Exists(Item) And Item <> "" Then .Add Item, ""
            Next
        End If
        UniqueList = .Keys
End With

 
Lần chỉnh sửa cuối:
Upvote 0
Một phát hiện cực kỳ mới, nhằm tăng tốc khi sử dụng hàm mảng.

Nếu nhập đối số trong hàm là một RANGE thay vì một ARRAY thì sẽ nhanh hơn gần gấp đôi thời gian!

Khi thử nghiệm với Excel 2003, với 65536 dòng, tôi đã phát hiện ra như thế!

Mã:
[COLOR=#0000cd][B]Function Test3(ByVal Arr As Variant)[/B]
    Dim sArr
    sArr = Arr
    Test3 = sArr
End Function
[/COLOR]
[B]Sub [COLOR=#008080]mcrRANGE[/COLOR]()[/B]
    'Tham chieu la mot RANGE
    Dim T As Double, j As Double
    T = Timer
    [COLOR=#008080]Test3 Sheet1.Range("A1:H65536")[/COLOR]
    j = Timer - T
    MsgBox j
    Sheet1.Range("I1000").End(xlUp).Offset(1).Value = j
End Sub

[B]Sub [COLOR=#ff0000]mcrARRAY[/COLOR]()[/B]
    'Tham chieu la mot ARRAY
    Dim T As Double, j As Double
    T = Timer
    [COLOR=#008080]Test3 Sheet1.Range("A1:H65536")[/COLOR][COLOR=#ff0000].Value[/COLOR]
    j = Timer - T
    MsgBox j
    Sheet1.Range("J1000").End(xlUp).Offset(1).Value = j
End Sub

Các bạn thử tải file về kiểm chứng xem sao.
 

File đính kèm

Upvote 0

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

Back
Top Bottom