Code VBA tách dữ liệu theo thể tích và tên mặt hàng

Liên hệ QC
Tôi tuân thủ nội quy khi đăng bài

Văn Toàn 1996

Thành viên hoạt động
Tham gia
5/6/23
Bài viết
102
Được thích
22
em chào tất cả mọi người GPE. em có 1 file dữ liệu thô có vùng dữ liệu B4:F1000 , tên mặt hàng của em có 2 loại ( tên có kích thước và không có kích thước ). em mong muốn code chạy tách được ra như vùng H4:I15 ( như hình mô tả ). Nếu mặt hàng nào có kích thước mà trùng tên thì tách ra và cộng dồn lại cột tổng, còn mặt hàng nào không có kích thước vẫn giử nguyên. Em xin chân thành cảm ơn

1693326577980.pngÁCH
 

File đính kèm

  • the tich.xlsm
    11.6 KB · Đọc: 12
em chào tất cả mọi người GPE. em có 1 file dữ liệu thô có vùng dữ liệu B4:F1000 , tên mặt hàng của em có 2 loại ( tên có kích thước và không có kích thước ). em mong muốn code chạy tách được ra như vùng H4:I15 ( như hình mô tả ). Nếu mặt hàng nào có kích thước mà trùng tên thì tách ra và cộng dồn lại cột tổng, còn mặt hàng nào không có kích thước vẫn giử nguyên. Em xin chân thành cảm ơn

View attachment 294362ÁCH
Trong khi chờ đợi các giải pháp khác, hãy thử code này xem sao.
Mã:
Option Explicit

Sub VanToan1996()
Dim i&, j&, lr&, R&, n&, m&
Dim Arr(), KQ(), S, Tong()
Dim Dic As Object, Key
Dim Ws As Worksheet
Set Ws = Sheet1
lr = Ws.Cells(10000, "B").End(3).Row
Arr = Ws.Range("B4:F" & lr).Value
R = UBound(Arr)
ReDim KQ(1 To R * 2, 1 To 2): ReDim Tong(1 To R * 2)
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To R
    Key = Arr(i, 1)
    If Not Dic.exists(Key) Then         Dic(Key) = i    Else        Dic(Key) = Dic(Key) & "," & i
Next i
For Each Key In Dic.Keys
    j = j + 1:    KQ(j, 1) = Key
    S = Split(Dic(Key), ",")
    If UBound(S) > 0 Then
        n = j
        For m = 0 To UBound(S)
            n = n + 1
            KQ(n, 1) = "  -" & Arr(S(m), 2) & "x" & Arr(S(m), 3) & "x" & Arr(S(m), 4) & "  =" & Arr(S(m), 5)
            KQ(j, 2) = KQ(j, 2) + Arr(S(m), 5)
        Next m
        j = n
    ElseIf UBound(S) = 0 Then
        If Arr(S(0), 2) <> Empty Or Arr(S(0), 3) <> Empty Or Arr(S(0), 4) <> Empty Then
            n = j + 1
            KQ(n, 1) = "  -" & Arr(S(0), 2) & "x" & Arr(S(0), 3) & "x" & Arr(S(0), 4) & "  =" & Arr(S(0), 5)
            KQ(j, 2) = KQ(j, 2) + Arr(S(0), 5)
        Else
            KQ(j, 2) = Arr(S(0), 5):            n = j
        End If
        j = n
    End If
  
Next
If j Then
    Ws.Range("K4").Resize(10000, 2).ClearContents
    Ws.Range("K4").Resize(j, 2) = KQ
End If
Set Dic = Nothing
End Sub
 
Upvote 0
Trong khi chờ đợi các giải pháp khác, hãy thử code này xem sao.
Mã:
Option Explicit

Sub VanToan1996()
Dim i&, j&, lr&, R&, n&, m&
Dim Arr(), KQ(), S, Tong()
Dim Dic As Object, Key
Dim Ws As Worksheet
Set Ws = Sheet1
lr = Ws.Cells(10000, "B").End(3).Row
Arr = Ws.Range("B4:F" & lr).Value
R = UBound(Arr)
ReDim KQ(1 To R * 2, 1 To 2): ReDim Tong(1 To R * 2)
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To R
    Key = Arr(i, 1)
    If Not Dic.exists(Key) Then         Dic(Key) = i    Else        Dic(Key) = Dic(Key) & "," & i
Next i
For Each Key In Dic.Keys
    j = j + 1:    KQ(j, 1) = Key
    S = Split(Dic(Key), ",")
    If UBound(S) > 0 Then
        n = j
        For m = 0 To UBound(S)
            n = n + 1
            KQ(n, 1) = "  -" & Arr(S(m), 2) & "x" & Arr(S(m), 3) & "x" & Arr(S(m), 4) & "  =" & Arr(S(m), 5)
            KQ(j, 2) = KQ(j, 2) + Arr(S(m), 5)
        Next m
        j = n
    ElseIf UBound(S) = 0 Then
        If Arr(S(0), 2) <> Empty Or Arr(S(0), 3) <> Empty Or Arr(S(0), 4) <> Empty Then
            n = j + 1
            KQ(n, 1) = "  -" & Arr(S(0), 2) & "x" & Arr(S(0), 3) & "x" & Arr(S(0), 4) & "  =" & Arr(S(0), 5)
            KQ(j, 2) = KQ(j, 2) + Arr(S(0), 5)
        Else
            KQ(j, 2) = Arr(S(0), 5):            n = j
        End If
        j = n
    End If
 
Next
If j Then
    Ws.Range("K4").Resize(10000, 2).ClearContents
    Ws.Range("K4").Resize(j, 2) = KQ
End If
Set Dic = Nothing
End Sub
Dữ liệu sắp sẵn thế này đâu cần phải dùng dic nhỉ?!
 
Upvote 0
Trong khi chờ đợi các giải pháp khác, hãy thử code này xem sao.
Mã:
Option Explicit

Sub VanToan1996()
Dim i&, j&, lr&, R&, n&, m&
Dim Arr(), KQ(), S, Tong()
Dim Dic As Object, Key
Dim Ws As Worksheet
Set Ws = Sheet1
lr = Ws.Cells(10000, "B").End(3).Row
Arr = Ws.Range("B4:F" & lr).Value
R = UBound(Arr)
ReDim KQ(1 To R * 2, 1 To 2): ReDim Tong(1 To R * 2)
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To R
    Key = Arr(i, 1)
    If Not Dic.exists(Key) Then         Dic(Key) = i    Else        Dic(Key) = Dic(Key) & "," & i
Next i
For Each Key In Dic.Keys
    j = j + 1:    KQ(j, 1) = Key
    S = Split(Dic(Key), ",")
    If UBound(S) > 0 Then
        n = j
        For m = 0 To UBound(S)
            n = n + 1
            KQ(n, 1) = "  -" & Arr(S(m), 2) & "x" & Arr(S(m), 3) & "x" & Arr(S(m), 4) & "  =" & Arr(S(m), 5)
            KQ(j, 2) = KQ(j, 2) + Arr(S(m), 5)
        Next m
        j = n
    ElseIf UBound(S) = 0 Then
        If Arr(S(0), 2) <> Empty Or Arr(S(0), 3) <> Empty Or Arr(S(0), 4) <> Empty Then
            n = j + 1
            KQ(n, 1) = "  -" & Arr(S(0), 2) & "x" & Arr(S(0), 3) & "x" & Arr(S(0), 4) & "  =" & Arr(S(0), 5)
            KQ(j, 2) = KQ(j, 2) + Arr(S(0), 5)
        Else
            KQ(j, 2) = Arr(S(0), 5):            n = j
        End If
        j = n
    End If
 
Next
If j Then
    Ws.Range("K4").Resize(10000, 2).ClearContents
    Ws.Range("K4").Resize(j, 2) = KQ
End If
Set Dic = Nothing
End Sub
Cảm ơn bạn đã hỗ trợ. Bạn có thể sửa lại giúp mình nếu trường hợp 2 tên giống nhau mà không có kích thước thì vẫn giữ nguyên như củ. Không cần tách ( Ví dụ như dòng Trái cây bên dưới )

1693367688259.png
 
Upvote 0
Như vậy có được không?

1693368634064.png

G4 =IF(C4="","",C4&"x"&D4&"x"&E4&" = "&F4)
 
Upvote 0
Dữ liệu sắp sẵn thế này đâu cần phải dùng dic nhỉ?!
Cảm ơn đã xem bài.
Hy vọng được xem code xịn.
Bài đã được tự động gộp:

Cảm ơn bạn đã hỗ trợ. Bạn có thể sửa lại giúp mình nếu trường hợp 2 tên giống nhau mà không có kích thước thì vẫn giữ nguyên như củ. Không cần tách ( Ví dụ như dòng Trái cây bên dưới )

View attachment 294369
Thay bằng code này:
Mã:
Option Explicit

Sub VanToan1996()
Dim i&, j&, lr&, R&, n&, m&
Dim Arr(), KQ(), S, Tong()
Dim Dic As Object, Key
Dim Ws As Worksheet
Set Ws = Sheet1
lr = Ws.Cells(10000, "B").End(3).Row
Arr = Ws.Range("B4:F" & lr).Value
R = UBound(Arr)
ReDim KQ(1 To R * 2, 1 To 2): ReDim Tong(1 To R * 2)
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To R
    Key = Arr(i, 1)
    If Not Dic.exists(Key) Then Dic(Key) = i Else Dic(Key) = Dic(Key) & "," & i
Next i
For Each Key In Dic.Keys
    j = j + 1:     KQ(j, 1) = Key
    S = Split(Dic(Key), ",")
    If UBound(S) > 0 Then
        n = j
        For m = 0 To UBound(S)
        If Arr(S(m), 2) <> Empty Or Arr(S(m), 3) <> Empty Or Arr(S(m), 4) <> Empty Then
            n = n + 1
            KQ(n, 1) = "  -" & Arr(S(m), 2) & "x" & Arr(S(m), 3) & "x" & Arr(S(m), 4) & "  =" & Arr(S(m), 5)
        End If
            KQ(j, 2) = KQ(j, 2) + Arr(S(m), 5)
        Next m
        j = n
    ElseIf UBound(S) = 0 Then
        If Arr(S(0), 2) <> Empty Or Arr(S(0), 3) <> Empty Or Arr(S(0), 4) <> Empty Then
            n = j + 1
            KQ(n, 1) = "  -" & Arr(S(0), 2) & "x" & Arr(S(0), 3) & "x" & Arr(S(0), 4) & "  =" & Arr(S(0), 5)
            KQ(j, 2) = KQ(j, 2) + Arr(S(0), 5)
        Else
            KQ(j, 2) = Arr(S(0), 5):            n = j
        End If
        j = n
    End If
  
Next
If j Then
    Ws.Range("K4").Resize(10000, 2).ClearContents
    Ws.Range("K4").Resize(j, 2) = KQ
End If
Set Dic = Nothing
End Sub
 
Upvote 0
Cảm ơn đã xem bài.
Hy vọng được xem code xịn.
Bài đã được tự động gộp:


Thay bằng code này:
Mã:
Option Explicit

Sub VanToan1996()
Dim i&, j&, lr&, R&, n&, m&
Dim Arr(), KQ(), S, Tong()
Dim Dic As Object, Key
Dim Ws As Worksheet
Set Ws = Sheet1
lr = Ws.Cells(10000, "B").End(3).Row
Arr = Ws.Range("B4:F" & lr).Value
R = UBound(Arr)
ReDim KQ(1 To R * 2, 1 To 2): ReDim Tong(1 To R * 2)
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To R
    Key = Arr(i, 1)
    If Not Dic.exists(Key) Then Dic(Key) = i Else Dic(Key) = Dic(Key) & "," & i
Next i
For Each Key In Dic.Keys
    j = j + 1:     KQ(j, 1) = Key
    S = Split(Dic(Key), ",")
    If UBound(S) > 0 Then
        n = j
        For m = 0 To UBound(S)
        If Arr(S(m), 2) <> Empty Or Arr(S(m), 3) <> Empty Or Arr(S(m), 4) <> Empty Then
            n = n + 1
            KQ(n, 1) = "  -" & Arr(S(m), 2) & "x" & Arr(S(m), 3) & "x" & Arr(S(m), 4) & "  =" & Arr(S(m), 5)
        End If
            KQ(j, 2) = KQ(j, 2) + Arr(S(m), 5)
        Next m
        j = n
    ElseIf UBound(S) = 0 Then
        If Arr(S(0), 2) <> Empty Or Arr(S(0), 3) <> Empty Or Arr(S(0), 4) <> Empty Then
            n = j + 1
            KQ(n, 1) = "  -" & Arr(S(0), 2) & "x" & Arr(S(0), 3) & "x" & Arr(S(0), 4) & "  =" & Arr(S(0), 5)
            KQ(j, 2) = KQ(j, 2) + Arr(S(0), 5)
        Else
            KQ(j, 2) = Arr(S(0), 5):            n = j
        End If
        j = n
    End If
 
Next
If j Then
    Ws.Range("K4").Resize(10000, 2).ClearContents
    Ws.Range("K4").Resize(j, 2) = KQ
End If
Set Dic = Nothing
End Sub
cảm ơn bạn. Ý mình là nếu dòng nào không có kích thước thì vẫn giữ nguyên không cần Gom lại. Ví dụ dòng Trái cây nó bao nhiêu dòng thì giữ lại nguyên thủy không cần làm gì cả. Nhờ bạn sửa lại như vậy là Đúng ý mình luôn. rất cảm ơn bạn đã nhiệt tình hỗ trợ

Kết Quả Code Hiện tại:
1693372720711.png

Kết Quả Mình mong muốn:
1693372748120.png
Bài đã được tự động gộp:

Như vậy có được không?

View attachment 294370

G4 =IF(C4="","",C4&"x"&D4&"x"&E4&" = "&F4)
dạ cảm ơn a. em cần dữ liệu Thô để em xử lý qua công đoạn khác, nên cần Code ra dữ liệu thô
 
Upvote 0
Upvote 0
Cảm ơn đã xem bài.
Hy vọng được xem code xịn.
Bài đã được tự động gộp:


Thay bằng code này:
Mã:
Option Explicit

Sub VanToan1996()
Dim i&, j&, lr&, R&, n&, m&
Dim Arr(), KQ(), S, Tong()
Dim Dic As Object, Key
Dim Ws As Worksheet
Set Ws = Sheet1
lr = Ws.Cells(10000, "B").End(3).Row
Arr = Ws.Range("B4:F" & lr).Value
R = UBound(Arr)
ReDim KQ(1 To R * 2, 1 To 2): ReDim Tong(1 To R * 2)
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To R
    Key = Arr(i, 1)
    If Not Dic.exists(Key) Then Dic(Key) = i Else Dic(Key) = Dic(Key) & "," & i
Next i
For Each Key In Dic.Keys
    j = j + 1:     KQ(j, 1) = Key
    S = Split(Dic(Key), ",")
    If UBound(S) > 0 Then
        n = j
        For m = 0 To UBound(S)
        If Arr(S(m), 2) <> Empty Or Arr(S(m), 3) <> Empty Or Arr(S(m), 4) <> Empty Then
            n = n + 1
            KQ(n, 1) = "  -" & Arr(S(m), 2) & "x" & Arr(S(m), 3) & "x" & Arr(S(m), 4) & "  =" & Arr(S(m), 5)
        End If
            KQ(j, 2) = KQ(j, 2) + Arr(S(m), 5)
        Next m
        j = n
    ElseIf UBound(S) = 0 Then
        If Arr(S(0), 2) <> Empty Or Arr(S(0), 3) <> Empty Or Arr(S(0), 4) <> Empty Then
            n = j + 1
            KQ(n, 1) = "  -" & Arr(S(0), 2) & "x" & Arr(S(0), 3) & "x" & Arr(S(0), 4) & "  =" & Arr(S(0), 5)
            KQ(j, 2) = KQ(j, 2) + Arr(S(0), 5)
        Else
            KQ(j, 2) = Arr(S(0), 5):            n = j
        End If
        j = n
    End If
 
Next
If j Then
    Ws.Range("K4").Resize(10000, 2).ClearContents
    Ws.Range("K4").Resize(j, 2) = KQ
End If
Set Dic = Nothing
End Sub
Bạn thử code không dùng dic sẽ gọn hơn
 
Upvote 0
Pivot table xong copy là ra dữ liệu thô. Hoaa85c dùng chính pivot table làm dữ liệu thô.
Tạo cột calculated field lúc dựng Data Table. Pivot Table làm êm ái.
Nhưng kiểu trả lời của thớt có lẽ là dân quen code, không hề đối diện với các công cụ trung gian.
 
Upvote 0
Tạo cột calculated field lúc dựng Data Table. Pivot Table làm êm ái.
Nhưng kiểu trả lời của thớt có lẽ là dân quen code, không hề đối diện với các công cụ trung gian.
Lại còn kiểu lấy kết quả là dữ liệu thô. Tôi không hiểu dữ liệu có dòng Sub total mà dùng làm dữ liệu thô kiểu gì.
 
Upvote 0
Xài đỡ cái này:
PHP:
Option Explicit
Sub gop()
Dim lr&, k&, ce As Range, sum&, pos&, count&, res(1 To 1000, 1 To 2)
lr = Cells(Rows.count, "B").End(xlUp).Row
For Each ce In Range("B4:B" & lr)
    count = WorksheetFunction.CountA(ce.Resize(1, 4))
    If count = 1 Or ce.Offset(-1, 0) <> ce Then
        sum = 0: k = k + 1: pos = k: res(k, 1) = ce: res(k, 2) = ce.Offset(0, 4)
        If count = 1 Then GoTo z
    End If
    k = k + 1: res(k, 1) = " -" & ce.Offset(0, 1) & "x" & ce.Offset(0, 2) & _
         "x" & ce.Offset(0, 3) & " = " & ce.Offset(0, 4)
    sum = sum + ce.Offset(0, 4): res(pos, 2) = sum
z:
Next
Range("H4:I10000").ClearContents
Range("H4").Resize(k, 2).Value = res
End Sub
 

File đính kèm

  • the tich.xlsm
    23.4 KB · Đọc: 8
Upvote 0
cảm ơn bạn. Ý mình là nếu dòng nào không có kích thước thì vẫn giữ nguyên không cần Gom lại. Ví dụ dòng Trái cây nó bao nhiêu dòng thì giữ lại nguyên thủy không cần làm gì cả. Nhờ bạn sửa lại như vậy là Đúng ý mình luôn. rất cảm ơn bạn đã nhiệt tình hỗ trợ

Kết Quả Code Hiện tại:
View attachment 294376

Kết Quả Mình mong muốn:
View attachment 294377
Bài đã được tự động gộp:


dạ cảm ơn a. em cần dữ liệu Thô để em xử lý qua công đoạn khác, nên cần Code ra dữ liệu thô
Chỉnh lại:
Mã:
Sub VanToan1996()
Dim i&, j&, lr&, R&, n&, m&
Dim Arr(), KQ(), S, Tong()
Dim Dic As Object, Key
Dim Ws As Worksheet
Set Ws = Sheet1
lr = Ws.Cells(10000, "B").End(3).Row
Arr = Ws.Range("B4:F" & lr).Value
R = UBound(Arr)
ReDim KQ(1 To R * 2, 1 To 2): ReDim Tong(1 To R * 2)
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To R
    Key = Arr(i, 1)
    If Not Dic.exists(Key) Then Dic(Key) = i Else Dic(Key) = Dic(Key) & "," & i
Next i
For Each Key In Dic.Keys
    j = j + 1:     KQ(j, 1) = Key
    S = Split(Dic(Key), ",")
    If UBound(S) > 0 Then
        n = j
        For m = 0 To UBound(S)
        If Arr(S(m), 2) <> Empty Or Arr(S(m), 3) <> Empty Or Arr(S(m), 4) <> Empty Then
            n = n + 1
            KQ(n, 1) = "  -" & Arr(S(m), 2) & "x" & Arr(S(m), 3) & "x" & Arr(S(m), 4) & "  =" & Arr(S(m), 5)
        Else
            n = n + 1
            KQ(n, 1) = Arr(S(m), 5)
        End If
            KQ(j, 2) = KQ(j, 2) + Arr(S(m), 5)
        Next m
        j = n
    ElseIf UBound(S) = 0 Then
        If Arr(S(0), 2) <> Empty Or Arr(S(0), 3) <> Empty Or Arr(S(0), 4) <> Empty Then
            n = j + 1
            KQ(n, 1) = "  -" & Arr(S(0), 2) & "x" & Arr(S(0), 3) & "x" & Arr(S(0), 4) & "  =" & Arr(S(0), 5)
            KQ(j, 2) = KQ(j, 2) + Arr(S(0), 5)
        Else
            KQ(j, 2) = Arr(S(0), 5):            n = j
        End If
        j = n
    End If
  
Next
If j Then
    Ws.Range("K4").Resize(10000, 2).ClearContents
    Ws.Range("K4").Resize(j, 2) = KQ
End If
Set Dic = Nothing
End Sub
 
Upvote 0
Web KT

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

Back
Top Bottom