Nhờ viết code tổng hợp dữ liệu từ sheet này sang sheet khác theo điều kiện

Liên hệ QC

tranquynh.81

Thành viên mới
Tham gia
21/1/21
Bài viết
11
Được thích
3
kính chào các anh các chị!
em có file trong file có 3 sheet , mình cần copy 3 sheet vào 1 sheet tổng hợp , điều kiện nếu giống cột số thứ tự (stt trong file ) thì copy các dòng từ sst đó . ví dụ stt 151 thì copy các dòng từ stt 151 đến truoéc dòng 152 . trong file em có sheet kết quả .
mong các anh chị giúp đỡ.
cảm ơn a/c nhiều
 

File đính kèm

  • DC+md+kd 15.8.21 (HOI VBA).xlsx
    318.4 KB · Đọc: 28
kính chào các anh các chị!
em có file trong file có 3 sheet , mình cần copy 3 sheet vào 1 sheet tổng hợp , điều kiện nếu giống cột số thứ tự (stt trong file ) thì copy các dòng từ sst đó . ví dụ stt 151 thì copy các dòng từ stt 151 đến truoéc dòng 152 . trong file em có sheet kết quả .
mong các anh chị giúp đỡ.
cảm ơn a/c nhiều
trong khi chờ đợi người khác giúp thử dùng code này xem sao.
Lưu ý Nhập các số thứ tự cần tổng hợp vào Cột P của Sh KET QUA.
Nhấn nút TONG HOP và xem, kiểm tra kết quả.
 

File đính kèm

  • DC+md+kd 15.8.21 (HOI VBA)-TranQuynh.xlsm
    333.8 KB · Đọc: 19
Upvote 0
trong khi chờ đợi người khác giúp thử dùng code này xem sao.
Lưu ý Nhập các số thứ tự cần tổng hợp vào Cột P của Sh KET QUA.
Nhấn nút TONG HOP và xem, kiểm tra kết quả.
Cảm ơn bạn nhiều đã giúp mình . bạn giúp mình tí thêm tí nữa nha bạn . mình muốn bỏ có dòng trùng nhau trong sheet "KẾT QUẢ"
.ví dụ có 3 dòng 151 trùng nhau thì xóa 2 dòng chỉ giữ lại 1 dòng.
cảm ơn bạn rất nhiều!
 

File đính kèm

  • DC+md+kd 15.8.21 (HOI VBA)-TranQuynh1.xlsm
    331.4 KB · Đọc: 21
Upvote 0
Cảm ơn bạn nhiều đã giúp mình . bạn giúp mình tí thêm tí nữa nha bạn . mình muốn bỏ có dòng trùng nhau trong sheet "KẾT QUẢ"
.ví dụ có 3 dòng 151 trùng nhau thì xóa 2 dòng chỉ giữ lại 1 dòng.
cảm ơn bạn rất nhiều!
Bạn thay code trong modul 1 bằng code này:
Mã:
Sub TONGHOP()
Dim wsh As Worksheet
Dim Sh As Worksheet
Dim Lr&, d&, k&, J&, I&, x&
'On Error Resume Next
Application.ScreenUpdating = False
Set Sh = Sheets("KET QUA")
Sh.Range("A2:L10000").ClearContents
J = Sh.Cells(Rows.Count, 16).End(xlUp).Row
For I = 2 To J
x = 1
    For Each wsh In ThisWorkbook.Worksheets
        If wsh.Name <> "KET QUA" Then
            If x = 1 Then
                d = Application.WorksheetFunction.Match(Sh.Cells(I, 16), wsh.Range("A1:A10000"), 0)
            Else
                d = Application.WorksheetFunction.Match(Sh.Cells(I, 16), wsh.Range("A1:A10000"), 0) + 1
            End If
                k = wsh.Cells(d, 1).End(xlDown).Row - 1
                Lr = Sh.Cells(Rows.Count, 9).End(3).Row
                wsh.Range("A" & d, "L" & k).Copy Sh.Cells(Lr + 1, "A")
                x = x + 1
        End If
Next wsh
Next I
    Sh.Cells(1).Select
    MsgBox " Xong"
Application.ScreenUpdating = True
End Sub
 
Upvote 0
Bạn thay code trong modul 1 bằng code này:
Mã:
Sub TONGHOP()
Dim wsh As Worksheet
Dim Sh As Worksheet
Dim Lr&, d&, k&, J&, I&, x&
'On Error Resume Next
Application.ScreenUpdating = False
Set Sh = Sheets("KET QUA")
Sh.Range("A2:L10000").ClearContents
J = Sh.Cells(Rows.Count, 16).End(xlUp).Row
For I = 2 To J
x = 1
    For Each wsh In ThisWorkbook.Worksheets
        If wsh.Name <> "KET QUA" Then
            If x = 1 Then
                d = Application.WorksheetFunction.Match(Sh.Cells(I, 16), wsh.Range("A1:A10000"), 0)
            Else
                d = Application.WorksheetFunction.Match(Sh.Cells(I, 16), wsh.Range("A1:A10000"), 0) + 1
            End If
                k = wsh.Cells(d, 1).End(xlDown).Row - 1
                Lr = Sh.Cells(Rows.Count, 9).End(3).Row
                wsh.Range("A" & d, "L" & k).Copy Sh.Cells(Lr + 1, "A")
                x = x + 1
        End If
Next wsh
Next I
    Sh.Cells(1).Select
    MsgBox " Xong"
Application.ScreenUpdating = True
End Sub
code trên đúng ý mình rồi.
Cảm ơn các bạn rất nhiều đã giúp đỡ.
thanks all
 
Upvote 0
code trên đúng ý mình rồi.
Cảm ơn các bạn rất nhiều đã giúp đỡ.
thanks all
Có lẽ bạn chưa thử hết nên chưa thấy chỗ bất cập. Bạn thử một trong các số thứ tự 176, 177 xem, hoặc nhập cả hai số 176, 177 ở cột P rồi chạy xem.

Lý do: Dữ liệu của bạn bố trí không chuẩn. Lẽ ra tất cả các dòng chứa STT đều phải là dòng tổng và được chi tiết bên dưới chúng. Trong khi các STT đó chỉ có tổng mà không có chi tiết.
 
Upvote 0
code trên đúng ý mình rồi.
Cảm ơn các bạn rất nhiều đã giúp đỡ.
thanks all
Ngoài vấn đề bài #6 đã nói, tôi thấy còn 1 vấn đề nữa.
Trường hợp Số thứ tự chỉ tồn tại ở 1/3 hoặc 2/3 Sheet thành phần thì khi chạy code kia sẽ có lỗi ngay.
 
Upvote 0
Ngoài vấn đề bài #6 đã nói, tôi thấy còn 1 vấn đề nữa.
Trường hợp Số thứ tự chỉ tồn tại ở 1/3 hoặc 2/3 Sheet thành phần thì khi chạy code kia sẽ có lỗi ngay.
Có lẽ bạn chưa thử hết nên chưa thấy chỗ bất cập. Bạn thử một trong các số thứ tự 176, 177 xem, hoặc nhập cả hai số 176, 177 ở cột P rồi chạy xem.

Lý do: Dữ liệu của bạn bố trí không chuẩn. Lẽ ra tất cả các dòng chứa STT đều phải là dòng tổng và được chi tiết bên dưới chúng. Trong khi các STT đó chỉ có tổng mà không có chi tiết.
Cảm ơn bạn @Maika8008 và bạn @vanthinh3101 đã xem bài và chỉ ra chỗ còn thiếu sót. Code của bài này tôi sửa lại thế này, các anh ghé qua xem và kiểm tra giùm xem còn có sai sót gì không nhé.
Mã:
Option Explicit
Sub TONGHOP()
Dim wsh As Worksheet
Dim Sh As Worksheet, Rng As Range, sRng As Range
Dim Lr&, d&, k&, J&, I&, x&, C&
'On Error Resume Next
Application.ScreenUpdating = False
Set Sh = Sheets("KET QUA")
Sh.Range("A2:L10000").ClearContents
J = Sh.Cells(Rows.Count, 16).End(xlUp).Row
For I = 2 To J
x = 1
    For Each wsh In ThisWorkbook.Worksheets
        If wsh.Name <> "KET QUA" Then
            Set Rng = wsh.Range("A2:A10000")
            Set sRng = Rng.Find(Sh.Cells(I, 16))
                If Not sRng Is Nothing Then
                    d = sRng.Row
                Else
                    Exit For
                End If
            If wsh.Cells(d + 1, 1) = Empty Then
                k = wsh.Cells(d, 1).End(xlDown).Row - 1
            Else
                k = d
            End If
                Lr = Sh.Cells(Rows.Count, 9).End(3).Row
            If x = 1 Then
                    wsh.Range("A" & d, "L" & k).Copy Sh.Cells(Lr + 1, "A")
            Else
                If wsh.Cells(d + 1, 1) = Empty Then
                C = d + 1
            Else
                C = d
            End If
                    wsh.Range("A" & C, "L" & k).Copy Sh.Cells(Lr + 1, "A")
            End If
                x = x + 1
        End If
Next wsh
Next I
    Sh.Cells(1).Select
    Set Rng = Nothing: Set sRng = Nothing
    MsgBox " Xong"
Application.ScreenUpdating = True
End Sub
Hy vọng là code này đã khắc phục được 2 lỗi mà 2 anh đã nêu. Chắc là vẫn còn những thiếu sót (lỗi-code) nữa mà tôi chưa có nhiều kinh nghiệm để loại trừ. Mong mọi người nếu ghé qua xem code và cho góp ý để bạn chủ thớt có được code hoàn chỉnh, tôi có thêm kinh nghiệm
Trân trọng!

Đúng như anh Maika8008 đã nhận xét. một phần code chưa chuẩn và phần nữa là dữ liệu bố trí chưa chuẩn nên có thể chạy code cho kết quả không được như mong đợi.
nếu không sửa cột B có dữ liệu I không có dữ liệu thì khi chạy code kết quả sẽ sai.[/CODE]
 
Lần chỉnh sửa cuối:
Upvote 0
Cảm ơn bạn @Maika8008 và bạn @vanthinh3101 đã xem bài và chỉ ra chỗ còn thiếu sót. Code của bài này tôi sửa lại thế này, các anh ghé qua xem và kiểm tra giùm xem còn có sai sót gì không nhé.
Mã:
Option Explicit
Sub TONGHOP()
Dim wsh As Worksheet
Dim Sh As Worksheet, Rng As Range, sRng As Range
Dim Lr&, d&, k&, J&, I&, x&, C&
'On Error Resume Next
Application.ScreenUpdating = False
Set Sh = Sheets("KET QUA")
Sh.Range("A2:L10000").ClearContents
J = Sh.Cells(Rows.Count, 16).End(xlUp).Row
For I = 2 To J
x = 1
    For Each wsh In ThisWorkbook.Worksheets
        If wsh.Name <> "KET QUA" Then
            Set Rng = wsh.Range("A2:A10000")
            Set sRng = Rng.Find(Sh.Cells(I, 16))
                If Not sRng Is Nothing Then
                    d = sRng.Row
                Else
                    Exit For
                End If
            If wsh.Cells(d + 1, 1) = Empty Then
                k = wsh.Cells(d, 1).End(xlDown).Row - 1
            Else
                k = d
            End If
                Lr = Sh.Cells(Rows.Count, 9).End(3).Row
            If x = 1 Then
                    wsh.Range("A" & d, "L" & k).Copy Sh.Cells(Lr + 1, "A")
            Else
                If wsh.Cells(d + 1, 1) = Empty Then
                C = d + 1
            Else
                C = d
            End If
                    wsh.Range("A" & C, "L" & k).Copy Sh.Cells(Lr + 1, "A")
            End If
                x = x + 1
        End If
Next wsh
Next I
    Sh.Cells(1).Select
    Set Rng = Nothing: Set sRng = Nothing
    MsgBox " Xong"
Application.ScreenUpdating = True
End Sub
Hy vọng là code này đã khắc phục được 2 lỗi mà 2 anh đã nêu. Chắc là vẫn còn những thiếu sót (lỗi-code) nữa mà tôi chưa có nhiều kinh nghiệm để loại trừ. Mong mọi người nếu ghé qua xem code và cho góp ý để bạn chủ thớt có được code hoàn chỉnh, tôi có thêm kinh nghiệm
Trân trọng!

Đúng như anh Maika8008 đã nhận xét. một phần code chưa chuẩn và phần nữa là dữ liệu bố trí chưa chuẩn nên có thể chạy code cho kết quả không được như mong đợi.
nếu không sửa cột B có dữ liệu I không có dữ liệu thì khi chạy code kết quả sẽ sai.[/CODE]
Tôi chưa xem được kỹ, nhưng tôi viết code mảng.
Bạn thử xem nhé!
PHP:
Sub Tonghopdulieu()
    Dim Stt(), Res()
    Dim Ws As Worksheet, fRange As Range, fRangeNext As Range
    Dim I As Byte, fRow As Integer, fRowNext As Integer, K As Integer, lR As Integer, lR1 As Integer, lR2 As Integer
    Dim IsFirstWorksheet As Boolean
    
    Application.ScreenUpdating = False
    'Xoa du lieu cu
    Sheet4.Range("A1").CurrentRegion.Offset(1).ClearContents
    'Tao mang chua cac So thu tu can tong hop
    Stt() = Sheet4.Range("P2", Sheet4.Range("P2").End(xlDown)).Value
    'Quy dinh kich thuoc mang ket qua
    'ReDim Res(1 To 100, 1 To 12)
    
    'Vong lap qua tung phan tu cua mang Stt
    For I = 1 To UBound(Stt, 1)
        'Sheet kiem tra dau tien
        IsFirstWorksheet = True
        'Vong lap qua tung sheet trong workbook
        For Each Ws In ThisWorkbook.Sheets
            With Ws
                'Neu khong dung Sheets("KET QUA") thi tiep tuc, dung thi chuyen sheet tiep theo
                If .Name <> "KET QUA" Then
                    'Tim trong cot A o co chua So thu tu can tong hop
                    Set fRange = .Range("A:A").Find(Stt(I, 1))
                    'Neu fRang co ket qua
                    If Not fRange Is Nothing Then
                        'Chi so dong cua fRange
                        fRow = fRange.Row
                        'Tim dong tiep theo co du lieu trong cot A sau fRow
                        fRowNext = .Range("A:A").Find(what:="?*", After:=fRange, LookIn:=xlValues).Row
                        'Truong hop fRow la dong cuoi cung co du lieu trong cot A, fRowNext tra ve ket qua <= fRow
                        If fRowNext <= fRow Then
                            'Gan fRowNext theo chi so dong cuoi o cot B
                            fRowNext = .Range("B" & Rows.Count).End(xlUp).Row + 1
                        End If
                        'Dong cuoi cung co du lieu trong Sheets("KET QUA") + 1 --> dong dau tien de dien ket qua
                        lR1 = Sheet4.Range("I" & Rows.Count).End(xlUp).Row + 1
                        lR2 = Sheet4.Range("J" & Rows.Count).End(xlUp).Row + 1
                        If lR1 > lR2 Then lR = lR1 Else lR = lR2
                        
                        'Neu la Sheet dau tien
                        If IsFirstWorksheet Then
                            K = fRowNext - fRow
                            'Gan gia tri can tim vao mang Ket qua
                            Res() = .Range("A" & fRow).Resize(K, 12).Value
                            'Chuyen gia tri cho bien
                            IsFirstWorksheet = False
                        Else
                            K = fRowNext - fRow - 1
                            'Gan gia tri can tim vao mang Ket qua
                            If K Then
                                Res() = .Range("A" & (fRow + 1)).Resize(K, 12).Value
                            End If
                        End If
                        'Dien ket qua vao Sheets("KET QUA")
                        If K Then Sheet4.Range("A" & lR).Resize(K, 12) = Res
                        'Xoa toan bo du lieu trong mang ket qua
                        Erase Res
                    End If
                End If
            End With
        Next Ws
    Next I
    
    Application.ScreenUpdating = True
    
    MsgBox "Done", vbInformation, "GPE"
End Sub
 
Upvote 0
Tôi chưa xem được kỹ, nhưng tôi viết code mảng.
Bạn thử xem nhé!
PHP:
Sub Tonghopdulieu()
    Dim Stt(), Res()
    Dim Ws As Worksheet, fRange As Range, fRangeNext As Range
    Dim I As Byte, fRow As Integer, fRowNext As Integer, K As Integer, lR As Integer, lR1 As Integer, lR2 As Integer
    Dim IsFirstWorksheet As Boolean
   
    Application.ScreenUpdating = False
    'Xoa du lieu cu
    Sheet4.Range("A1").CurrentRegion.Offset(1).ClearContents
    'Tao mang chua cac So thu tu can tong hop
    Stt() = Sheet4.Range("P2", Sheet4.Range("P2").End(xlDown)).Value
    'Quy dinh kich thuoc mang ket qua
    'ReDim Res(1 To 100, 1 To 12)
   
    'Vong lap qua tung phan tu cua mang Stt
    For I = 1 To UBound(Stt, 1)
        'Sheet kiem tra dau tien
        IsFirstWorksheet = True
        'Vong lap qua tung sheet trong workbook
        For Each Ws In ThisWorkbook.Sheets
            With Ws
                'Neu khong dung Sheets("KET QUA") thi tiep tuc, dung thi chuyen sheet tiep theo
                If .Name <> "KET QUA" Then
                    'Tim trong cot A o co chua So thu tu can tong hop
                    Set fRange = .Range("A:A").Find(Stt(I, 1))
                    'Neu fRang co ket qua
                    If Not fRange Is Nothing Then
                        'Chi so dong cua fRange
                        fRow = fRange.Row
                        'Tim dong tiep theo co du lieu trong cot A sau fRow
                        fRowNext = .Range("A:A").Find(what:="?*", After:=fRange, LookIn:=xlValues).Row
                        'Truong hop fRow la dong cuoi cung co du lieu trong cot A, fRowNext tra ve ket qua <= fRow
                        If fRowNext <= fRow Then
                            'Gan fRowNext theo chi so dong cuoi o cot B
                            fRowNext = .Range("B" & Rows.Count).End(xlUp).Row + 1
                        End If
                        'Dong cuoi cung co du lieu trong Sheets("KET QUA") + 1 --> dong dau tien de dien ket qua
                        lR1 = Sheet4.Range("I" & Rows.Count).End(xlUp).Row + 1
                        lR2 = Sheet4.Range("J" & Rows.Count).End(xlUp).Row + 1
                        If lR1 > lR2 Then lR = lR1 Else lR = lR2
                       
                        'Neu la Sheet dau tien
                        If IsFirstWorksheet Then
                            K = fRowNext - fRow
                            'Gan gia tri can tim vao mang Ket qua
                            Res() = .Range("A" & fRow).Resize(K, 12).Value
                            'Chuyen gia tri cho bien
                            IsFirstWorksheet = False
                        Else
                            K = fRowNext - fRow - 1
                            'Gan gia tri can tim vao mang Ket qua
                            If K Then
                                Res() = .Range("A" & (fRow + 1)).Resize(K, 12).Value
                            End If
                        End If
                        'Dien ket qua vao Sheets("KET QUA")
                        If K Then Sheet4.Range("A" & lR).Resize(K, 12) = Res
                        'Xoa toan bo du lieu trong mang ket qua
                        Erase Res
                    End If
                End If
            End With
        Next Ws
    Next I
   
    Application.ScreenUpdating = True
   
    MsgBox "Done", vbInformation, "GPE"
End Sub
Lúc đầu tôi cũng đã viết code dùng mảng, nhưng sau xét thấy Sh KET QUA có thể vẫn phải dùng đến công thức của cột I , J nên sử dụng phương pháp copy.
Dùng mảng chắc chắn là nhanh rồi, tuy nhiên phương pháp copy cũng không phải là phương pháp kém hiệu quả. Cái đoạn lấy IR1,IR2 và so sánh để lấy dòng cuối cùng của Sh KET QUA là một kinh nghiệm quý.
 
Upvote 0
Lúc đầu tôi cũng đã viết code dùng mảng, nhưng sau xét thấy Sh KET QUA có thể vẫn phải dùng đến công thức của cột I , J nên sử dụng phương pháp copy.
Dùng mảng chắc chắn là nhanh rồi, tuy nhiên phương pháp copy cũng không phải là phương pháp kém hiệu quả. Cái đoạn lấy IR1,IR2 và so sánh để lấy dòng cuối cùng của Sh KET QUA là một kinh nghiệm quý.
Quan trọng vẫn là kết quả đúng bạn ạ.
Hiệu quả tính sau.
 
Upvote 0
Tôi chưa xem được kỹ, nhưng tôi viết code mảng.
Bạn thử xem nhé!
PHP:
Sub Tonghopdulieu()
    Dim Stt(), Res()
    Dim Ws As Worksheet, fRange As Range, fRangeNext As Range
    Dim I As Byte, fRow As Integer, fRowNext As Integer, K As Integer, lR As Integer, lR1 As Integer, lR2 As Integer
    Dim IsFirstWorksheet As Boolean
    
    Application.ScreenUpdating = False
    'Xoa du lieu cu
    Sheet4.Range("A1").CurrentRegion.Offset(1).ClearContents
    'Tao mang chua cac So thu tu can tong hop
    Stt() = Sheet4.Range("P2", Sheet4.Range("P2").End(xlDown)).Value
    'Quy dinh kich thuoc mang ket qua
    'ReDim Res(1 To 100, 1 To 12)
    
    'Vong lap qua tung phan tu cua mang Stt
    For I = 1 To UBound(Stt, 1)
        'Sheet kiem tra dau tien
        IsFirstWorksheet = True
        'Vong lap qua tung sheet trong workbook
        For Each Ws In ThisWorkbook.Sheets
            With Ws
                'Neu khong dung Sheets("KET QUA") thi tiep tuc, dung thi chuyen sheet tiep theo
                If .Name <> "KET QUA" Then
                    'Tim trong cot A o co chua So thu tu can tong hop
                    Set fRange = .Range("A:A").Find(Stt(I, 1))
                    'Neu fRang co ket qua
                    If Not fRange Is Nothing Then
                        'Chi so dong cua fRange
                        fRow = fRange.Row
                        'Tim dong tiep theo co du lieu trong cot A sau fRow
                        fRowNext = .Range("A:A").Find(what:="?*", After:=fRange, LookIn:=xlValues).Row
                        'Truong hop fRow la dong cuoi cung co du lieu trong cot A, fRowNext tra ve ket qua <= fRow
                        If fRowNext <= fRow Then
                            'Gan fRowNext theo chi so dong cuoi o cot B
                            fRowNext = .Range("B" & Rows.Count).End(xlUp).Row + 1
                        End If
                        'Dong cuoi cung co du lieu trong Sheets("KET QUA") + 1 --> dong dau tien de dien ket qua
                        lR1 = Sheet4.Range("I" & Rows.Count).End(xlUp).Row + 1
                        lR2 = Sheet4.Range("J" & Rows.Count).End(xlUp).Row + 1
                        If lR1 > lR2 Then lR = lR1 Else lR = lR2
                        
                        'Neu la Sheet dau tien
                        If IsFirstWorksheet Then
                            K = fRowNext - fRow
                            'Gan gia tri can tim vao mang Ket qua
                            Res() = .Range("A" & fRow).Resize(K, 12).Value
                            'Chuyen gia tri cho bien
                            IsFirstWorksheet = False
                        Else
                            K = fRowNext - fRow - 1
                            'Gan gia tri can tim vao mang Ket qua
                            If K Then
                                Res() = .Range("A" & (fRow + 1)).Resize(K, 12).Value
                            End If
                        End If
                        'Dien ket qua vao Sheets("KET QUA")
                        If K Then Sheet4.Range("A" & lR).Resize(K, 12) = Res
                        'Xoa toan bo du lieu trong mang ket qua
                        Erase Res
                    End If
                End If
            End With
        Next Ws
    Next I
    
    Application.ScreenUpdating = True
    
    MsgBox "Done", vbInformation, "GPE"
End Sub
Dùng mảng thì sẽ phát sinh vấn đề phải định dạng vùng kết quả. Nếu thừa thì hơi dở tí nhưng còn đỡ, nhưng nếu thiếu thì sẽ thòi ra mấy dòng không được định dạng thì dở hơn.

Mà phải định dạng bằng vba thì lại chậm tốc độ -> cũng bằng như cách làm trên sheet.
 
Upvote 0
Cảm ơn bạn @Maika8008 và bạn @vanthinh3101 đã xem bài và chỉ ra chỗ còn thiếu sót. Code của bài này tôi sửa lại thế này, các anh ghé qua xem và kiểm tra giùm xem còn có sai sót gì không nhé.
Mã:
Option Explicit
Sub TONGHOP()
Dim wsh As Worksheet
Dim Sh As Worksheet, Rng As Range, sRng As Range
Dim Lr&, d&, k&, J&, I&, x&, C&
'On Error Resume Next
Application.ScreenUpdating = False
Set Sh = Sheets("KET QUA")
Sh.Range("A2:L10000").ClearContents
J = Sh.Cells(Rows.Count, 16).End(xlUp).Row
For I = 2 To J
x = 1
    For Each wsh In ThisWorkbook.Worksheets
        If wsh.Name <> "KET QUA" Then
            Set Rng = wsh.Range("A2:A10000")
            Set sRng = Rng.Find(Sh.Cells(I, 16))
                If Not sRng Is Nothing Then
                    d = sRng.Row
                Else
                    Exit For
                End If
            If wsh.Cells(d + 1, 1) = Empty Then
                k = wsh.Cells(d, 1).End(xlDown).Row - 1
            Else
                k = d
            End If
                Lr = Sh.Cells(Rows.Count, 9).End(3).Row
            If x = 1 Then
                    wsh.Range("A" & d, "L" & k).Copy Sh.Cells(Lr + 1, "A")
            Else
                If wsh.Cells(d + 1, 1) = Empty Then
                C = d + 1
            Else
                C = d
            End If
                    wsh.Range("A" & C, "L" & k).Copy Sh.Cells(Lr + 1, "A")
            End If
                x = x + 1
        End If
Next wsh
Next I
    Sh.Cells(1).Select
    Set Rng = Nothing: Set sRng = Nothing
    MsgBox " Xong"
Application.ScreenUpdating = True
End Sub
Hy vọng là code này đã khắc phục được 2 lỗi mà 2 anh đã nêu. Chắc là vẫn còn những thiếu sót (lỗi-code) nữa mà tôi chưa có nhiều kinh nghiệm để loại trừ. Mong mọi người nếu ghé qua xem code và cho góp ý để bạn chủ thớt có được code hoàn chỉnh, tôi có thêm kinh nghiệm
Trân trọng!

Đúng như anh Maika8008 đã nhận xét. một phần code chưa chuẩn và phần nữa là dữ liệu bố trí chưa chuẩn nên có thể chạy code cho kết quả không được như mong đợi.
nếu không sửa cột B có dữ liệu I không có dữ liệu thì khi chạy code kết quả sẽ sai.[/CODE]
Nhập P2=151 và P3=162 kiểm tra lại thấy nhiều chỗ chưa đúng như:
Dữ liệu không chuẩn, khi copy công thức hàm Sum vùng tham chiếu không còn đúng
Chỉ copy tới cột L, cột L tính tích lũy sử dụng dữ liệu cột M: copy thiếu
....
Tôi chưa xem được kỹ, nhưng tôi viết code mảng.
Bạn thử xem nhé!
PHP:
Sub Tonghopdulieu()
    Dim Stt(), Res()
    Dim Ws As Worksheet, fRange As Range, fRangeNext As Range
    Dim I As Byte, fRow As Integer, fRowNext As Integer, K As Integer, lR As Integer, lR1 As Integer, lR2 As Integer
    Dim IsFirstWorksheet As Boolean
   
    Application.ScreenUpdating = False
    'Xoa du lieu cu
    Sheet4.Range("A1").CurrentRegion.Offset(1).ClearContents
    'Tao mang chua cac So thu tu can tong hop
    Stt() = Sheet4.Range("P2", Sheet4.Range("P2").End(xlDown)).Value
    'Quy dinh kich thuoc mang ket qua
    'ReDim Res(1 To 100, 1 To 12)
   
    'Vong lap qua tung phan tu cua mang Stt
    For I = 1 To UBound(Stt, 1)
        'Sheet kiem tra dau tien
        IsFirstWorksheet = True
        'Vong lap qua tung sheet trong workbook
        For Each Ws In ThisWorkbook.Sheets
            With Ws
                'Neu khong dung Sheets("KET QUA") thi tiep tuc, dung thi chuyen sheet tiep theo
                If .Name <> "KET QUA" Then
                    'Tim trong cot A o co chua So thu tu can tong hop
                    Set fRange = .Range("A:A").Find(Stt(I, 1))
                    'Neu fRang co ket qua
                    If Not fRange Is Nothing Then
                        'Chi so dong cua fRange
                        fRow = fRange.Row
                        'Tim dong tiep theo co du lieu trong cot A sau fRow
                        fRowNext = .Range("A:A").Find(what:="?*", After:=fRange, LookIn:=xlValues).Row
                        'Truong hop fRow la dong cuoi cung co du lieu trong cot A, fRowNext tra ve ket qua <= fRow
                        If fRowNext <= fRow Then
                            'Gan fRowNext theo chi so dong cuoi o cot B
                            fRowNext = .Range("B" & Rows.Count).End(xlUp).Row + 1
                        End If
                        'Dong cuoi cung co du lieu trong Sheets("KET QUA") + 1 --> dong dau tien de dien ket qua
                        lR1 = Sheet4.Range("I" & Rows.Count).End(xlUp).Row + 1
                        lR2 = Sheet4.Range("J" & Rows.Count).End(xlUp).Row + 1
                        If lR1 > lR2 Then lR = lR1 Else lR = lR2
                       
                        'Neu la Sheet dau tien
                        If IsFirstWorksheet Then
                            K = fRowNext - fRow
                            'Gan gia tri can tim vao mang Ket qua
                            Res() = .Range("A" & fRow).Resize(K, 12).Value
                            'Chuyen gia tri cho bien
                            IsFirstWorksheet = False
                        Else
                            K = fRowNext - fRow - 1
                            'Gan gia tri can tim vao mang Ket qua
                            If K Then
                                Res() = .Range("A" & (fRow + 1)).Resize(K, 12).Value
                            End If
                        End If
                        'Dien ket qua vao Sheets("KET QUA")
                        If K Then Sheet4.Range("A" & lR).Resize(K, 12) = Res
                        'Xoa toan bo du lieu trong mang ket qua
                        Erase Res
                    End If
                End If
            End With
        Next Ws
    Next I
   
    Application.ScreenUpdating = True
   
    MsgBox "Done", vbInformation, "GPE"
End Sub
Nếu chỉ nhập P2=151 các ô dưới trống sẽ bị lỗi.
Nhập P2=151 và P3=162 kiểm tra lại thấy nhiều chỗ chưa đúng. Các ô có công thức khá phức tạp phải thêm lệnh tính riêng
 
Upvote 0
Các ơn các bạn HUONGHCKT, Maika8008, Vanthinh3101, HieuCD rất nhiều đã giúp đỡ mình. Chứ không mình copy 15000 dòng chắc xỉu. VBA thật tuyệt.
 
Upvote 0
Nhập P2=151 và P3=162 kiểm tra lại thấy nhiều chỗ chưa đúng như:
Dữ liệu không chuẩn, khi copy công thức hàm Sum vùng tham chiếu không còn đúng
Chỉ copy tới cột L, cột L tính tích lũy sử dụng dữ liệu cột M: copy thiếu
...
Cảm ơn anh đã quan tâm xem bài và chỉ ra chỗ còn sai, còn thiếu.
1/Do dữ liệu không chuẩn và chủ thớt yêu cầu xóa bỏ dòng TT nếu trùng nhau ==> công thức copy sang sẽ bị sai, việc này chắc chắn chủ thớt biết và có hướng khắc phục. (Tự XD kiểm tra và XD lại công thức các ô trong vùng kết quả)
2/Copy thiếu dữ liệu cột M, do các Sh cần lấy dữ liệu thấy để cột M nằm ngoài vùng view và không có tiêu đề, nên không copy. Còn nếu copy thì sửa lại code dòng wsh.Range("A" & d, "L" & K).Copy Sh.Cells(Lr + 1, "A") thay bằng wsh.Range("A" & d, "M" & K).Copy Sh.Cells(Lr + 1, "A") là được.
3/ Tôi cũng không kiểm tra kỹ kết quả, đúng như anh đã chỉ ra :Khi nhập P2=151, P3=162 và chạy code ra kết quả thiếu: Đó là do code lấy dòng cuối của Sh KET QUA chỉ lấy ở cột I mà dòng I(n) không có dữ liệu==> paste sai dòng. Hướng khắc phục lỗi này là Tìm dòng cuối cả 2 cột I và J và gán vào biến Lr1,Lr2
Lr1 = Sh.Cells(Rows.Count, 9).End(3).Row
Lr2 = Sh.Cells(Rows.Count, 10).End(3).Row

và thêm đoạn code để xác định If Lr1>Lr2 then Lr=Lr1 else Lr=Lr2 thì thấy ổn.

Tôi chưa có nhiều kinh nghiệm viết code và cũng nhác kiểm tra kỹ chỉ thấy code chạy ổn trong một vài trường hợp là thấy được rồi.
Mong anh và các anh chị em khác quan tâm xem và chỉ giáo những chỗ còn sai còn thiếu để hoàn thiện.
Trân trọng !
 
Upvote 0
Tôi nghĩ là bài này có thể sửa code để thành có thể chọn các Sh khác nhau để lấy dữ liệu theo kiểu:
Các Sheet cần lấy dũ liệuNhập số TT cần tổng hợp
DC
151​
MD
162​
176​
177​
Hoặc
Các Sheet cần lấy dũ liệuNhập số TT cần tổng hợp
DC151,162, 158
MD
163, 177, 169​
Thì đều được và cũng tiện cho người cần tổng hợp.
 
Upvote 0
Nếu chỉ nhập P2=151 các ô dưới trống sẽ bị lỗi.
Em sửa lại 1 chút, đúng là em hơi chủ quan chỗ này:
Từ:
PHP:
Stt() = Sheet4.Range("P2", Sheet4.Range("P2").End(xlDown)).Value
Thành:
PHP:
lR = Sheet4.Range("P" & Rows.Count).End(xlUp).Row
If lR = 1 Then
    MsgBox "Chua co thong tin STT can tong hop", vbCritical, "GPE"
    Exit Sub
Else
    Stt() = Sheet4.Range("P2").Resize(lR - 2 + 1).Value
End If

Nhập P2=151 và P3=162 kiểm tra lại thấy nhiều chỗ chưa đúng. Các ô có công thức khá phức tạp phải thêm lệnh tính riêng
Thực tế là em thấy dữ liệu cũng có vấn đề, chưa chuẩn hóa.
Nhưng điều này thì người đưa yêu cầu trợ giúp phải xem xét để điều chỉnh lại.
Em chắc chắn các code gợi ý cho bạn đó bây giờ chưa thể chuẩn được.
Hơi lạ là bạn đó cứ cảm ơn nhưng không biết kết quả ứng ý chưa :rolleyes:

Em cám ơn anh và chúc anh 1 ngày vui :D
 
Upvote 0
Em sửa lại 1 chút, đúng là em hơi chủ quan chỗ này:
Từ:
PHP:
Stt() = Sheet4.Range("P2", Sheet4.Range("P2").End(xlDown)).Value
Thành:
PHP:
lR = Sheet4.Range("P" & Rows.Count).End(xlUp).Row
If lR = 1 Then
    MsgBox "Chua co thong tin STT can tong hop", vbCritical, "GPE"
    Exit Sub
Else
    Stt() = Sheet4.Range("P2").Resize(lR - 2 + 1).Value
End If


Thực tế là em thấy dữ liệu cũng có vấn đề, chưa chuẩn hóa.
Nhưng điều này thì người đưa yêu cầu trợ giúp phải xem xét để điều chỉnh lại.
Em chắc chắn các code gợi ý cho bạn đó bây giờ chưa thể chuẩn được.
Hơi lạ là bạn đó cứ cảm ơn nhưng không biết kết quả ứng ý chưa :rolleyes:

Em cám ơn anh và chúc anh 1 ngày vui :D

Tôi thấy với code của bạn thì vấn đề các STT chỉ có 1 dòng vẫn chưa được đưa vào kết quả, trong khi nó vẫn phải được đưa vào chứ. Còn với chủ thớt thì chẳng biết thế nào, hay là anh ta chỉ cần làm với mấy cài STT có nhiều dòng chi tiết đó?!
 
Upvote 0
Code của các bạn đã đúng ý mình . đúng là dữ liệu của mình cần phải chuẩn hóa lại file mình . cảm ơn các bạn HUONGHCKT, Maika8008, Vanthinh3101, HieuCD đã giúp đỡ mình.
 
Upvote 0
Tôi thấy với code của bạn thì vấn đề các STT chỉ có 1 dòng vẫn chưa được đưa vào kết quả, trong khi nó vẫn phải được đưa vào chứ. Còn với chủ thớt thì chẳng biết thế nào, hay là anh ta chỉ cần làm với mấy cài STT có nhiều dòng chi tiết đó?!
Do tôi nhìn trong dữ liệu các trường hợp có 1 dòng giống nhau hết nên tôi không lấy.
Đoán là ý chủ thớt vậy, thực tế thì...
Nếu cứ lấy thì sửa thêm 1 chút :p
PHP:
Sub Tonghopdulieu()
    Dim Stt(), Res()
    Dim Ws As Worksheet, fRange As Range, fRangeNext As Range
    Dim I As Byte, fRow As Integer, fRowNext As Integer, K As Integer, lR As Integer, lR1 As Integer, lR2 As Integer
    Dim IsFirstWorksheet As Boolean
    
    Application.ScreenUpdating = False
    'Xoa du lieu cu
    Sheet4.Range("A1").CurrentRegion.Offset(1).ClearContents
    'Tao mang chua cac So thu tu can tong hop
    lR = Sheet4.Range("P" & Rows.Count).End(xlUp).Row
    If lR = 1 Then
        MsgBox "Chua co thong tin STT can tong hop", vbCritical, "GPE"
        Exit Sub
    Else
        Stt() = Sheet4.Range("P2").Resize(lR - 2 + 1).Value
    End If
    'Quy dinh kich thuoc mang ket qua
    'ReDim Res(1 To 100, 1 To 12)
    
    'Vong lap qua tung phan tu cua mang Stt
    For I = 1 To UBound(Stt, 1)
        'Sheet kiem tra dau tien
        IsFirstWorksheet = True
        'Vong lap qua tung sheet trong workbook
        For Each Ws In ThisWorkbook.Sheets
            With Ws
                'Neu khong dung Sheets("KET QUA") thi tiep tuc, dung thi chuyen sheet tiep theo
                If .Name <> "KET QUA" Then
                    'Tim trong cot A o co chua So thu tu can tong hop
                    Set fRange = .Range("A:A").Find(Stt(I, 1))
                    'Neu fRang co ket qua
                    If Not fRange Is Nothing Then
                        'Chi so dong cua fRange
                        fRow = fRange.Row
                        'Tim dong tiep theo co du lieu trong cot A sau fRow
                        fRowNext = .Range("A:A").Find(what:="?*", After:=fRange, LookIn:=xlValues).Row
                        'Truong hop fRow la dong cuoi cung co du lieu trong cot A, fRowNext tra ve ket qua <= fRow
                        If fRowNext <= fRow Then
                            'Gan fRowNext theo chi so dong cuoi o cot B
                            fRowNext = .Range("B" & Rows.Count).End(xlUp).Row + 1
                        End If
                        'Dong cuoi cung co du lieu trong Sheets("KET QUA") + 1 --> dong dau tien de dien ket qua
                        lR1 = Sheet4.Range("I" & Rows.Count).End(xlUp).Row + 1
                        lR2 = Sheet4.Range("J" & Rows.Count).End(xlUp).Row + 1
                        If lR1 > lR2 Then lR = lR1 Else lR = lR2
                        
                        'Neu la Sheet dau tien
                        If IsFirstWorksheet Then
                            K = fRowNext - fRow
                            'Gan gia tri can tim vao mang Ket qua
                            Res() = .Range("A" & fRow).Resize(K, 12).Value
                            'Chuyen gia tri cho bien
                            IsFirstWorksheet = False
                        Else
                            K = fRowNext - fRow - 1
                            'Gan gia tri can tim vao mang Ket qua
                            If K Then
                                Res() = .Range("A" & (fRow + 1)).Resize(K, 12).Value
                            Else
                                Res() = .Range("A" & fRow).Resize(, 12).Value
                                Res(1, 1) = ""
                            End If
                        End If
                        'Dien ket qua vao Sheets("KET QUA")
                        Sheet4.Range("A" & lR).Resize(UBound(Res, 1), 12) = Res
                        'Xoa toan bo du lieu trong mang ket qua
                        Erase Res
                    End If
                End If
            End With
        Next Ws
    Next I
    
    Application.ScreenUpdating = True
    
    MsgBox "Done", vbInformation, "GPE"
End Sub
 
Upvote 0
Web KT

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

Back
Top Bottom