Nhờ giúp đỡ tạo hàm UDF tìm kiếm trả về nhiều giá trị

Liên hệ QC

Mr.hieudoanxd

Thành viên thường trực
Tham gia
25/10/19
Bài viết
322
Được thích
150
Để xử lý hàm tìm kiếm trả về nhiều giá trị trong các hàm khác nhau em thường sử dụng 2 hàm tự tạo sau
Function ManyLookup(Lookup_Value As Variant, _ Area_Lookup As Range, _ Area_Result As Range, _ Optional ByVal Delimiter As String = " ") As Variant Application.ScreenUpdating = False On Error Resume Next Dim a As Long, kq As Variant kq = "" For a = 1 To Area_Lookup.Cells.count If Lookup_Value = Area_Lookup.Cells(a) Then If kq = "" Then kq = Area_Result.Cells(a) Else: kq = kq & Delimiter & Area_Result.Cells(a) End If End If Next a ManyLookup = kq Application.ScreenUpdating = True End Function
sau đó sử dụng hàm nối
Function SplitText(Text As String, Delimiter As String, Number As Long) As String Dim Rept As String, Repl As String, le As Long On Error Resume Next le = Len(Text) Rept = WorksheetFunction.Rept(" ", le + 1) Repl = Replace(Text, Delimiter, Rept) SplitText = Trim(Mid(Repl, (Number - 1) * le + 1, le)) End Function
Nhược điểm của 2 hàm trên chỉ trả về 1 giá trị duy nhất, công thức khá lòng vòng khi muốn trả về nhiều giá trị trên các ô, =SplitText(ManyLookup(.....,ROWS($1:1))
Em muốn các anh tạo giúp UDF trả về nhiều giá trị trên các ô giống công thức mảng của Office 365 (không sử dụng Ctrl+Shift+Enter) và giải thuật cho các trường hợp muốn tạo hàm như thế, em có THam khảo một số hàm UDF của anh HeSanbi nhưng nó quá sức với em để hiểu.
Cảm ơn mọi người trước ạ!
 
Lần chỉnh sửa cuối:
Ý bạn là gõ công thức hàm trên trang tính thì nó sẽ hiện cả mảng kết quả bắt đầu ngay tại ô công thức?
 
Upvote 0
Có giải pháp của bạn Ngô Hải Đăng là dùng class module. Nếu bạn muốn thử thì gửi file dữ liệu của bạn lên.
 
Upvote 0
Thêm chủ bài đăng 1 ví dụ UDF

Chúc các bạn vui khỏe trãi qua kỳ dịch
 

File đính kèm

  • UDF.rar
    15.9 KB · Đọc: 13
Upvote 0
Gửi anh ví dụ tham khảo. em có để sẵn 2 code của mình trong đó rồi đó anh
Bạn dùng công thức ở ô I2 nhé, đã bỏ đi tham số cuối rồi.

Khi đã có kết quả thì chỉ cần xóa ô chứa công thức là mảng kết quả sẽ được xóa hết.
 

File đính kèm

  • Vidu_Mr.hieudoanxd.xlsb
    30.9 KB · Đọc: 24
Upvote 0
Thêm chủ bài đăng 1 ví dụ UDF

Chúc các bạn vui khỏe trãi qua kỳ dịch
Cảm ơn bác, ví dụ này em đã đọc của bác qua 1 lần ở bài viết nào đó rồi ạ. Có điều em không muốn sử dụng { } nó khó khăn khi sửa công thức, thay đổi kích thước đầu vào ạ. Vui vui tí thì hiện chỗ em không có ca nào. Hehe
Bạn dùng công thức ở ô I2 nhé, đã bỏ đi tham số cuối rồi.

Khi đã có kết quả thì chỉ cần xóa ô chứa công thức là mảng kết quả sẽ được xóa hết.
Rất cảm ơn anh, đúng ý em rồi ạ.
À, nhân tiện đây, có điều này em thắc mắc 1 chút.
1. Nếu ô công thức em không xóa mà thay bằng giá trị khác thì kết quả ko bị xóa, chỉ biến mất kết quả khi xóa hẳn ô đi.
2. Nếu thay đổi dữ liệu đầu vào ở Ô công thức nó hiện dòng chữ Caculating...
3. Không biết bác có thể thêm Option nếu giá trị tìm được tương ứng là Rỗng hoặc 0 thì bỏ qua không hiển thị không ạ?
4. Cuối cùng, Bác có thể hướng dẫn xử lý theo cách của bác và của bác Đăng cho những bài toán như thế này không ạ? Em hơi tham lam tí
 
Upvote 0
Cảm ơn bác, ví dụ này em đã đọc của bác qua 1 lần ở bài viết nào đó rồi ạ. Có điều em không muốn sử dụng { } nó khó khăn khi sửa công thức, thay đổi kích thước đầu vào ạ. Vui vui tí thì hiện chỗ em không có ca nào. Hehe

Rất cảm ơn anh, đúng ý em rồi ạ.
À, nhân tiện đây, có điều này em thắc mắc 1 chút.
1. Nếu ô công thức em không xóa mà thay bằng giá trị khác thì kết quả ko bị xóa, chỉ biến mất kết quả khi xóa hẳn ô đi.
2. Nếu thay đổi dữ liệu đầu vào ở Ô công thức nó hiện dòng chữ Caculating...
3. Không biết bác có thể thêm Option nếu giá trị tìm được tương ứng là Rỗng hoặc 0 thì bỏ qua không hiển thị không ạ?
4. Cuối cùng, Bác có thể hướng dẫn xử lý theo cách của bác và của bác Đăng cho những bài toán như thế này không ạ? Em hơi tham lam tí
Thực tình tôi chỉ biết dùng thôi chứ không sửa được. Chỉ là thay vì dùng comment ô để ghi lại kích thước của mảng thì tôi sửa code lại dùng ghi chú của name để ghi. Bạn chịu khó xóa hẳn đi rồi nhập lại công thức mới vậy.

Mà tôi dùng file trên máy tôi, nó đâu có bị tình trạng như vậy. Vẫn cập nhật công thức đầy đủ khi thay đổi công thức, thay đổi dữ liệu đầu vào.
 
Lần chỉnh sửa cuối:
Upvote 0
Vâng anh!. Một lần nữa cảm ơn anh
Bạn xem lại bài #9 tôi có viết thêm. Bạn xử lý cách này xem: Xóa công thức đi, xem lại trong Name Manager thử có name nào có tên ARR và Sheet... như hình thì xóa đi. Sau đó nhập lại công thức, thử lại thay đổi công thức hoặc dữ liệu đầu vào xem.
1631453066524.png
 
Upvote 0
Bạn xem lại bài #9 tôi có viết thêm. Bạn xử lý cách này xem: Xóa công thức đi, xem lại trong Name Manager thử có name nào có tên ARR và Sheet... như hình thì xóa đi. Sau đó nhập lại công thức, thử lại thay đổi công thức hoặc dữ liệu đầu vào xem.
Vâng, công thức đã trả về giá trị đúng khi thay đổi dữ liệu đầu vào, chỉ còn vấn đề nhỏ là thêm OPtion lựa chọn bỏ qua ô rỗng thôi em có thử chỉnh code của anh như sau
Function ManyLookup(Lookup_Value As Variant, _ Area_Lookup As Range, _ Area_Result As Range, _ Optional ByVal NullValue As Boolean = True) As Variant On Error Resume Next Dim a As Long, i As Long, kq As Variant i = 0 ReDim kq(1 To Area_Lookup.Rows.Count, 1 To 1) For a = 1 To Area_Lookup.Cells.Count If Lookup_Value = Area_Lookup.Cells(a) Then If NullValue = True Then i = i + 1 If Area_Result.Cells(a).Value <> vbNullString Then kq(i, 1) = Area_Result.Cells(a) Else i = i + 1 kq(i, 1) = Area_Result.Cells(a) End If End If Next a ManyLookup = kq mUDSF.Link "UDS_ARRAYFORMULA", ManyLookup mUDSF.CallBack ManyLookup End Function
Tuy nhiên không có tác dụng với những ô rỗng ở cột kết quả. Không biết anh có thể sửa một chút xíu đc không?
 
Upvote 0
Bạn muốn NullValue = True thì mệnh đề: If Area_Result.Cells(a).Value <> vbNullString... làm gì? Bạn có thể diễn giải bằng lời được không?
 
Upvote 0
Bạn muốn NullValue = True thì mệnh đề: If Area_Result.Cells(a).Value <> vbNullString... làm gì? Bạn có thể diễn giải bằng lời được không?
nếu giá trị chỉ định NullValue =true thì so sánh nếu Area_Result.cells(a).value khác VbNullString thì ghi giá trị Area_Result.cells(a) vào mảng
Tóm lại là lựa chọn true bỏ qua những ô tìm được ở cột kết quả có giá trị bằng VbNullString ạ
 
Upvote 0
nếu giá trị chỉ định NullValue =true thì so sánh nếu Area_Result.cells(a).value khác VbNullString thì ghi giá trị Area_Result.cells(a) vào mảng
Tóm lại là lựa chọn true bỏ qua những ô tìm được ở cột kết quả có giá trị bằng VbNullString ạ
Tôi không biết cái hằng số vbNullString kia là gì nhưng tôi biết là 1 ô rỗng mà dùng IsNull(ô) thì nó VBA bảo là False. Do đó nếu bạn không muốn ghi giá trị 1 ô rỗng thì thay If Area_Result.Cells(a).Value <> vbNullString bằng If Area_Result.Cells(a) <> "" Then
 
Upvote 0
Tôi không biết cái hằng số vbNullString kia là gì nhưng tôi biết là 1 ô rỗng mà dùng IsNull(ô) thì nó VBA bảo là False. Do đó nếu bạn không muốn ghi giá trị 1 ô rỗng thì thay If Area_Result.Cells(a).Value <> vbNullString bằng If Area_Result.Cells(a) <> "" Then

Em xóa giá trị ở ô G5 đi sau đó test ở Immediate đều ra kết quả True

?range("g5:g22").Cells(1).value = ""
True
?range("g5:g22").Cells(1).value = vbnullstring
True

Em thử thay của anh vào cũng không được ạ
 
Upvote 0
À quên, bạn còn phải bỏ i = i + 1 vào bên trong if đó nữa chứ. Nếu không thì i vẫn tăng vô điều kiện và cái if kia thành vô nghĩa.
 
Lần chỉnh sửa cuối:
Upvote 0
Em làm được rồi anh. Rất cảm ơn anh!
Mã:
Function ManyLookUp(Lookup_Value As Variant, _
                Area_Lookup As Range, _
                Area_Result As Range, _
                Optional ByVal NullValue As Boolean = True) As Variant
   
    On Error Resume Next
    Dim a As Long, i As Long, kq As Variant
    i = 0
    ReDim kq(1 To Area_Lookup.Rows.count, 1 To 1)
    For a = 1 To Area_Lookup.Cells.count
        If Lookup_Value = Area_Lookup.Cells(a) Then

            If NullValue = True Then
                If Area_Result.Cells(a) <> VBA.vbNullString Then
                    i = i + 1
                    kq(i, 1) = Area_Result.Cells(a)
                Else: End If
            Else
                i = i + 1
                kq(i, 1) = Area_Result.Cells(a)
            End If
           
        End If
    Next a
    ManyLookUp = kq
    mUDSF.Link "UDS_ARRAYFORMULA", ManyLookUp
    mUDSF.CallBack ManyLookUp
   
End Function
 
Upvote 0
Web KT

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

Back
Top Bottom