Giúp đỡ hàm tìm kiếm Lookup bằng VBA (7 người xem)

Liên hệ QC

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

gianghoxaotra

Thành viên chính thức
Tham gia
6/2/13
Bài viết
53
Được thích
1
Hiện tại em đang viết một code VBA thay thế cho hàm VLookup vì hàm Vlookup chạy nhiều chậm máy quá, nhờ các cao thủ trên đây giúp đỡ vì hàm viết không chạy được.
Em mời vào nghề nên cần các cao thủ chỉ giáo dùm thêm. Cảm ơn mọi người.

Đây là Code VBA:
Function MTlookup(Source As Range, VTCV As Integer, Data As Range, ValueCell As Range)

Dim KQ As Object

ReDim KQ(1 To UBound(Data), 1 To 1)

Set Dic = CreateObject("scripting.dictionary")

For i = 1 To UBound(Source)
If Not Dic.exists(CStr(Source(i, VTCV))) Then

Dic.Add CStr(Source(i, VTCV)), i

End If

'Dic(CStr(Source(i, 1))) = i

Next

For i = 1 To UBound(Data)
Itm = CStr(Data(i, 1))
If Dic.exists(Itm) Then

KQ(i, 1) = Source(Dic.Item(Itm), 1)

End If

Next

ValueCell.Resize(i - 1, 1) = KQ


End Function
 
bạn đính lèm file xem sao. Chứ tôi nhìn cái code này phải là 1 thủ tục chứ sao là hàm số được !$@!!
 
Mình gửi file lên nhé, vì mục đích là muốn viết cái hàm thay cho Vlookup để nó chạy nhanh hơn Vlookup.
 
Lần chỉnh sửa cuối:
Mình gửi file lên nhé, vì mục đích là muốn viết cái hàm thay cho Vlookup để nó chạy nhanh hơn Vlookup.

Thường thì hay dùng phương thức nào đó thay hàm số để excel không phải tính toán trên bảng tính thôi. chứ Không có hàm nào tốt hơn hàm Vlookup đâu bạn
 
Mình viết cái Function này nó chạy mà sao ra kết quả toàn là #Value!, nhờ anh em trên đây xem dùm giúp với. Cảm ơn.

Function Tlookup(Source As Range, VTCV As Integer, Data As Range)

Dim N As Integer, M As Integer

N = Sourse.Rows.Count
M = Data.Rows.Count


ReDim KQ(1 To M, 1 To 1)

Set Dic = CreateObject("scripting.dictionary")

For i = 1 To N
If Not Dic.exists(CStr(Source(i, VTCV))) Then

Dic.Add CStr(Source(i, VTCV)), i

End If


Next

For i = 1 To M
Itm = CStr(Data(i, 1))
If Dic.exists(Itm) Then

KQ(i, 1) = Source(Dic.Item(Itm), 1)

End If

Next

Tlookup = KQ

End Function
 
Mình viết cái Function này nó chạy mà sao ra kết quả toàn là #Value!, nhờ anh em trên đây xem dùm giúp với. Cảm ơn.

Function Tlookup(Source As Range, VTCV As Integer, Data As Range)

Dim N As Integer, M As Integer

N = Sourse.Rows.Count
M = Data.Rows.Count


ReDim KQ(1 To M, 1 To 1)

Set Dic = CreateObject("scripting.dictionary")

For i = 1 To N
If Not Dic.exists(CStr(Source(i, VTCV))) Then

Dic.Add CStr(Source(i, VTCV)), i

End If


Next

For i = 1 To M
Itm = CStr(Data(i, 1))
If Dic.exists(Itm) Then

KQ(i, 1) = Source(Dic.Item(Itm), 1)

End If

Next

Tlookup = KQ

End Function

Bạn thử sửa chỗ màu đỏ xem sao. Ngoài ra bạn chưa nên khai báo tất cả các biiến.
Mà mỉnh đang thắc mắc không biết bạn dùng cái này vận dụng vào việc gì nhỉ ?
 
Mình gửi file lên nhé, vì mục đích là muốn viết cái hàm thay cho Vlookup để nó chạy nhanh hơn Vlookup.
anh Bill làm ra hàm vlookup thì cũng đã thử nghiệm tốc độ hết rồi bác à! cái đầu mình sao bằng đầu của mấy cha làm cho anh Bill được mà muốn nhanh hơn.
 
Bạn thử sửa chỗ màu đỏ xem sao. Ngoài ra bạn chưa nên khai báo tất cả các biiến.
Mà mỉnh đang thắc mắc không biết bạn dùng cái này vận dụng vào việc gì nhỉ ?

Hic, vẫn không được.
Nếu hàm này chạy được, chỉ cần đánh 1 câu lệnh có thể ra cả trăm nghìn kết quả bên dưới. Nhanh hơn rất nhiều.
 
Hic, vẫn không được.
Nếu hàm này chạy được, chỉ cần đánh 1 câu lệnh có thể ra cả trăm nghìn kết quả bên dưới. Nhanh hơn rất nhiều.
Có lẽ do bạn chưa khai báo hết biến, bởi bạn nói xuông không có nói lỗi là lỗi như thế nào, không chạy được là không chạy được chỗ nào nên đến #10 vẫn chưa đi đến đâu.
 
Lần chỉnh sửa cuối:
Có lẽ do bạn chưa khai báo hết biến, bởi bạn nói xuông không có nói lỗi là lỗi như thế nào, không chạy được là không chạy được chỗ nào nên đến #10 vẫn chưa đi đến đâu.

Mình gửi file lên đây, bạn xem thử. Cảm ơn nhé.
 
Lần chỉnh sửa cuối:
Hic, vẫn không được.
Nếu hàm này chạy được, chỉ cần đánh 1 câu lệnh có thể ra cả trăm nghìn kết quả bên dưới. Nhanh hơn rất nhiều.

Có lẽ bạn nhầm cái Function() với Sub.
Tôi nghĩ câu bạn nói "chỉ cần đánh 1 câu lệnh có thể ra cả trăm nghìn kết quả bên dưới" chỉ có thể dùng Sub, Nếu viết 1 Function() thay thế Vlookup() của anh Bill thì quá "siêng".
 
Không phải là không được. Vì hàm Vlookup phải chạy tổng quát. Nếu bạn viết hàm đăc biệt cho đúng tình huống của mình thì có thể nhanh hơn thật. Ví dụ trường hợp cái bảng lookup của bạn có rất nhiều trị lặp lại. Vlookup phải duyệt qua các trị này. Bạn thâu nó về Dictionary thì giảm thiểu số lookup.

Tuy nhiên code trên người viết hoàn toàn không biết gì về phạm vi đời sống của biến. Mỗi lần gọi hàm, lại phải lập lại Dictionary và do đó phải đọc nguyên range lại từ đầu. Chả tiết kiệm được gì cả. Nếu muốn tiết kiệm thì phải có cách giữ biến Dictionary không bị tiêu huỷ khi thoát khỏi hàm. Đó là nhiệm vụ của biến static.

Nếu dùng sub thì nói như bạn Ba Tê trên là đúng rồi. Lập Dictionary 1 lần dùng cho cả range kết quả. Tiết kiệm được nhiều.
 
Không phải là không được. Vì hàm Vlookup phải chạy tổng quát. Nếu bạn viết hàm đăc biệt cho đúng tình huống của mình thì có thể nhanh hơn thật. Ví dụ trường hợp cái bảng lookup của bạn có rất nhiều trị lặp lại. Vlookup phải duyệt qua các trị này. Bạn thâu nó về Dictionary thì giảm thiểu số lookup.

Tuy nhiên code trên người viết hoàn toàn không biết gì về phạm vi đời sống của biến. Mỗi lần gọi hàm, lại phải lập lại Dictionary và do đó phải đọc nguyên range lại từ đầu. Chả tiết kiệm được gì cả. Nếu muốn tiết kiệm thì phải có cách giữ biến Dictionary không bị tiêu huỷ khi thoát khỏi hàm. Đó là nhiệm vụ của biến static.

Nếu dùng sub thì nói như bạn Ba Tê trên là đúng rồi. Lập Dictionary 1 lần dùng cho cả range kết quả. Tiết kiệm được nhiều.

bài này nếu dùng hàm thì điểm hấp dẫn không nằm ở chỗ làm sao lập Dictionary 1 lần . Mà hấp dẫn ở chỗ làm sao khi thay đổi giá trị bảng dò thì giá trị hàm lookUpChe cũng thay đổi theo . hi hi
 
Tôi có nói từ đầu là Vlookup làm việc tổng quát. Hàm viết gọn lại chỉ hiệu nghiệm với trường hợp đặc thù của mình thôi.
 
Không phải là không được. Vì hàm Vlookup phải chạy tổng quát. Nếu bạn viết hàm đăc biệt cho đúng tình huống của mình thì có thể nhanh hơn thật. Ví dụ trường hợp cái bảng lookup của bạn có rất nhiều trị lặp lại. Vlookup phải duyệt qua các trị này. Bạn thâu nó về Dictionary thì giảm thiểu số lookup.

Tuy nhiên code trên người viết hoàn toàn không biết gì về phạm vi đời sống của biến. Mỗi lần gọi hàm, lại phải lập lại Dictionary và do đó phải đọc nguyên range lại từ đầu. Chả tiết kiệm được gì cả. Nếu muốn tiết kiệm thì phải có cách giữ biến Dictionary không bị tiêu huỷ khi thoát khỏi hàm. Đó là nhiệm vụ của biến static.

Nếu dùng sub thì nói như bạn Ba Tê trên là đúng rồi. Lập Dictionary 1 lần dùng cho cả range kết quả. Tiết kiệm được nhiều.
Biến Static là sao vậy bạn, bạn cụ thể chút được không? Bạn có thể chia sẻ tài liệu nào nói về cái này ko? Cảm ơn bạn.
 
Mình viết cái Function này nó chạy mà sao ra kết quả toàn là #Value!, nhờ anh em trên đây xem dùm giúp với. Cảm ơn.

Function Tlookup(Source As Range, VTCV As Integer, Data As Range)

Dim N As Integer, M As Integer

N = Sourse.Rows.Count
M = Data.Rows.Count


ReDim KQ(1 To M, 1 To 1)

Set Dic = CreateObject("scripting.dictionary")

For i = 1 To N
If Not Dic.exists(CStr(Source(i, VTCV))) Then

Dic.Add CStr(Source(i, VTCV)), i

End If


Next

For i = 1 To M
Itm = CStr(Data(i, 1))
If Dic.exists(Itm) Then

KQ(i, 1) = Source(Dic.Item(Itm), 1)

End If

Next

Tlookup = KQ

End Function
Sửa khai báo integer thành long hoặc double xem sao
 
Sửa khai báo integer thành long hoặc double xem sao
Mình sửa thì nó ra kết quả rồi, nhưng chỉ ra kết quả tại dòng đó thôi chứ không ra được cả mảng kết quả như mong muốn.
Và mình thử dùng theo chức năng Ctrl + Shift + Enter theo công thức mảng thì kết quả ra cả mảng luôn, nhanh bất ngờ. -+*/
 
Lần chỉnh sửa cuối:
Mình sửa thì nó ra kết quả rồi, nhưng chỉ ra kết quả tại dòng đó thôi chứ không ra được cả mảng kết quả như mong muốn.
Và mình thử dùng theo chức năng Ctrl + Shift + Enter theo công thức mảng thì kết quả ra cả mảng luôn, nhanh bất ngờ. -+*/

Nạp công thức cho một vùng thì dùng Ctrl+Enter. Dùng Ctrl+Shift+Enter sẽ làm cho cả vùng nối với nhau thành 1 mảng.
 
Mình sửa thì nó ra kết quả rồi, nhưng chỉ ra kết quả tại dòng đó thôi chứ không ra được cả mảng kết quả như mong muốn.
Và mình thử dùng theo chức năng Ctrl + Shift + Enter theo công thức mảng thì kết quả ra cả mảng luôn, nhanh bất ngờ. -+*/
Hình như bạn chưa phân biệt được đâu là hàm đâu là thủ tục ?

1 hàm sẵn có hay tự tạo thì cũng chỉ cho ra kết quả ở ô đặt hàm số (tôi cũng chưa thấy hàm nào mà nhập hàm ở 1 ô mà cho kết quả ở nhiều ô, hoặc có nhưng tôi chưa biết)

việc bạn muốn nói cho kết quả ở cả vùng tôi hiểu là chạy 1 thủ tục để cho ra kết quả mà thôi.
 
Web KT

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

Back
Top Bottom