Hàm nối chuổi theo điều kiện (1 người xem)

Liên hệ QC

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

Miền Cát Trắng

Thành viên hoạt động
Tham gia
18/5/13
Bài viết
171
Được thích
37
Xin chào các bạn,đầu xuân chúc các bạn luôn mạnh khỏe,luôn hạnh phúc và đạt nhiều thành công trong cuộc sống.
Tôi có một bài toán đã đề cập trong file kèm, các bạn xem và giúp mình với.
Cảm ơn!
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Bạn thử dùng hàm Jointext của bác ndu96081631 xem có được ko? --=0
Cảm ơn bạn đã giúp đỡ.
Bạn ơi vba mình còn kém quá, liệu có cách nào dùng với công thức?
(Hi,nhờ có file của bạn mà mình mới thấy file đính kém của mình gửi bị sai kết quả minh họa,cột table2 mình nhập sai tháng)
Cảm ơn bạn!
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn thử dùng hàm Jointext của bác ndu96081631 xem có được ko? --=0
Chào bạn, Mình đã test thử thấy kết quả đã đúng.
Nhưng có nhược điểm của hàm này mà mình không xử lý được là nếu ô nào không có dữ liệu nó sẽ hiển thị kết quả 0,lại phiền các bạn giúp mình khắc phục lỗi này với.
Cảm ơn bạn!
 
Upvote 0
Chào bạn, Mình đã test thử thấy kết quả đã đúng.
Nhưng có nhược điểm của hàm này mà mình không xử lý được là nếu ô nào không có dữ liệu nó sẽ hiển thị kết quả 0,lại phiền các bạn giúp mình khắc phục lỗi này với.
Cảm ơn bạn!
Thì bạn dùng hàm if để bắt lỗi.
Nếu A1="" thì "" còn lại sẽ là kết quả thu được nhờ hàm JoinText
 
Upvote 0
Thì bạn dùng hàm if để bắt lỗi.
Nếu A1="" thì "" còn lại sẽ là kết quả thu được nhờ hàm JoinText
Thật sự với hàm mảng và vba này mình chưa biết áp dụng cách của bạn thế nào nữa...mong được bạn chỉ thêm qua file kèm.

Cảm ơn bạn!
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Chào bạn, Mình đã test thử thấy kết quả đã đúng.
Nhưng có nhược điểm của hàm này mà mình không xử lý được là nếu ô nào không có dữ liệu nó sẽ hiển thị kết quả 0,lại phiền các bạn giúp mình khắc phục lỗi này với.
Cảm ơn bạn!
Hàm đó tôi cảm thấy khá rắc rối khi áp dụng, bạn dùng hàm này vậy:

[GPECODE=vb]
Option Explicit


Function TextJoin(ByVal ConditionalColumn As Range, _
ByVal ConditionalCell As Range, _
ByVal DataColumn As Range) As String

Dim ResultArr()
Dim Dict As Object
Dim r As Long, n As Long
Dim Item As String, CondCell As String
Dim CondColArr As Variant, DataColArr As Variant

CondCell = ConditionalCell.Value

If IsArray(ConditionalColumn) Then
CondColArr = ConditionalColumn
Else
ReDim CondColArr(1 To 1, 1 To 1)
CondColArr(1, 1) = ConditionalColumn
End If

If IsArray(DataColumn) Then
DataColArr = DataColumn
Else
ReDim DataColArr(1 To 1, 1 To 1)
DataColArr(1, 1) = DataColumn
End If

Set Dict = CreateObject("Scripting.Dictionary")

For r = 1 To UBound(CondColArr)
If CondColArr(r, 1) = CondCell Then
Item = DataColArr(r, 1)
If Not Dict.Exists(Item) And Item > "" Then
Dict.Add Item, Empty
ReDim Preserve ResultArr(0 To n)
ResultArr(n) = Item
n = n + 1
End If
End If
Next

If n Then
TextJoin = Join(ResultArr, ", ")
End If


End Function[/GPECODE]

Cách dùng như sau:

Giả sử cột A chứa tất cả điều kiện, cột B chứa dữ liệu và cột D chứa điều kiện, thì cột E có công thức như sau:

=TextJoin($A$1:$A$11,D1,$B$1:$B$11)

Rất giống hàng SUMIF phải không bạn? Có dễ dùng lắm không?

Lưu ý: Cột A và cột B phải có số hàng tương ứng nha bạn!
 

File đính kèm

Upvote 0
Thật sự với hàm mảng và vba này mình chưa biết áp dụng cách của bạn thế nào nữa...mong bạn chỉ chỉ thêm.
Cảm ơn bạn!
Hàm mảng hay hàm tự tạo cũng có quy luật chung mà bạn, bạn dùng if để biến đổi sẽ cho các kết quả như ý. Ví dụ
Mã:
=jointext(",",TRUE,IF([COLOR=#ff0000][B]($E$3:$E$20<>"")[/B][/COLOR]*($D$3:$D$20)=G3,$E$3:$E$20,""))
Đoạn màu đỏ là đoạn bắt lỗi trong If, thêm điều kiện cột E không rỗng. Bạn cứ thế triển khai thôi. Còn về cách sử dụng hàm JoinText thì bạn tìm trên diễn đàn sẽ có ngay.
 
Upvote 0
Cảm ơn anh Nghĩa,Cảm ơn mọi kết quả đã đúng với ý của em.
Có vấn đề em sẽ hồi âm lại.
Chúc GPE ngủ ngon và có nhiều giấc đẹp!
 
Upvote 0
Vì điều kiện tôi đưa ra là Cột Điều Kiện và Cột Dữ Liệu phải có số hàng tương ứng nên tôi đã sửa lại hàm cho gọn lại tí:

Mã:
Function TextJoin(ByVal ConditionalColumn As Range, _
                  ByVal ConditionalCell As Range, _
                  ByVal DataColumn As Range) As String
    
    Dim r As Long
    Dim Dict As Object
    Dim Item As String, CondCell As String
    Dim CondColArr As Variant, DataColArr As Variant
    
    CondCell = ConditionalCell.Value
    
    If IsArray(ConditionalColumn) Then
        CondColArr = ConditionalColumn
        DataColArr = DataColumn
    Else
        ReDim CondColArr(1 To 1, 1 To 1)
        ReDim DataColArr(1 To 1, 1 To 1)
        CondColArr(1, 1) = ConditionalColumn
        DataColArr(1, 1) = DataColumn
    End If
    
    Set Dict = CreateObject("Scripting.Dictionary")
    
    For r = 1 To UBound(CondColArr)
        If CondColArr(r, 1) = CondCell Then
            Item = DataColArr(r, 1)
            If Not Dict.Exists(Item) And Item > "" Then
                Dict.Add Item, Empty
            End If
        End If
    Next
    
[COLOR=#0000cd][B]    If Dict.Count Then[/B][/COLOR]
[COLOR=#0000cd][B]        TextJoin = Join(Dict.Keys, ", ")[/B][/COLOR]
[COLOR=#0000cd][B]    End If[/B][/COLOR]


End Function

--------------------------------------------------------------
Do làm một cách máy móc và vội vàng nên tôi đã thêm biến n và mảng ResultArr, bây giờ tôi đã sửa lại phần này!
 
Lần chỉnh sửa cuối:
Upvote 0
Hàm mảng hay hàm tự tạo cũng có quy luật chung mà bạn, bạn dùng if để biến đổi sẽ cho các kết quả như ý. Ví dụ
Mã:
=jointext(",",TRUE,IF([COLOR=#ff0000][B]($E$3:$E$20<>"")[/B][/COLOR]*($D$3:$D$20)=G3,$E$3:$E$20,""))
Đoạn màu đỏ là đoạn bắt lỗi trong If, thêm điều kiện cột E không rỗng. Bạn cứ thế triển khai thôi. Còn về cách sử dụng hàm JoinText thì bạn tìm trên diễn đàn sẽ có ngay.
Cảm ơn bạn.
Hàm này mình test không đúng với kết quả mong muốn nếu dữ liệu giống nhau chỉ lấy 1 giá trị.
Ngày 01-01-1900 dữ liệu là a và a thì kết quả lại là a,a theo kết quả mong muốn chỉ là thôi, lúc nào rảnh nếu không phiền bạn xem lại giúp mình nhé.
 

File đính kèm

Upvote 0
Cảm ơn bạn.
Hàm này mình test không đúng với kết quả mong muốn nếu dữ liệu giống nhau chỉ lấy 1 giá trị.
Ngày 01-01-1900 dữ liệu là a và a thì kết quả lại là a,a theo kết quả mong muốn chỉ là thôi, lúc nào rảnh nếu không phiền bạn xem lại giúp mình nhé.
Riêng dữ liệu của bạn đưa ra, cột điều kiện ở bảng 1 không có ngày 04/02/2014 và 05/02/2014 nha bạn, trong khi ở cột bảng 2 lại có ngày đó thì sao nó tính được?

Hàm ở bài vừa rồi (#921)tôi mới sửa lại nha, bạn copy về mà xài!
 
Upvote 0
Riêng dữ liệu của bạn đưa ra, cột điều kiện ở bảng 1 không có ngày 04/02/2014 và 05/02/2014 nha bạn, trong khi ở cột bảng 2 lại có ngày đó thì sao nó tính được?

Hàm ở bài vừa rồi (#921)tôi mới sửa lại nha, bạn copy về mà xài!
Cảm ơn anh Nghĩa hiện em đang sử dụng hàm mới cập của Anh nhưng chưa thấy lỗi để lập bảng dữ liệu xem có lỗi gì không em sẽ hồi âm lại,còn Dữ liệu này em cũng đã biết rồi. Nhưng cái lỗi mà em nêu ở 922 là đang phát sinh.

Một lần nữa cảm ơn Anh,Anh giữ gìn sức khỏe!
 
Upvote 0
Cảm ơn anh Nghĩa hiện em đang sử dụng hàm mới cập của Anh nhưng chưa thấy lỗi để lập bảng dữ liệu xem có lỗi gì không em sẽ hồi âm lại,còn Dữ liệu này em cũng đã biết rồi. Nhưng cái lỗi mà em nêu ở 922 là đang phát sinh.

Một lần nữa cảm ơn Anh,Anh giữ gìn sức khỏe!

Lỗi phát sinh là trùng dữ liệu nó không xử lý ở hàm JoinText, nhưng với hàm TextJoin của tôi thì đã xử lý việc trùng này và cấu trúc gọn gàng dễ sử dụng hơn nha bạn.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Lỗi phát sinh là trùng dữ liệu nó không xử lý ở hàm JoinText, nhưng với hàm TextJoin của tôi thì đã xử lý việc trùng này và cấu trúc gọn gàng dễ sử dụng hơn nha bạn.
Anh chưa ngủ ạ, vậy thì anh xem trường thêm trường hợp này nhé hàm TextJoin nếu định dạng khác nhau thì kết quả cũng sai hả Anh Nghĩa.
Ví dụ cùng 1 dữ liệu 1 ô em định dạng(Format) là "dd" và một ô là Value(number) thì kết quả bị sai lệch.
Anh xem file kèm nhé!
 

File đính kèm

Upvote 0
Anh chưa ngủ ạ, vậy thì anh xem trường thêm trường hợp này nhé hàm TextJoin nếu định dạng khác nhau thì kết quả cũng sai hả Anh Nghĩa.
Ví dụ cùng 1 dữ liệu 1 ô em định dạng(Format) là "dd" và một ô là Value(number) thì kết quả bị sai lệch.
Anh xem file kèm nhé!
Cho tôi hỏi, cột điều kiện luôn luôn là dạng ngày tháng phải không?
 
Upvote 0
Cảm ơn bạn.
Hàm này mình test không đúng với kết quả mong muốn nếu dữ liệu giống nhau chỉ lấy 1 giá trị.
Ngày 01-01-1900 dữ liệu là a và a thì kết quả lại là a,a theo kết quả mong muốn chỉ là thôi, lúc nào rảnh nếu không phiền bạn xem lại giúp mình nhé.

Bộ hàm nối chuổi mà tôi viết gồm có 2 hàm: JoinTextJoinIf. Bài này bạn nên dùng JoinIf mới đúng (vì liên quan đến Unique)
Hàm thế này:
Mã:
Function JoinIf(ByVal Delimiter As String, ByVal CriteriaArray, ByVal Criteria, Optional ByVal TargetArray) As String
  Dim aTmpCrit, aTmpDes, tmp1, tmp2, Arr(), dic As Object
  Dim bComp As Boolean, Chk As Boolean
  Dim i As Long, j As Long, k As Long, dTmpVal As Double
  Set dic = CreateObject("Scripting.Dictionary")
  If IsMissing(TargetArray) Then TargetArray = CriteriaArray
  aTmpCrit = ConvertTo1DArray(CriteriaArray)
  aTmpDes = ConvertTo1DArray(TargetArray)
  If (Not IsArray(aTmpCrit)) Or (Not IsArray(aTmpDes)) Then Exit Function
  On Error Resume Next
  bComp = (InStr("<>=", Left(Criteria, 1)) > 0)
  For i = LBound(aTmpDes) To UBound(aTmpDes)
    tmp1 = aTmpCrit(i): tmp2 = aTmpDes(i)
    If bComp And Len(Criteria) Then
      dTmpVal = CDbl(aTmpCrit(i))
      If Evaluate(dTmpVal & Criteria) Then dic.Add tmp2, ""
    Else
      If (Left(Criteria, 1) = "!") Then
        If Not (UCase(tmp1) Like UCase(Mid(Criteria, 2, Len(Criteria)))) Then dic.Add tmp2, ""
      Else
        If (UCase(tmp1) Like UCase(Criteria)) Then dic.Add tmp2, ""
      End If
    End If
  Next
  If dic.Count Then
    Arr = dic.Keys
    JoinIf = Join(Arr, Delimiter)
  End If
End Function
Tất cả được xử lý trên mảng.
---------------------------------------------------------------------------
Mặc khác, bạn đang dùng hàm JoinText version cũ đấy, mới nhất nó là thế này:
Mã:
Function JoinText(ByVal Delimiter As String, ParamArray Arrays()) As String
  Dim aTmp, Arr(), Item, tmp As String
  Dim i As Long, n As Long
  'On Error Resume Next
  For i = LBound(Arrays) To UBound(Arrays)
    aTmp = Arrays(i)
    If Not IsArray(aTmp) Then aTmp = Array(aTmp)
    For Each Item In aTmp
      If TypeName(Item) <> "Error" Then
        tmp = CStr(Item)
        n = n + 1
        ReDim Preserve Arr(1 To n)
        Arr(n) = tmp
      End If
    Next
  Next
  If n Then JoinText = Join(Arr, Delimiter)
End Function
--------------------
Với file của bạn thì cú pháp hàm dùng trên bảng tính là:
Mã:
=JoinIf(", ",$D$3:$D$20,G3,$E$3:$E$20)
 

File đính kèm

Upvote 0
@ThầyNdu:
Ui,Thầy! Có Anh nào Thấy hàm JoinText của Thầy không đạt hiệu quả nên Alô cho Thầy ạ... hix!-+*/
Em sẽ test kết quả ạ.
++++++++++
@Anh Nghĩa: Ý của em không nhất thiết dữ liệu của em định dạng kiểu ngày hay number nhưng em vô tình định dạng như vậy thì phát hiện sự cố đó để anh tìm giải pháp cho hoàn thiện hơn thôi ạ.Còn theo bài của anh em có thể định dạng sao cho kết quả đúng với ý của mình là được.
==========
Cảm ơn Thầy và Anh!Thật là khó lựa chọn khi có 2 bài đạt chuẩn ý -> bí mật! :)
 
Upvote 0
Anh chưa ngủ ạ, vậy thì anh xem trường thêm trường hợp này nhé hàm TextJoin nếu định dạng khác nhau thì kết quả cũng sai hả Anh Nghĩa.
Ví dụ cùng 1 dữ liệu 1 ô em định dạng(Format) là "dd" và một ô là Value(number) thì kết quả bị sai lệch.
Anh xem file kèm nhé!

Nếu cột điều kiện đều là dạng DATE thì hàm này chỉ viết riêng cho trường hợp của bạn:

Mã:
Function TextJoin(ByVal ConditionalColumn As Range, _
                  ByVal ConditionalCell As Range, _
                  ByVal DataColumn As Range) As String
    On Error Resume Next
    Dim r As Long
    Dim Dict As Object
    Dim Item As String, CondCell As Date
    Dim CondColArr As Variant, DataColArr As Variant
    CondCell = ConditionalCell.Value
    If IsArray(ConditionalColumn) Then
        CondColArr = ConditionalColumn
        DataColArr = DataColumn
    Else
        ReDim CondColArr(1 To 1, 1 To 1)
        ReDim DataColArr(1 To 1, 1 To 1)
        CondColArr(1, 1) = ConditionalColumn
        DataColArr(1, 1) = DataColumn
    End If
    Set Dict = CreateObject("Scripting.Dictionary")
    For r = 1 To UBound(CondColArr)
        If CDate(CondColArr(r, 1)) = CondCell Then
            Item = DataColArr(r, 1)
            If Not Dict.Exists(Item) And Item > "" Then
                Dict.Add Item, Empty
            End If
        End If
    Next
    If Dict.Count Then
        TextJoin = Join(Dict.Keys, ", ")
    End If
End Function

Bạn muốn định dạng kiểu "quái" nào cũng được, miễn là từ DATE mà ra!
 

File đính kèm

Upvote 0
Anh chưa ngủ ạ, vậy thì anh xem trường thêm trường hợp này nhé hàm TextJoin nếu định dạng khác nhau thì kết quả cũng sai hả Anh Nghĩa.
Ví dụ cùng 1 dữ liệu 1 ô em định dạng(Format) là "dd" và một ô là Value(number) thì kết quả bị sai lệch.
Anh xem file kèm nhé!

File mới của bạn, nếu dùng hàm JoinIf của tôi thì sẽ thế này:
Mã:
=JoinIf(", ",$H$8:$H$100,[COLOR=#ff0000]"="&K8[/COLOR],$I$8:$I$100)
---------------------
Nếu cột điều kiện đều là dạng DATE thì hàm này chỉ viết riêng cho trường hợp của bạn:
Ai lại làm thế! Hàm phải tổng quát chứ
Trường hợp này nó giống với Advanced Filter và Filter đấy (dạng đặc biệt) và ta cũng phải lường trước trong code
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Hix!@ThầyNDU và Anh Nghĩa!
Em đã test cả 2 bài mới nhất và kết quả thật sự là đẹp mỹ mãn lắm rồi ạ...
Xin cảm ơn Thầy và Anh rất nhiều và nhân dịp đầu năm chúc Thầy và Anh luôn vui vẻ và mãi gắn bó với GPE để bầu trời tươi đẹp của thế hệ trẻ sau này được rộng mở.
 
Upvote 0
Hix!@ThầyNDU và Anh Nghĩa!
Em đã test cả 2 bài mới nhất và kết quả thật sự là đẹp mỹ mãn lắm rồi ạ...
Xin cảm ơn Thầy và Anh rất nhiều và nhân dịp đầu năm chúc Thầy và Anh luôn vui vẻ và mãi gắn bó với GPE để bầu trời tươi đẹp của thế hệ trẻ sau này được rộng mở.
Bài đó chưa có hay đâu, bài này mới đã nè!

[GPECODE=vb]
Function TextJoin(ByVal ConditionalColumn As Range, _
ByVal ConditionalCell As Range, _
ByVal DataColumn As Range) As String
''On Error Resume Next
If ConditionalCell.Value = "" Then Exit Function
Dim r As Long
Dim Dict As Object
Dim Cond, CondCell, CondColArr, DataColArr, Tmp
CondCell = ConditionalCell.Value
If IsArray(ConditionalColumn) Then
CondColArr = ConditionalColumn
DataColArr = DataColumn
Else
ReDim CondColArr(1 To 1, 1 To 1)
ReDim DataColArr(1 To 1, 1 To 1)
CondColArr(1, 1) = ConditionalColumn
DataColArr(1, 1) = DataColumn
End If
Set Dict = CreateObject("Scripting.Dictionary")
If TypeName(CondCell) = "String" Then
For r = 1 To UBound(CondColArr)
If CStr(CondColArr(r, 1)) = CStr(CondCell) Then
Tmp = DataColArr(r, 1)
If Not Dict.Exists(Tmp) And Tmp > "" Then
Dict.Add Tmp, ""
End If
End If
Next
Else
For r = 1 To UBound(CondColArr)
Cond = CondColArr(r, 1)
If TypeName(Cond) <> "String" Then
If CDbl(Cond) = CDbl(CondCell) Then
Tmp = DataColArr(r, 1)
If Not Dict.Exists(Tmp) And Tmp > "" Then
Dict.Add Tmp, ""
End If
End If
End If
Next
End If
If Dict.Count Then
TextJoin = Join(Dict.Keys, ", ")
End If
Dict.RemoveAll
Set Dict = Nothing
End Function[/GPECODE]

File mới của bạn, nếu dùng hàm JoinIf của tôi thì sẽ thế này:
Mã:
=JoinIf(", ",$H$8:$H$100,[COLOR=#ff0000]"="&K8[/COLOR],$I$8:$I$100)
---------------------

Ai lại làm thế! Hàm phải tổng quát chứ
Trường hợp này nó giống với Advanced Filter và Filter đấy (dạng đặc biệt) và ta cũng phải lường trước trong code

Em đã làm một cách tổng quát cho Hàm TextJoin và khi so sánh thì Hàm JoinIf còn nhiều trường hợp chưa chính xác.

Xem file.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Bổ sung vấn đề so sánh chữ HOA, chữ Thường

[GPECODE=vb]
Function TextJoin(ByVal ConditionalColumn As Range, _
ByVal ConditionalCell As Range, _
ByVal DataColumn As Range, _
Optional ByVal Compare As Boolean) As String
''Voi Compare neu phan biet chu HOA chu Thuong
''thi chon la TRUE, khong thi thoi.

''On Error Resume Next
Application.Volatile
If ConditionalCell.Value = "" Then Exit Function
Dim r As Long
Dim Dict As Object
Dim Cond, CondCell, CondColArr, DataColArr, Tmp
CondCell = ConditionalCell.Value
If IsArray(ConditionalColumn) Then
CondColArr = ConditionalColumn
DataColArr = DataColumn
Else
ReDim CondColArr(1 To 1, 1 To 1)
ReDim DataColArr(1 To 1, 1 To 1)
CondColArr(1, 1) = ConditionalColumn
DataColArr(1, 1) = DataColumn
End If
Set Dict = CreateObject("Scripting.Dictionary")
If TypeName(CondCell) = "String" Then
CondCell = CStr(CondCell)
If Compare Then
For r = 1 To UBound(CondColArr)
If CStr(CondColArr(r, 1)) = CondCell Then
Tmp = DataColArr(r, 1)
If Not Dict.Exists(Tmp) And Tmp > "" Then
Dict.Add Tmp, ""
End If
End If
Next
Else
CondCell = UCase(CondCell)
For r = 1 To UBound(CondColArr)
If CStr(UCase(CondColArr(r, 1))) = CondCell Then
Tmp = DataColArr(r, 1)
If Not Dict.Exists(Tmp) And Tmp > "" Then
Dict.Add Tmp, ""
End If
End If
Next
End If
Else
For r = 1 To UBound(CondColArr)
Cond = CondColArr(r, 1)
If TypeName(Cond) <> "String" Then
If CDbl(Cond) = CDbl(CondCell) Then
Tmp = DataColArr(r, 1)
If Not Dict.Exists(Tmp) And Tmp > "" Then
Dict.Add Tmp, ""
End If
End If
End If
Next
End If
If Dict.Count Then
TextJoin = Join(Dict.Keys, ", ")
End If
Dict.RemoveAll
Set Dict = Nothing
End Function[/GPECODE]

Nếu bạn không cần so sánh chữ HOA, chữ thường thì làm công thức bình thường:

=TextJoin($B$2:$B$94,E2,$C$2:$C$94)

Nhưng nếu bạn phân biệt chỉ tính chữ HOA hoặc chữ thường thì bạn thêm TRUE:

=TextJoin($B$2:$B$94,E2,$C$2:$C$94,TRUE)

Rất tiện lợi phải không!

Để ý rằng có 3 vòng lặp FOR ... NEXT trong hàm phải không các bạn, không phải ngại chạy chậm đâu nhé, thực tế, chúng chỉ chạy có 1 vòng lặp khi thỏa một điều kiện nhất định mà thôi.
 
Upvote 0
Em đã làm một cách tổng quát cho Hàm TextJoin và khi so sánh thì Hàm JoinIf còn nhiều trường hợp chưa chính xác.

Xem file.

Không chính xác là vì chú mày không biết xài hàm thôi
Hàm tôi so sánh dựa trên toán tử Like và Evaluate. Vậy, đối với dữ liệu dạng Number, nếu muốn so sánh CHÍNH XÁC thì phải thêm dấu "=" vào điều kiện
Ví dụ: Thay vì viết:
Mã:
=JoinIf(", ",$B$2:$B$94,E2,$C$2:$C$94)
Thì phải viết:
Mã:
=JoinIf(", ",$B$2:$B$94,[COLOR=#ff0000]"="&E2[/COLOR],$C$2:$C$94)
Hàm này hoạt động gần giống với SUMIF: Cho phép so sánh "=", ">", "<" vân... vân...
Ngoài ra, hàm hoạt động theo Array nên dữ liệu trên bảng tính là ngang hay dọc đều dùng được cả
---------------------
Còn cái chuyện Nghĩa cố tình đưa ra những dữ liệu tào lao để cố chứng minh rằng hàm tôi không chính xác thì tôi.. không quan tâm. Vì dữ liệu thật chẳng bao giờ như vậy cả
Nên nhớ rằng: Tôi viết hàm là để phục vụ cho nhu cầu có thật, dựa trên CSDL thật. Thành ra, ai thích cứ xài, không thích cũng không sao
Ẹc... Ẹc...
 
Upvote 0
Còn cái chuyện Nghĩa cố tình đưa ra những dữ liệu tào lao để cố chứng minh rằng hàm tôi không chính xác thì tôi.. không quan tâm. Vì dữ liệu thật chẳng bao giờ như vậy cả

Ẹc... Ẹc...
Không hẳn là cố tình đưa ra dữ liệu tào lao, mà vì:

Một, có thể một lúc nào đó người ta định dạng kiểu d/m/y nhưng cũng có thể người ta định dạng kiểu khác thì hàm của Thầy chưa đáp ứng được.

Hai, cũng tương tự hàm SUMIF, cột điều kiện là rỗng thì nó không tính

Ba, dùng hàm Evaluate để tính toán, với dữ liệu lớn chắc chắn 100% sẽ chậm hơn phép so sánh bằng.

-------------------------------------------

Cũng như Thầy nói, ai dùng hàm nào cũng được, miễn sao đáp ứng được hiệu quả nhu cầu của mình sử dụng.

Riêng việc đổi chiều dọc thành chiều ngang thì thêm vài phép tính nữa thôi mà Thầy. Quan điểm của em có thể viết thêm sửa đổi sao cho khi sử dụng người dùng cảm thấy đơn giản dễ hiểu, hiệu quả, nhanh chóng, chính xác, còn hàm có viết tràn lan đại hải cũng không sao (đâu ai quan tâm đến hàm SUM của Excel nó được viết thế nào, họ chỉ biết dùng mà thôi).
 
Upvote 0
Một, có thể một lúc nào đó người ta định dạng kiểu d/m/y nhưng cũng có thể người ta định dạng kiểu khác thì hàm của Thầy chưa đáp ứng được.
Cái này như tôi đã nói ở trên: Thêm dấu "=" để so sánh rồi còn gì
Hai, cũng tương tự hàm SUMIF, cột điều kiện là rỗng thì nó không tính
Quá dễ, nếu muốn sửa code
Ba, dùng hàm Evaluate để tính toán, với dữ liệu lớn chắc chắn 100% sẽ chậm hơn phép so sánh bằng.
Cái này thì Nghĩa đã suy nghĩ quá xa rồi. Nối chuổi có bao giờ ra kết quả mấy ngàn từ không? Cho dù có ra được kết quả cũng chẳng đọc được

-------------------------------------------
Cũng như Thầy nói, ai dùng hàm nào cũng được, miễn sao đáp ứng được hiệu quả nhu cầu của mình sử dụng.

Riêng việc đổi chiều dọc thành chiều ngang thì thêm vài phép tính nữa thôi mà Thầy. Quan điểm của em có thể viết thêm sửa đổi sao cho khi sử dụng người dùng cảm thấy đơn giản dễ hiểu, hiệu quả, nhanh chóng, chính xác, còn hàm có viết tràn lan đại hải cũng không sao (đâu ai quan tâm đến hàm SUM của Excel nó được viết thế nào, họ chỉ biết dùng mà thôi).
Như ta đã biết, đã gọi là SO SÁNH thì không chỉ có SO SÁNH BẰNG. Còn có LỚN HƠN, NHỎ HƠN, KHÁC hoặc GẦN GIỐNG nữa... và JoinIf của tôi viết ra là để phục vụ cho nhu cầu này (gần giống với SUMIF)
SUMIF là do cả tập đoàn MS viết ra mà trong một số trường hợp cụ thể còn có sai sót (đã bàn trên diễn đàn nhiều lần rồi). Vậy nên MS cũng viết thêm hàm SUMPRODUCT để ta tùy ý phát biểu điều kiện... Thực chất chúng ta không thể viết 1 hàm tổng quát đến mức có thể đáp ứng mọi dữ liệu và mọi nhu cầu... nên tôi cũng bắt chước MS, viết thêm hàm JoinText để người dùng có thêm lựa chọn trong trường hợp điều kiện so sánh phức tạp
Vậy:
- Nếu cảm thấy SUMIF không chính xác thì dùng SUMPRODUCT
- Cũng giống như nếu cảm thấy JoinIf không chính xác thì dùng JoinText
Thế thôi
 
Upvote 0
Cái này như tôi đã nói ở trên: Thêm dấu "=" để so sánh rồi còn gì

Một dữ liệu vừa là chuỗi, vừa là số, mà để dấu "=" thì đúng phần số và sai phần chuỗi, Thầy thử nghĩ coi, nếu phải mỗi ô mỗi công thức khác nhau thì sao được hả Thầy?

Còn việc so sánh lớn hơn, nhỏ hơn thì bắt buộc dữ liệu điều kiện phải là dạng số

Và việc so sánh na ná giống có lẽ phải dữ liệu bằng chuỗi thôi.

Dĩ nhiên trình độ em được học từ Thầy, nhưng đây là ý tưởng để Thầy hoàn thiện, bổ sung thêm cho nó hoàn chỉnh mà thôi, em không có ý gì đâu ạ.
 
Lần chỉnh sửa cuối:
Upvote 0
Một dữ liệu vừa là chuỗi, vừa là số, mà để dấu "=" thì đúng phần số và sai phần chuỗi, Thầy thử nghĩ coi, nếu phải mỗi ô mỗi công thức khác nhau thì sao được hả Thầy?
Thì dùng hàm JoinText
Và việc so sánh na ná giống có lẽ phải dữ liệu bằng chuỗi thôi.
Na ná nghĩa là *Chuổi* ấy, đương nhiên là so sánh chuổi rồi. Code tôi dùng toán tử Like nên chẳng cần phải suy nghĩ gì nhiều, tự nhiên nó vẫn đạt được như vậy thôi (áp dụng giải thuật trong hàm Filter2DArray)
Dĩ nhiên trình độ em được học từ Thầy, nhưng đây là ý tưởng để Thầy hoàn thiện, bổ sung thêm cho nó hoàn chỉnh mà thôi, em không có ý gì đâu ạ.

Chú mày nói quá! Chỉ là nghiên cứu thôi (với lại tôi cũng không nghĩ phải hoàn thiện thêm gì nữa cả: 2 hàm JoinIf và JoinText là quá đủ để áp dụng)
------------------------------------------
(Đã dời bài đúng box)
 
Lần chỉnh sửa cuối:
Upvote 0

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

Back
Top Bottom