Lại hỏi vấn đề gộp dòng theo điều kiện

Liên hệ QC

Yeswrong

Thành viên mới
Tham gia
18/1/07
Bài viết
22
Được thích
6
Em muốn biết dòng nào được gộp vào dòng nào trong excel như y/c trong file att các anh chị giúp em cái

Em ưu tiên công thức vì Macro thì em không biết gì cả nếu anh chị hướng dẫn bằng maccro thì chỉ cho em chu đáo 1 tí nhé, em chỉ biết ấn mỗi ALT + F11 thôi

Vừa rồi em quên att
 

File đính kèm

Lần chỉnh sửa cuối:
Em muốn biết dòng nào được gộp vào dòng nào trong excel như y/c trong file att các anh chị giúp em cái

Em ưu tiên công thức vì Macro thì em không biết gì cả nếu anh chị hướng dẫn bằng maccro thì chỉ cho em chu đáo 1 tí nhé, em chỉ biết ấn mỗi ALT + F11 thôi

Vừa rồi em quên att
Tôi nghĩ bài này chỉ có thể làm bằng code VBA
Dạng yêu cầu của bạn gần giống với hàm JoinIf tôi đã viết, chỉ có khác là bạn bỏ phần tử đầu tiên! Vậy tôi sửa lại hàm JoinIf này tí xiu
PHP:
Function JoinIf(CritArr, Criteria, ResArr, Sep As String, Optional FirstItem As Boolean = True) As String
  Dim CritTmp, ResTmp, i As Long, j As Long, k As Long, Arr()
  CritTmp = CritArr: ResTmp = ResArr
  On Error Resume Next
  For i = LBound(CritTmp, 1) To UBound(CritTmp, 1)
    For j = LBound(CritTmp, 2) To UBound(CritTmp, 2)
      If CritTmp(i, j) = Criteria And CritTmp(i, j) <> "" Then
        k = k + 1
        If k > 1 + FirstItem Then
          ReDim Preserve Arr(1 To IIf(FirstItem, k, k - 1))
          Arr(IIf(FirstItem, k, k - 1)) = ResTmp(i, j)
        End If
      End If
    Next
  Next
  JoinIf = Join(Arr, Sep)
End Function
Ngoài ra, nếu đã lở làm bằng VBA thì ta dùng VBA toàn bộ ---> Trong file của bạn, để lọc duy nhất 3 điều kiện, bạn đã phải tốn 2 cột phụ ---> Tôi bỏ luôn, dùng code nhé
PHP:
Function UniqueMultiArr(Pos As Long, ColIndex As Long, ParamArray sArray() As Variant) As String
  Dim TmpArr, Tmp, ResArr, uCrit As String, i As Long, j As Long, k As Long, n As Long
  On Error Resume Next
  TmpArr = sArray(0)
  With CreateObject("Scripting.Dictionary")
    For i = LBound(TmpArr, 1) To UBound(TmpArr, 1)
      For j = LBound(TmpArr, 2) To UBound(TmpArr, 2)
        uCrit = ""
        For k = 0 To UBound(sArray)
          Tmp = sArray(k)
          uCrit = uCrit & Tmp(i, j)
          If k = ColIndex - 1 Then ResArr = Tmp(i, j)
        Next
        If uCrit <> "" Then
          If Not .Exists(uCrit) Then
            .Add uCrit, "": Pos = Pos - 1
            If Pos = 0 Then UniqueMultiArr = ResArr: Exit Function
          End If
        End If
      Next j
    Next i
  End With
End Function
Cái trò Unique nhiều điều kiện của bạn rất hay ---> Để viết thành code phải vả mồ hôi mất buổi tối
----------------
Áp dụng cho công thức UniqueMultiArr
- Tại cell K3 ta gõ công thức:
=UniqueMultiArr(ROWS($1:1),1,$D$3:$D$12,$F$3:$F$12,$G$3:$G$12)
ROWS($1:1) ý muốn nói bạn đang lấy phần tử đầu tiên mà ta tìm thấy
Số 1 màu đổ ý muốn nói sau khi so sánh duy nhất ở 3 mảng $D$3:$D$12, $F$3:$F$12 và $G$3:$G$12 thì cái ta cần lấy nằm ở mảng số 1 (tức $D$3:$D$12)
Áp dụng cho công thức JoinIf:
- Tại cell I3 ta gõ công thức:
=JoinIf($D$3:$D$12,$K3,$C$3:$C$12,", ",FALSE)
Đối số màu đỏ, nếu = TRUE nghĩa là lấy luôn phần tử đầu tiên, ngược lại là... giống như ý của bạn
Xem file nhé (hơi khó hiểu 1 chút)
Lưu ý: Vì bạn nói bạn không biết macro nên khi mở file nhớ Enable macros nhé ---> nếu không thì hàm sẽ không chạy đâu
 

File đính kèm

Lần chỉnh sửa cuối:
Em cảm ơn thầy NDU nhiều.
Hôm trước em hỏi cái thread này:
http://www.giaiphapexcel.com/forum/...iống-nhau-cùng-đơn-giá-thành-1-dòng&highlight=
được nhiều bác cho nhiều giải pháp và chọn được cách của bác 3T vì nó hợp với khả năng hiểu của em, từ đó em học thêm được hàm sumprroduct và hàm max em thấy rất thú vị
"Cái trò Unique nhiều điều kiện của bạn rất hay ---> Để viết thành code phải vả mồ hôi mất buổi tối" Thầy nói cứ dễ như là nấu 1 bữa cơm vậy.

Em hòi chút riêng là: Học đểt viết được cái code này thì phải bắt đầu học từ đâu vậy thầy. Đến trung tâm người ta chỉ có học tin học văn phòng chung chung là excel word ... thôi.
Em có điều kiện kinh tế đi học nhưng hơi già rồi (hơn 30) không biết có có kịp học không ạ (học mà mất vài năm là em chịu rồi)
 
Thầy NDU ơi khi em xoá dữ liệu cell D6 thì nó lại trống một dòng; Vùng màu vàng là cái công thức cũ của em
Với lại em muốn cho cái đoạn Joinif vào file gốc của em thì phải làm thế nào?
En đã làm:
Mở cái file gốc ra ấn alt+F11 paste đoạn này của thầy vào

Function JoinIf(CritArr, Criteria, ResArr, Sep As String, Optional FirstItem As Boolean = True) As String
Dim CritTmp, ResTmp, i As Long, j As Long, k As Long, Arr()
....
JoinIf = Join(Arr, Sep)
End Function

save và đóng cả lại, khi mở ra đánh công thức nó báo #NAME?
 

File đính kèm

Thầy NDU ơi khi em xoá dữ liệu cell D6 thì nó lại trống một dòng; Vùng màu vàng là cái công thức cũ của em
Về nguyên tắc, nếu bạn chỉ xóa cell D6 nhưng các cell khác cùng dòng vẫn còn thì ta cũng phải coi dòng ấy là 1 thành phần, và nó vẫn ra kết quả thôi ---> Nếu bạn muốn giống như công thức của bạn thì cũng không có vấn đề gì, chỉ thêm 1 cái IF nữa là xong (Đã sửa)

Với lại em muốn cho cái đoạn Joinif vào file gốc của em thì phải làm thế nào?
En đã làm:
Mở cái file gốc ra ấn alt+F11 paste đoạn này của thầy vào

Function JoinIf(CritArr, Criteria, ResArr, Sep As String, Optional FirstItem As Boolean = True) As String
Dim CritTmp, ResTmp, i As Long, j As Long, k As Long, Arr()
....
JoinIf = Join(Arr, Sep)
End Function

save và đóng cả lại, khi mở ra đánh công thức nó báo #NAME?
Để chèn code của tôi vào file gốc của bạn, ta làm như sau:
- Copy code của tôi
- Mở file gốc của bạn
- Bấm Alt + F11 để vào khung soạn thảo code
- Vảo menu Insert\Module rồi paste code vào khung bên phải
- Đóng khung soạn thảo code, ra bảng tính và gõ công thức
Ngoải ra có cách khác nhanh hơn
- Mở file của tôi cùng với file của bạn
- Bấm Alt + F11
- Dùng chuột nắm Module1 trong file chứa code, kéo và thả vào file của bạn

untitled.JPG
 

File đính kèm

Em chèn được cái đoạn code JOIN đó rồi thầy ạ; Em cảm ơn thầy nhiều.
Nhưng cái unique trong file nó vẫn sai
 

File đính kèm

Em chèn được cái đoạn code JOIN đó rồi thầy ạ; Em cảm ơn thầy nhiều.
Nhưng cái unique trong file nó vẫn sai
Sai chổ nào hả bạn?
Cái chổ bạn đánh dấu màu vàng ấy có cùng mã, dùng ĐK khác nhưng khác đơn giá cơ mà
 
Cái ô I4 đơn giá 0.0072 thì nó phải ghi là lấy dòng 3 và 7 mới đúng đây nó lại lấy 4,7
 
Thầy NDU ơi em nhầm, cái unique chạy nó đúng; cái Join nó bị sai, nó chỉ check mỗi phần mã trùng nhau trong khi em muốn là dòng nào được gộp thì nó ghi ra cột I.
 
Lần chỉnh sửa cuối:
Thầy NDU ơi em nhầm, cái unique chạy nó đúng; cái Join nó bị sai, nó chỉ check mỗi phần mã trùng nhau trong khi em muốn là dòng nào được gộp thì nó ghi ra cột I.
Bài này đúng là khoai thật ---> Thì ra cái thằng JoinIf nó cũng phải hoạt động gần giống với hàm UniqueMultiArr thì mới được, tức dò tìm nhiều điều kiện (tôi nhầm chổ này, tưởng chỉ dò cột đầu tiên)
Giờ sửa lại nhé!
PHP:
Function JoinIfMultiArr(Criteria, FirstItem As Boolean, ParamArray sArray() As Variant) As String
  Dim TmpArr, Tmp, tCrit As String, i As Long, j As Long, k As Long, n As Long, Arr()
  On Error Resume Next
  TmpArr = sArray(0)
  For i = LBound(TmpArr, 1) To UBound(TmpArr, 1)
    For j = LBound(TmpArr, 2) To UBound(TmpArr, 2)
      tCrit = ""
      If TmpArr(i, j) <> "" Then
        For k = 0 To UBound(sArray)
          Tmp = sArray(k)
          tCrit = tCrit & Tmp(i, j)
        Next
        If tCrit = Criteria Then
          n = n + 1
          If n > 1 + FirstItem Then
            ReDim Preserve Arr(1 To IIf(FirstItem, n, n - 1))
            Arr(IIf(FirstItem, n, n - 1)) = i
          End If
        End If
      End If
    Next
  Next
  JoinIfMultiArr = Join(Arr, ", ")
End Function
Bạn kiểm tra lại giúp tôi!
Lưu ý: Cú pháp hàm JoinIf giờ đã thay đổi rồi, cả tên hàm cũng đổi luôn
Tại I3 bạn gõ công thức:
Mã:
=JoinIfMultiArr($K3&$N3&$L3,FALSE,$D$3:$D$12,$F$3:$F$12,$G$3:$G$12)
Kéo fill xuống
 

File đính kèm

Thấy ơi cái join mới này thì chuẩn luôn

Em cho vào cái bảng dữ liệu gốc thì có 1 khó khăn thực sự như sau:
Tại dòng được gộp đầu tiên thì nhận ra ngay các con gộp
Tại dòng được gộp tiếp theo thì nó bị lệch pha => chẳng biết con nào bị gộp đầu tiên => cực khó kiểm tra với chứng từ giấy

Em mong muốn cột H nó thể hiện được như cột N có được không thầy tức là viết số thứ tự của của chính nó ra nữa

File gốc của em 1 lần giao hàng tối thiểu khoảng 1000 mục (30 trang A4) gộp lại thì chỉ có khoảng 5 trang a4 thôi kiểm tra lệch pha thế này thì quả thật rất nản
 

File đính kèm

Em mong muốn cột H nó thể hiện được như cột N có được không thầy tức là viết số thứ tự của của chính nó ra nữa

File gốc của em 1 lần giao hàng tối thiểu khoảng 1000 mục (30 trang A4) gộp lại thì chỉ có khoảng 5 trang a4 thôi kiểm tra lệch pha thế này thì quả thật rất nản
Tôi đã lường trước việc này nên trong hàm có đối số cho phép chọn TRUE và FALSE
TRUE : lấy luôn item đầu tiên
FALSE: bỏ qua item đầu tiên
Vậy trong công thức trên, bạn thử thay FALSE thành TRUE xem ---> Và nếu sửa như vậy thì những phần tử duy nhất (chỉ mình nó, không gộp từ đâu cả) cũng sẽ được thể hiện ---> Nếu không muốn điều này thì chỉ cần sửa đoạn code cuối cùng
PHP:
JoinIfMultiArr = Join(Arr, ", ")
thành vầy:
PHP:
JoinIfMultiArr = IIf(UBound(Arr) = 1, "", Join(Arr, ", "))
 

File đính kèm

Lần chỉnh sửa cuối:
Chuẩn và đúng mong muốn rồi thầy ạ, em dùng cách đổi thành TRUE để dễ cho check chứng từ giấy
Cảm ơn thầy nhiều
 
Thầy ơi lại phát sinh tiếp là cả Join và Uni nó phân biệt chữ hoa và chữ thường có cách nào khắc phục vấn đề này không thầy

Hiện tại em đang làm thủ công là upper tất cả rồi sau mới copy vào dữ liệu gốc
 
Thầy ơi lại phát sinh tiếp là cả Join và Uni nó phân biệt chữ hoa và chữ thường có cách nào khắc phục vấn đề này không thầy

Hiện tại em đang làm thủ công là upper tất cả rồi sau mới copy vào dữ liệu gốc
Mình không nghĩ là bạn lại không tự sửa được chổ này? Bạn biết dùng hàm UPPER, vậy thì trong VBA cũng thế thôi (trong VBA là UCase)
Sửa chổ này:
Mã:
If tCrit = Criteria Then
Thành:
Mã:
If UCase(tCrit) = UCase(Criteria) Then
Sửa chổ này:
Mã:
If Not .Exists(uCrit) Then
              .Add uCrit, "": Pos = Pos - 1
Thành:
Mã:
If Not .Exists(UCase(uCrit)) Then
              .Add UCase(uCrit),"": Pos = Pos - 1
 

File đính kèm

VBA em không biết tí gì mà thầy, em đang định tìm lớp đi học cho nó sáng dạ ra 1 chút. Công thức chỉ biết vài cái thông dụng thôi
 
Cho mình hỏi Thầy ndu một cái:
Bài này sao không sử dụng Sub mà dùng Function. Mình cảm giác giải quyết bằng Sub nhẹ nhàng hơn nhiều mà Thầy
Mã:
Public Sub gom()
    Dim d, Vung As Range, J As Integer, Cll As Range, Mg(1 To 500, 1 To 6), Kk As Integer, Tam
    Range([i3], [i5000].End(xlUp)).Resize(, 6).Clear
        Set d = CreateObject("Scripting.Dictionary")
        Set Vung = Range([d3], [d5000].End(xlUp))
        J = 1
            For Each Cll In Vung
                Tam = Cll.Value & Cll.Offset(, 2).Value & Cll.Offset(, 3).Value
                Tam = UCase(Tam)
                    If Not d.exists(Tam) Then
                        d.Add Tam, J
                        Mg(J, 1) = Cll.Offset(, -1)
                        Mg(J, 2) = J
                        Mg(J, 3) = Cll
                        Mg(J, 4) = Cll.Offset(, 1)
                        Mg(J, 5) = Cll.Offset(, 2)
                        Mg(J, 6) = Cll.Offset(, 3)
                        J = J + 1
                    Else
                        Kk = d.Item(Tam)
                        Mg(Kk, 4) = Mg(Kk, 4) + Cll.Offset(, 1)
                        Mg(Kk, 1) = Mg(Kk, 1) & " ," & Cll.Offset(, -1)
                    End If
            Next
[i3].Resize(J, 6) = Mg
End Sub
 

File đính kèm

Cho mình hỏi Thầy ndu một cái:
Bài này sao không sử dụng Sub mà dùng Function. Mình cảm giác giải quyết bằng Sub nhẹ nhàng hơn nhiều mà Thầy
Thì đương nhiên Sub sẽ nhẹ hơn nhưng không phải dùng Sub sẽ ngon hơn!
- Dùng Sub, anh bị hạn chế về các tham chiếu, chỉ chạy được với dữ liệu này mà bó tay với dữ liệu khác (mỗi lần dữ liệu đổi khác, buộc anh phải sửa code)
- Dùng Function sẽ cho ta khả năng tùy biến cao với mọi loại dữ liệu
-----------------
Để kết hợp ưu điểm của cả 2, có chăng là anh phải dùng Sub có tham số truyền
 
Web KT

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

Back
Top Bottom