Nhờ mọi người giúp em VBA gộp và cộng kết hợp các dòng giống nhau (có chứa shape)

Liên hệ QC

donghavmu

Thành viên mới
Tham gia
22/5/20
Bài viết
13
Được thích
0
Mong mọi người chỉ giúp đỡ em với ạ (file đính kèm bên dưới). Em muốn dùng VBA để xử lý: Các thanh thép có cùng SỐ HIỆU đang bị xuất hiện nhiều lần (như trong bảng bên thì thanh số hiệu 5 xuất hiện 3 lần). Em muốn những dòng này gộp làm 1 dòng duy nhất. Và giá trị MÀU XANH LÁ giữ nguyên không đổi. Còn giá trị MÀU ĐỎ thì gộp tổng vào với nhau. Kết quả thu về giống ở Sheet bên cạnh là em đã xử lý thủ công ^^. Mong mọi người chỉ giúp hoặc cho em xin code VBA tương tự với ạ. Em cảm ơn. (Lưu ý: Nếu cần có thể copy paste value để loại bỏ công thức đi rồi dùng VBA cũng được ạ). Capture.JPG
 

File đính kèm

  • Filekiemtra.xls
    346 KB · Đọc: 19
Lần chỉnh sửa cuối:
Giải pháp
Tôi đã xem. Hình như bạn muốn nói đến việc các hình không được xóa và chúng nằm đè lên nhau?

Vấn đề không liên quan tới code. Bạn chọn vd. hình đầu tiên rồi phải chuột rồi chọn Size And Properties thì bạn thấy Move but don't size with cells được chọn.

move.jpg

Bạn phải chọn lại thành Move and size with cells. Ở tập tin trước tất cả các shape đều có Move and size with cells

Bạn phải chuyển thành Move and size with cells cho tất cả các hình. Có thể làm 1 lần bằng cách chọn tất cả các hình rồi mới thay thành Move and size with cells.

Nếu không muốn nhọc công thì trong code SAU DÒNG
Mã:
Dim lastRow As Long, r As...
Và giá trị MÀU XANH LÁ giữ nguyên không đổi. Còn giá trị MÀU ĐỎ thì gộp tổng vào với nhau.

Không chính xác. Ngoài các cột ẩn tôi không kiểm tra thì cột S không được cộng dồn.

Thêm một module và dán vào nó code sau. Code được chú thích từng dòng.
Mã:
Option Explicit

Sub thongke()
Dim lastRow As Long, r As Long, c As Long, chiso As Long, count As Long, calc As Long, dulieu(), kq(), rng As Range, sh As Worksheet, dic As Object
'    rng la cac dong co SO HIEU bi lap lai. Truoc het tat ca cac dong cua ThongKe duoc copy sang "ThongKe da xu ly". Tiep theo cac dong thuoc rng se bi DELETE
'    Muc dich chi la lay cac hinh thanh thep. Cung co the lam cach khac copy sao cho chieu cao va chieu rong cac dong va cot vua voi kich thuoc cac hinh,
'    nhung co le cach thuc hien se phuc tap hon - tuy nhien toi khong thu, khong nghi them.
    Set sh = ThisWorkbook.Worksheets("ThongKe da xu ly")
    sh.Range("A1:A5000").EntireRow.Delete Shift:=xlUp    ' xoa ket qua cu - 5000 dong
    With ThisWorkbook.Worksheets("ThongKe")
        lastRow = .Cells(Rows.count, "A").End(xlUp).Row ' dong cuoi cung co du lieu trong cot A
        If lastRow < 10 Then Exit Sub   ' neu khong co du lieu thi don do choi
        calc = Application.Calculation
        Application.Calculation = xlCalculationManual
        dulieu = .Range("A10:X" & lastRow).Value    ' lay du lieu vao mang dulieu
        .Cells.Copy
    End With
    With sh ' dan noi dung ThongKe sang "ThongKe da xu ly"
        .Select
        .Range("A1").Select
        .Paste
    End With
    Application.Calculation = calc
   
    Set dic = CreateObject("Scripting.Dictionary")
    ReDim kq(1 To UBound(dulieu, 1), 1 To UBound(dulieu, 2))    ' mang kq cung lam la co so dong bang so dong cua dulieu
    For r = 1 To UBound(dulieu, 1)  ' duyet tung dong cua mang dulieu
        If dic.exists(dulieu(r, 3)) Then    ' da co SO HIEU trong tu dien
            If rng Is Nothing Then
                Set rng = sh.Rows(r + 9)
            Else
                Set rng = Union(rng, sh.Rows(r + 9))    ' tong cac dong bi lap lai SO HIEU
            End If
            chiso = dic.Item(dulieu(r, 3))  ' SH da co trong tu dien, doc ra chi so dong cua SH trong mang kq
            For c = 14 To UBound(kq, 2)
                If c <> 19 Then kq(chiso, c) = kq(chiso, c) + dulieu(r, c) ' cong don dong hien hanh cua mang dulieu vao dong chiso cua mang kq - khong cong cot S
            Next c
        Else    ' chua co SO HIEU trong tu dien, tuc dong co SH moi
            count = count + 1   ' tang so luong SO HIEU duy nhat
            For c = 1 To UBound(kq, 2)   ' sao chep dong hien hanh cua mang dulieu sang dong count cua mang kq
                kq(count, c) = dulieu(r, c)
            Next c
            dic.Add dulieu(r, 3), count ' them SH vao tu dien vi tu cach la KEY va chi so dong cua no trong mang kq voi tu cach la ITEM
        End If
    Next r
    If Not rng Is Nothing Then rng.Delete
    sh.Range("A10").Resize(count, UBound(kq, 2)).Value = kq
End Sub
 
Lần chỉnh sửa cuối:
Upvote 1
Không chính xác. Ngoài các cột ẩn tôi không kiểm tra thì cột S không được cộng dồn.

Thêm một module và dán vào nó code sau. Code được chú thích từng dòng.
Mã:
Option Explicit

Sub thongke()
Dim lastRow As Long, r As Long, c As Long, chiso As Long, count As Long, calc As Long, dulieu(), kq(), rng As Range, sh As Worksheet, dic As Object
'    rng la cac dong co SO HIEU bi lap lai. Truoc het tat ca cac dong cua ThongKe duoc copy sang "ThongKe da xu ly". Tiep theo cac dong thuoc rng se bi DELETE
'    Muc dich chi la lay cac hinh thanh thep. Cung co the lam cach khac copy sao cho chieu cao va chieu rong cac dong va cot vua voi kich thuoc cac hinh,
'    nhung co le cach thuc hien se phuc tap hon - tuy nhien toi khong thu, khong nghi them.
    Set sh = ThisWorkbook.Worksheets("ThongKe da xu ly")
    sh.Range("A1:A5000").EntireRow.Delete Shift:=xlUp    ' xoa ket qua cu - 5000 dong
    With ThisWorkbook.Worksheets("ThongKe")
        lastRow = .Cells(Rows.count, "A").End(xlUp).Row ' dong cuoi cung co du lieu trong cot A
        If lastRow < 10 Then Exit Sub   ' neu khong co du lieu thi don do choi
        calc = Application.Calculation
        Application.Calculation = xlCalculationManual
        dulieu = .Range("A10:X" & lastRow).Value    ' lay du lieu vao mang dulieu
        .Cells.Copy
    End With
    With sh ' dan noi dung ThongKe sang "ThongKe da xu ly"
        .Select
        .Range("A1").Select
        .Paste
    End With
    Application.Calculation = calc
  
    Set dic = CreateObject("Scripting.Dictionary")
    ReDim kq(1 To UBound(dulieu, 1), 1 To UBound(dulieu, 2))    ' mang kq cung lam la co so dong bang so dong cua dulieu
    For r = 1 To UBound(dulieu, 1)  ' duyet tung dong cua mang dulieu
        If dic.exists(dulieu(r, 3)) Then    ' da co SO HIEU trong tu dien
            If rng Is Nothing Then
                Set rng = sh.Rows(r + 9)
            Else
                Set rng = Union(rng, sh.Rows(r + 9))    ' tong cac dong bi lap lai SO HIEU
            End If
            chiso = dic.Item(dulieu(r, 3))  ' SH da co trong tu dien, doc ra chi so dong cua SH trong mang kq
            For c = 14 To UBound(kq, 2)
                If c <> 19 Then kq(chiso, c) = kq(chiso, c) + dulieu(r, c) ' cong don dong hien hanh cua mang dulieu vao dong chiso cua mang kq - khong cong cot S
            Next c
        Else    ' chua co SO HIEU trong tu dien, tuc dong co SH moi
            count = count + 1   ' tang so luong SO HIEU duy nhat
            For c = 1 To UBound(kq, 2)   ' sao chep dong hien hanh cua mang dulieu sang dong count cua mang kq
                kq(count, c) = dulieu(r, c)
            Next c
            dic.Add dulieu(r, 3), count ' them SH vao tu dien vi tu cach la KEY va chi so dong cua no trong mang kq voi tu cach la ITEM
        End If
    Next r
    If Not rng Is Nothing Then rng.Delete
    sh.Range("A10").Resize(count, UBound(kq, 2)).Value = kq
End Sub
[/coddồn
[/QUOTE]
dạ vâng. em cảm ơn anh. chính xác là cột S không cộng dồn ạ
Bài đã được tự động gộp:

dạ vâng, em cảm ơn anh. chính xác là cột S không cộng như anh nói ạ ^^. em nhầm chút ạ
 
Lần chỉnh sửa cuối:
Upvote 0
trước hết, em rất cảm ơn anh vì đã giúp e ạ. anh có thể cho em xin SĐT để em hậu tạ được không ạ. file trên em có thêm 1 chút cần anh chỉ dạy ạ
Bài đã được tự động gộp:

Không chính xác. Ngoài các cột ẩn tôi không kiểm tra thì cột S không được cộng dồn.

Thêm một module và dán vào nó code sau. Code được chú thích từng dòng.
Mã:
Option Explicit

Sub thongke()
Dim lastRow As Long, r As Long, c As Long, chiso As Long, count As Long, calc As Long, dulieu(), kq(), rng As Range, sh As Worksheet, dic As Object
'    rng la cac dong co SO HIEU bi lap lai. Truoc het tat ca cac dong cua ThongKe duoc copy sang "ThongKe da xu ly". Tiep theo cac dong thuoc rng se bi DELETE
'    Muc dich chi la lay cac hinh thanh thep. Cung co the lam cach khac copy sao cho chieu cao va chieu rong cac dong va cot vua voi kich thuoc cac hinh,
'    nhung co le cach thuc hien se phuc tap hon - tuy nhien toi khong thu, khong nghi them.
    Set sh = ThisWorkbook.Worksheets("ThongKe da xu ly")
    sh.Range("A1:A5000").EntireRow.Delete Shift:=xlUp    ' xoa ket qua cu - 5000 dong
    With ThisWorkbook.Worksheets("ThongKe")
        lastRow = .Cells(Rows.count, "A").End(xlUp).Row ' dong cuoi cung co du lieu trong cot A
        If lastRow < 10 Then Exit Sub   ' neu khong co du lieu thi don do choi
        calc = Application.Calculation
        Application.Calculation = xlCalculationManual
        dulieu = .Range("A10:X" & lastRow).Value    ' lay du lieu vao mang dulieu
        .Cells.Copy
    End With
    With sh ' dan noi dung ThongKe sang "ThongKe da xu ly"
        .Select
        .Range("A1").Select
        .Paste
    End With
    Application.Calculation = calc
  
    Set dic = CreateObject("Scripting.Dictionary")
    ReDim kq(1 To UBound(dulieu, 1), 1 To UBound(dulieu, 2))    ' mang kq cung lam la co so dong bang so dong cua dulieu
    For r = 1 To UBound(dulieu, 1)  ' duyet tung dong cua mang dulieu
        If dic.exists(dulieu(r, 3)) Then    ' da co SO HIEU trong tu dien
            If rng Is Nothing Then
                Set rng = sh.Rows(r + 9)
            Else
                Set rng = Union(rng, sh.Rows(r + 9))    ' tong cac dong bi lap lai SO HIEU
            End If
            chiso = dic.Item(dulieu(r, 3))  ' SH da co trong tu dien, doc ra chi so dong cua SH trong mang kq
            For c = 14 To UBound(kq, 2)
                If c <> 19 Then kq(chiso, c) = kq(chiso, c) + dulieu(r, c) ' cong don dong hien hanh cua mang dulieu vao dong chiso cua mang kq - khong cong cot S
            Next c
        Else    ' chua co SO HIEU trong tu dien, tuc dong co SH moi
            count = count + 1   ' tang so luong SO HIEU duy nhat
            For c = 1 To UBound(kq, 2)   ' sao chep dong hien hanh cua mang dulieu sang dong count cua mang kq
                kq(count, c) = dulieu(r, c)
            Next c
            dic.Add dulieu(r, 3), count ' them SH vao tu dien vi tu cach la KEY va chi so dong cua no trong mang kq voi tu cach la ITEM
        End If
    Next r
    If Not rng Is Nothing Then rng.Delete
    sh.Range("A10").Resize(count, UBound(kq, 2)).Value = kq
End Sub
trước hết, em rất cảm ơn anh vì đã giúp e ạ. anh có thể cho em xin SĐT để em hậu tạ được không ạ. file trên em có thêm 1 chút cần anh chỉ dạy ạ
 
Upvote 0
Có gì bạn cứ hỏi ở đây. Tôi không liên lạc riêng với ai cả.
Dạ vâng. Em cảm ơn anh vì VBA trước ạ. Em tải về và dùng thì có một số chỗ sau cần chỉnh như này ạ:
Những thanh cùng số hiệu và đồng thời phải cùng THUỘC 1 CẤU KIỆN (cột A) gộp làm 1 dòng duy nhất (kết quả sau chạy code, các dòng này không bị xen kẽ vào nhau) Kết quả em miêu tả giống bảng trong Sheet "ThongKe da xu ly". (Chỗ này do hôm qua em miêu tả chưa chuẩn ạ). Sheet "ThongKe da xu ly" là em ví dụ sau khi xử lý sẽ được như vậy ạ. Nếu code trong quá trình chạy ra kết quả luôn trên Sheet "ThongKe" và không liên quan gì đến Sheet "ThongKe da xu ly" thì tốt quá ạ ^^ . Trước khi code chạy em muốn chọn vùng thực hiện trước ạ. Còn về giá trị giữ nguyên và cộng tổng anh làm đúng rồi ạ. Cảm ơn anh và chúc anh sức khỏe ạ!
 

File đính kèm

  • File vi du lan 2.xls
    371 KB · Đọc: 12
Lần chỉnh sửa cuối:
Upvote 0
Nếu code trong quá trình chạy ra kết quả luôn trên Sheet "ThongKe" và không liên quan gì đến Sheet "ThongKe da xu ly" thì tốt quá ạ ^^
Cái này sẽ dẫn đến không còn tý công thức nào . tất cả các kết quả trả về là giá trị đó
 
Upvote 0
Trước khi code chạy em muốn chọn vùng thực hiện trước ạ. Còn về giá trị giữ nguyên và cộng tổng anh làm đúng rồi ạ. Cảm ơn anh và chúc anh sức khỏe ạ!
Tôi mới dậy do hôm qua thức khuya quá (chỗ tôi múi giờ sau Việt Nam 6 tiếng) nên giờ mới trả lời.

Bạn nên nói rõ. Bạn sẽ tự tay chọn vùng rồi mới nhấn nút chạy code hay bạn muốn code mở cửa sổ ra cho bạn chọn vùng? Hai cái này hoàn toàn khác nhau. Và nữa, tôi phải biết bạn sẽ có kiểu chọn như nào để phục vụ lựa chọn của bạn. Hiện dữ liệu bắt đầu từ dòng 10 và từ cột A tới X. Giả sử dữ liệu tới dòng 100. Bạn sẽ luôn chọn cột A tới X chỉ khác là có thể chọn từ dòng 17 tới hết tới 100, hoặc chỉ chọn từ 17 tới 29?
Nếu code trong quá trình chạy ra kết quả luôn trên Sheet "ThongKe" và không liên quan gì đến Sheet "ThongKe da xu ly" thì tốt quá ạ ^^ .
Nếu thế thì code ngắn hơn.

Code sẽ ghi kết quả ngay trên sheet ThongKe. Nếu cần bản sao thì bạn tự copy trước khi chạy code.

Tôi không hiểu sao bạn lại có trong sheet "ThongKe da xu ly" X14 = U14 = 20,10. Chạy code sẽ có ThongKe!X14 = U14 = 58,20
Mã:
Option Explicit

Sub thongke()
Dim lastRow As Long, r As Long, c As Long, chiso As Long, count As Long, dieukien As String, dulieu(), kq(), rng As Range, dic As Object
'    rng la cac dong co CAU KIEN + SO HIEU bi lap lai. Cac dong thuoc rng se bi DELETE
    With ThisWorkbook.Worksheets("ThongKe")
        lastRow = .Cells(Rows.count, "A").End(xlUp).Row ' dong cuoi cung co du lieu trong cot A
        If lastRow < 10 Then Exit Sub   ' neu khong co du lieu thi don do choi
        dulieu = .Range("A10:X" & lastRow).Value    ' lay du lieu vao mang dulieu
    End With
   
    Set dic = CreateObject("Scripting.Dictionary")
    ReDim kq(1 To UBound(dulieu, 1), 1 To UBound(dulieu, 2))    ' mang kq cung lam la co so dong bang so dong cua dulieu
    For r = 1 To UBound(dulieu, 1)  ' duyet tung dong cua mang dulieu
        dieukien = dulieu(r, 1) & "#" & dulieu(r, 3)    ' CAU KIEN#SO HIEU
        If dic.exists(dieukien) Then   ' da co CAU KIEN + SO HIEU trong tu dien
            If rng Is Nothing Then
                Set rng = ThisWorkbook.Worksheets("ThongKe").Rows(r + 9)
            Else
                Set rng = Union(rng, ThisWorkbook.Worksheets("ThongKe").Rows(r + 9))    ' tong cac dong bi lap lai CAU KIEN + SO HIEU
            End If
            chiso = dic.Item(dieukien)  ' CAU KIEN + SH da co trong tu dien, doc ra chi so dong cua SH trong mang kq
            For c = 14 To UBound(kq, 2)
                If c <> 19 Then kq(chiso, c) = kq(chiso, c) + dulieu(r, c) ' cong don dong hien hanh cua mang dulieu vao dong chiso cua mang kq - khong cong cot S
            Next c
        Else    ' chua co CAU KIEN + SO HIEU trong tu dien, tuc dong co SH moi
            count = count + 1   ' tang so luong SO HIEU duy nhat
            For c = 1 To UBound(kq, 2)   ' sao chep dong hien hanh cua mang dulieu sang dong count cua mang kq
                kq(count, c) = dulieu(r, c)
            Next c
            dic.Add dieukien, count ' them CAU KIEN#SH vao tu dien vi tu cach la KEY va chi so dong cua no trong mang kq voi tu cach la ITEM
        End If
    Next r
    If Not rng Is Nothing Then rng.Delete
    ThisWorkbook.Worksheets("ThongKe").Range("A10").Resize(count, UBound(kq, 2)).Value = kq
End Sub
 
Upvote 0
dạ em cảm ơn anh nhiều. em muốn được chọn trước và chạy code sau ạ, và có thể chọn từng vùng nhất định (ví dụ em có dữ liệu cần xử lý là từ vùng A10:X27, nhưng em chỉ xử lý cho cấu kiện D2-1 là từ A10:X18 thì em chọn vùng A10:X18 rồi ấn chạy code. ^^ còn về chỗ này là do em xử lý thủ công nên nhầm chút ạ. cảm ơn anh nhiều lắm ạ ^^
Tôi không hiểu sao bạn lại có trong sheet "ThongKe da xu ly" X14 = U14 = 20,10. Chạy code sẽ có ThongKe!X14 = U14 = 58,20
 
Upvote 0
Giả thiết:
1. Code chỉ làm việc khi vùng chọn có ít nhất 1 ô chung với vùng dữ liệu hiện hành - vùng từ dòng 10, cột từ A tới X.
2. Nếu vùng chọn là tổ hợp nhiều vùng đơn lẻ thì code lấy vùng đơn lẻ đầu tien - Selection.Areas(1)
3. Nếu vùng chọn không có đủ cột từ A tới X hoặc nhiều cột hơn thì code tự mở rộng hoặc thu hẹp vùng chọn về A:X
4. Nếu vùng chọn có cả những dòng trống ngoài vùng dữ liệu hiện hành thì code bỏ qua những dòng đó.
Từ giả thiết ta thấy là khi chọn vùng chỉ cần chọn chính xác phạm vi dòng, code tự chỉnh sửa phạm vi cột về A:X.

Mã:
Option Explicit

Sub thongke()
Dim lastRow As Long, r As Long, c As Long, chiso As Long, count As Long, startRow As Long, dieukien As String, dulieu(), kq(), rng As Range, dic As Object
'    rng la cac dong co CAU KIEN + SO HIEU bi lap lai. Cac dong thuoc rng se bi DELETE
    With ThisWorkbook.Worksheets("ThongKe")
        lastRow = .Cells(Rows.count, "A").End(xlUp).Row ' dong cuoi cung co du lieu trong cot A
        If lastRow < 10 Then Exit Sub   ' neu khong co du lieu thi don do choi
        If TypeName(Selection) <> "Range" Then Exit Sub
        Set rng = Intersect(Selection.Areas(1), .Range("A10:X" & lastRow))
        If rng Is Nothing Then Exit Sub
        dulieu = rng.Offset(0, 1 - rng.Column).Resize(, 24).Value    ' lay du lieu vao mang dulieu
        startRow = rng.Row
        Set rng = Nothing
    End With
    
    Set dic = CreateObject("Scripting.Dictionary")
    ReDim kq(1 To UBound(dulieu, 1), 1 To UBound(dulieu, 2))    ' mang kq cung lam la co so dong bang so dong cua dulieu
    For r = 1 To UBound(dulieu, 1)  ' duyet tung dong cua mang dulieu
        dieukien = dulieu(r, 1) & "#" & dulieu(r, 3)    ' CAU KIEN#SO HIEU
        If dic.exists(dieukien) Then   ' da co CAU KIEN + SO HIEU trong tu dien
            If rng Is Nothing Then
                Set rng = ThisWorkbook.Worksheets("ThongKe").Rows(r + startRow - 1)
            Else
                Set rng = Union(rng, ThisWorkbook.Worksheets("ThongKe").Rows(r + startRow - 1))    ' tong cac dong bi lap lai CAU KIEN + SO HIEU
            End If
            chiso = dic.Item(dieukien)  ' CAU KIEN + SH da co trong tu dien, doc ra chi so dong cua SH trong mang kq
            For c = 14 To UBound(kq, 2)
                If c <> 19 Then kq(chiso, c) = kq(chiso, c) + dulieu(r, c) ' cong don dong hien hanh cua mang dulieu vao dong chiso cua mang kq - khong cong cot S
            Next c
        Else    ' chua co CAU KIEN + SO HIEU trong tu dien, tuc dong co SH moi
            count = count + 1   ' tang so luong SO HIEU duy nhat
            For c = 1 To UBound(kq, 2)   ' sao chep dong hien hanh cua mang dulieu sang dong count cua mang kq
                kq(count, c) = dulieu(r, c)
            Next c
            dic.Add dieukien, count ' them CAU KIEN#SH vao tu dien vi tu cach la KEY va chi so dong cua no trong mang kq voi tu cach la ITEM
        End If
    Next r
    If Not rng Is Nothing Then rng.Delete
    ThisWorkbook.Worksheets("ThongKe").Cells(startRow, "A").Resize(count, UBound(kq, 2)).Value = kq
End Sub
 
Upvote 0
Giả thiết:
1. Code chỉ làm việc khi vùng chọn có ít nhất 1 ô chung với vùng dữ liệu hiện hành - vùng từ dòng 10, cột từ A tới X.
2. Nếu vùng chọn là tổ hợp nhiều vùng đơn lẻ thì code lấy vùng đơn lẻ đầu tien - Selection.Areas(1)
3. Nếu vùng chọn không có đủ cột từ A tới X hoặc nhiều cột hơn thì code tự mở rộng hoặc thu hẹp vùng chọn về A:X
4. Nếu vùng chọn có cả những dòng trống ngoài vùng dữ liệu hiện hành thì code bỏ qua những dòng đó.
Từ giả thiết ta thấy là khi chọn vùng chỉ cần chọn chính xác phạm vi dòng, code tự chỉnh sửa phạm vi cột về A:X.

Mã:
Option Explicit

Sub thongke()
Dim lastRow As Long, r As Long, c As Long, chiso As Long, count As Long, startRow As Long, dieukien As String, dulieu(), kq(), rng As Range, dic As Object
'    rng la cac dong co CAU KIEN + SO HIEU bi lap lai. Cac dong thuoc rng se bi DELETE
    With ThisWorkbook.Worksheets("ThongKe")
        lastRow = .Cells(Rows.count, "A").End(xlUp).Row ' dong cuoi cung co du lieu trong cot A
        If lastRow < 10 Then Exit Sub   ' neu khong co du lieu thi don do choi
        If TypeName(Selection) <> "Range" Then Exit Sub
        Set rng = Intersect(Selection.Areas(1), .Range("A10:X" & lastRow))
        If rng Is Nothing Then Exit Sub
        dulieu = rng.Offset(0, 1 - rng.Column).Resize(, 24).Value    ' lay du lieu vao mang dulieu
        startRow = rng.Row
        Set rng = Nothing
    End With
   
    Set dic = CreateObject("Scripting.Dictionary")
    ReDim kq(1 To UBound(dulieu, 1), 1 To UBound(dulieu, 2))    ' mang kq cung lam la co so dong bang so dong cua dulieu
    For r = 1 To UBound(dulieu, 1)  ' duyet tung dong cua mang dulieu
        dieukien = dulieu(r, 1) & "#" & dulieu(r, 3)    ' CAU KIEN#SO HIEU
        If dic.exists(dieukien) Then   ' da co CAU KIEN + SO HIEU trong tu dien
            If rng Is Nothing Then
                Set rng = ThisWorkbook.Worksheets("ThongKe").Rows(r + startRow - 1)
            Else
                Set rng = Union(rng, ThisWorkbook.Worksheets("ThongKe").Rows(r + startRow - 1))    ' tong cac dong bi lap lai CAU KIEN + SO HIEU
            End If
            chiso = dic.Item(dieukien)  ' CAU KIEN + SH da co trong tu dien, doc ra chi so dong cua SH trong mang kq
            For c = 14 To UBound(kq, 2)
                If c <> 19 Then kq(chiso, c) = kq(chiso, c) + dulieu(r, c) ' cong don dong hien hanh cua mang dulieu vao dong chiso cua mang kq - khong cong cot S
            Next c
        Else    ' chua co CAU KIEN + SO HIEU trong tu dien, tuc dong co SH moi
            count = count + 1   ' tang so luong SO HIEU duy nhat
            For c = 1 To UBound(kq, 2)   ' sao chep dong hien hanh cua mang dulieu sang dong count cua mang kq
                kq(count, c) = dulieu(r, c)
            Next c
            dic.Add dieukien, count ' them CAU KIEN#SH vao tu dien vi tu cach la KEY va chi so dong cua no trong mang kq voi tu cach la ITEM
        End If
    Next r
    If Not rng Is Nothing Then rng.Delete
    ThisWorkbook.Worksheets("ThongKe").Cells(startRow, "A").Resize(count, UBound(kq, 2)).Value = kq
End Sub
dạ, em cảm ơn anh nhiều ạ <3
 
Upvote 0
Giả thiết:
1. Code chỉ làm việc khi vùng chọn có ít nhất 1 ô chung với vùng dữ liệu hiện hành - vùng từ dòng 10, cột từ A tới X.
2. Nếu vùng chọn là tổ hợp nhiều vùng đơn lẻ thì code lấy vùng đơn lẻ đầu tien - Selection.Areas(1)
3. Nếu vùng chọn không có đủ cột từ A tới X hoặc nhiều cột hơn thì code tự mở rộng hoặc thu hẹp vùng chọn về A:X
4. Nếu vùng chọn có cả những dòng trống ngoài vùng dữ liệu hiện hành thì code bỏ qua những dòng đó.
Từ giả thiết ta thấy là khi chọn vùng chỉ cần chọn chính xác phạm vi dòng, code tự chỉnh sửa phạm vi cột về A:X.

Mã:
Option Explicit

Sub thongke()
Dim lastRow As Long, r As Long, c As Long, chiso As Long, count As Long, startRow As Long, dieukien As String, dulieu(), kq(), rng As Range, dic As Object
'    rng la cac dong co CAU KIEN + SO HIEU bi lap lai. Cac dong thuoc rng se bi DELETE
    With ThisWorkbook.Worksheets("ThongKe")
        lastRow = .Cells(Rows.count, "A").End(xlUp).Row ' dong cuoi cung co du lieu trong cot A
        If lastRow < 10 Then Exit Sub   ' neu khong co du lieu thi don do choi
        If TypeName(Selection) <> "Range" Then Exit Sub
        Set rng = Intersect(Selection.Areas(1), .Range("A10:X" & lastRow))
        If rng Is Nothing Then Exit Sub
        dulieu = rng.Offset(0, 1 - rng.Column).Resize(, 24).Value    ' lay du lieu vao mang dulieu
        startRow = rng.Row
        Set rng = Nothing
    End With
   
    Set dic = CreateObject("Scripting.Dictionary")
    ReDim kq(1 To UBound(dulieu, 1), 1 To UBound(dulieu, 2))    ' mang kq cung lam la co so dong bang so dong cua dulieu
    For r = 1 To UBound(dulieu, 1)  ' duyet tung dong cua mang dulieu
        dieukien = dulieu(r, 1) & "#" & dulieu(r, 3)    ' CAU KIEN#SO HIEU
        If dic.exists(dieukien) Then   ' da co CAU KIEN + SO HIEU trong tu dien
            If rng Is Nothing Then
                Set rng = ThisWorkbook.Worksheets("ThongKe").Rows(r + startRow - 1)
            Else
                Set rng = Union(rng, ThisWorkbook.Worksheets("ThongKe").Rows(r + startRow - 1))    ' tong cac dong bi lap lai CAU KIEN + SO HIEU
            End If
            chiso = dic.Item(dieukien)  ' CAU KIEN + SH da co trong tu dien, doc ra chi so dong cua SH trong mang kq
            For c = 14 To UBound(kq, 2)
                If c <> 19 Then kq(chiso, c) = kq(chiso, c) + dulieu(r, c) ' cong don dong hien hanh cua mang dulieu vao dong chiso cua mang kq - khong cong cot S
            Next c
        Else    ' chua co CAU KIEN + SO HIEU trong tu dien, tuc dong co SH moi
            count = count + 1   ' tang so luong SO HIEU duy nhat
            For c = 1 To UBound(kq, 2)   ' sao chep dong hien hanh cua mang dulieu sang dong count cua mang kq
                kq(count, c) = dulieu(r, c)
            Next c
            dic.Add dieukien, count ' them CAU KIEN#SH vao tu dien vi tu cach la KEY va chi so dong cua no trong mang kq voi tu cach la ITEM
        End If
    Next r
    If Not rng Is Nothing Then rng.Delete
    ThisWorkbook.Worksheets("ThongKe").Cells(startRow, "A").Resize(count, UBound(kq, 2)).Value = kq
End Sub
Em chào anh. Code VBA lần trước anh giúp em hoạt động rất tốt ạ. Em có thay đổi một chút anh giúp em với ạ. Do lúc trước em vẽ hình dạng thanh thép bằng công cụ Shape trong Excel, khi em nhập bảng thống kê từ Excel vào Autocad thì những Shape này hay bị lỗi. Bây giờ em sử dụng hình ảnh để làm hình dạng thanh thép, sẽ không gặp phải những lỗi đó nữa. Nhưng code của anh giúp em lần trước (code gộp những thanh thép cùng hình dạng, số hiệu trong cùng cấu kiện) lại không giúp gộp những hình ảnh này (như file ví dụ em đính kèm). Vậy mong anh có thể chỉnh lại code giúp em với ạ. Code em đã để sẵn trong file ở Modul 1 ạ. Trân trọng cảm ơn anh ạ.
 

File đính kèm

  • File vi du lan 3.xls
    304.5 KB · Đọc: 11
Upvote 0
Tôi đã xem. Hình như bạn muốn nói đến việc các hình không được xóa và chúng nằm đè lên nhau?

Vấn đề không liên quan tới code. Bạn chọn vd. hình đầu tiên rồi phải chuột rồi chọn Size And Properties thì bạn thấy Move but don't size with cells được chọn.

move.jpg

Bạn phải chọn lại thành Move and size with cells. Ở tập tin trước tất cả các shape đều có Move and size with cells

Bạn phải chuyển thành Move and size with cells cho tất cả các hình. Có thể làm 1 lần bằng cách chọn tất cả các hình rồi mới thay thành Move and size with cells.

Nếu không muốn nhọc công thì trong code SAU DÒNG
Mã:
Dim lastRow As Long, r As Long, c As Long, chiso As Long, count As Long, dieukien As String, dulieu(), kq(), rng As Range, dic As Object

thì thêm

Mã:
Dim shp As Shape
    For Each shp In ThisWorkbook.Worksheets("ThongKe").Shapes
        shp.Placement = xlMoveAndSize
    Next shp
 
Upvote 0
Giải pháp
Tôi đã xem. Hình như bạn muốn nói đến việc các hình không được xóa và chúng nằm đè lên nhau?

Vấn đề không liên quan tới code. Bạn chọn vd. hình đầu tiên rồi phải chuột rồi chọn Size And Properties thì bạn thấy Move but don't size with cells được chọn.

View attachment 273923

Bạn phải chọn lại thành Move and size with cells. Ở tập tin trước tất cả các shape đều có Move and size with cells

Bạn phải chuyển thành Move and size with cells cho tất cả các hình. Có thể làm 1 lần bằng cách chọn tất cả các hình rồi mới thay thành Move and size with cells.

Nếu không muốn nhọc công thì trong code SAU DÒNG
Mã:
Dim lastRow As Long, r As Long, c As Long, chiso As Long, count As Long, dieukien As String, dulieu(), kq(), rng As Range, dic As Object

thì thêm

Mã:
Dim shp As Shape
    For Each shp In ThisWorkbook.Worksheets("ThongKe").Shapes
        shp.Placement = xlMoveAndSize
    Next shp
dạ em làm được rồi ạ, em cảm ơn anh ạ
 
Upvote 0
Web KT

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

Back
Top Bottom