Gộp Dữ Liệu

  • Thread starter Thread starter ZzNHCzZ
  • Ngày gửi Ngày gửi
Liên hệ QC

ZzNHCzZ

Thành viên bị đình chỉ hoạt động
Thành viên bị đình chỉ hoạt động
Tham gia
8/5/08
Bài viết
166
Được thích
44
Nghề nghiệp
Hàng Không
Xin chào GPE!
Em muốn viết 1 Macro gộp dữ liệu các Sheet lại thành 1 sheet.
Để tiện làm Báo cáo.
Mong nhận được sự góp ý và giúp đở từ mọi người.

Thân!
 
Lần chỉnh sửa cuối:

File đính kèm

Upvote 0
Có cãm giác bài này sẽ có 1 cách khác hay hơn: Bằng cách quét qua các sheet, xem tiêu đề cột là chử gì và ra quyết định sẽ copy dử liệu nguồn dán vào cột nào của KQ!
Ví dụ: Khi quét qua sheet4, thấy cột E có chử Phụ cấp thì ta đánh dấu cho nó là số 6 (tương đương với chỉ số cột Phụ cấp của sheet KQ)... Khi copy nó sang KQ, tự động code nhận biết rằng sẽ phải dán cột E của sheet4 vào cột Phụ cấp của sheet KQ
Nghĩ là thế mà làm nãy giờ ko ra!
 
Upvote 0
Đây rồi!
PHP:
Option Explicit
Sub MCopy()
  Dim K1, K2, K3, K4, K5, K6 As Byte
  Dim Rng, Rng1, Rng2, Rng3, Rng4, Rng5, Rng6 As Range
  Dim i, Er1, Er2 As Long
  On Error Resume Next
  ActiveSheet.Range("A2:G1000").Clear
  Set Rng = ActiveSheet.Range("A1:G1")
  For i = 1 To ActiveSheet.Index - 1
    With Sheets(i)
      Er1 = .[A65536].End(xlUp).Row
      Er2 = Sheet5.[A65536].End(xlUp).Row + 1
      K1 = Application.WorksheetFunction.Match(.Cells(1, 1), Rng, 0)
      K2 = Application.WorksheetFunction.Match(.Cells(1, 2), Rng, 0)
      K3 = Application.WorksheetFunction.Match(.Cells(1, 3), Rng, 0)
      K4 = Application.WorksheetFunction.Match(.Cells(1, 4), Rng, 0)
      K5 = Application.WorksheetFunction.Match(.Cells(1, 5), Rng, 0)
      K6 = Application.WorksheetFunction.Match(.Cells(1, 6), Rng, 0)
      Set Rng1 = .Range("A2:A" & Er1)
      Set Rng2 = .Range("B2:B" & Er1)
      Set Rng3 = .Range("C2:C" & Er1)
      Set Rng4 = .Range("D2:D" & Er1)
      Set Rng5 = .Range("E2:E" & Er1)
      Set Rng6 = .Range("F2:F" & Er1)
      Rng1.Copy Destination:=Cells(Er2, K1)
      Rng2.Copy Destination:=Cells(Er2, K2)
      Rng3.Copy Destination:=Cells(Er2, K3)
      Rng4.Copy Destination:=Cells(Er2, K4)
      Rng5.Copy Destination:=Cells(Er2, K5)
      Rng6.Copy Destination:=Cells(Er2, K6)
    End With
  Next
End Sub
Bạn chạy file đính kèm của tôi... Cho bạn đảo lộn trật của các cột thoải mái, nó vẩn copy về sheet KQ chính xác
Yêu cầu:
-TIÊU ĐỀ CỘT của bạn phải thống nhất (chổ thì viết là TIỀN, chổ viết TRỪ TIỀN là toi)
-Cho phép thêm sheet nhưng sheet KQ phải là sheet cuối cùng
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Xin chào GPE!
Em muốn viết 1 Macro gộp dữ liệu các Sheet lại thành 1 sheet.
Để tiện làm Báo cáo.
Mong nhận được sự góp ý và giúp đở từ mọi người.

Thân!

Gửi bạn một cách khác ngắn gọn :

PHP:
Sub Loc()
Dim sh As Byte, i As Byte
Dim ri As Long, r As Long
    Sheet3.Columns("F:F").Insert Shift:=xlToRight
    Sheet4.Columns("E:E").Insert Shift:=xlToRight
    Sheet5.Range("A2:G65536").ClearContents
    For sh = 1 To 4
        ri = Sheets(sh).[A65536].End(xlUp).Row
        Sheets(sh).Range("A2:G" & ri).Copy
        r = Sheet5.[A65536].End(xlUp).Row + 1
        Sheet5.Range("A" & r).PasteSpecial Paste:=xlPasteValues
    Next
    Sheet3.Columns("F:F").Delete Shift:=xlToRight
    Sheet4.Columns("E:E").Delete Shift:=xlToRight
    [H3].Select
End Sub
 

File đính kèm

Upvote 0
Bạn chạy file đính kèm của tôi... Cho bạn đảo lộn trật của các cột thoải mái, nó vẩn copy về sheet KQ chính xác
Yêu cầu:
-TIÊU ĐỀ CỘT của bạn phải thống nhất (chổ thì viết là TIỀN, chổ viết TRỪ TIỀN là toi)
-Cho phép thêm sheet nhưng sheet KQ phải là sheet cuối cùng

Anhtuan1106 em chưa hiểu Code của anh cho lắm.
Mong anh giải thích tường tận giúp em.
Đoạn nào nói lên có thể thay đổi vị trí cột?


Thân!
 
Upvote 0
Anhtuan1106 em chưa hiểu Code của anh cho lắm.
Mong anh giải thích tường tận giúp em.
Đoạn nào nói lên có thể thay đổi vị trí cột?


Thân!

Ý nghĩa trong code của Bác Antuan1066 là dò tìm từ khóa trong tiêu đề cột của từng sheet, sau đó sẽ chỉ ra cột nào của sheet nào sẽ được đưa vào đúng vị trí ở sheet cuối cùng. Do vậy khi ta thay đổi thứ tự các cột như Bộ phận qua Ngày hay Ngày qua Phụ cấp thì code vẫn chạy đúng (với điều kiện là text trong tiêu đề ở các sheet phải thống nhất với nhau)
 
Upvote 0
Ý nghĩa trong code của Bác Antuan1066 là dò tìm từ khóa trong tiêu đề cột của từng sheet, sau đó sẽ chỉ ra cột nào của sheet nào sẽ được đưa vào đúng vị trí ở sheet cuối cùng. Do vậy khi ta thay đổi thứ tự các cột như Bộ phận qua Ngày hay Ngày qua Phụ cấp thì code vẫn chạy đúng (với điều kiện là text trong tiêu đề ở các sheet phải thống nhất với nhau)

Ý em muốn hỏi đoạn Code nào của anh tuan đã nói lên điều đó.
Và giải thích giúp em ý nghĩa của những đoạn code sau:
K1 = Application.WorksheetFunction.Match(.Cells(1, 1), Rng, 0)
Set Rng1 = .Range("A2:A" & Er1)
Rng1.Copy Destination:=Cells(Er2, K1)

Em cám ơn!
Thân!
 
Upvote 0
Anhtuan1106 em chưa hiểu Code của anh cho lắm.
Mong anh giải thích tường tận giúp em.
Đoạn nào nói lên có thể thay đổi vị trí cột?


Thân!
Ngay đoạn :
K1 = Application.WorksheetFunction.Match(.Cells(1, 1), Rng, 0)
K2 = Application.WorksheetFunction.Match(.Cells(1, 2), Rng, 0)
K3 = Application.WorksheetFunction.Match(.Cells(1, 3), Rng, 0)
K4 = Application.WorksheetFunction.Match(.Cells(1, 4), Rng, 0)
K5 = Application.WorksheetFunction.Match(.Cells(1, 5), Rng, 0)
K6 = Application.WorksheetFunction.Match(.Cells(1, 6), Rng, 0)
Dùng Match để xác định tiêu đề cột của từng sheet tương ứng với cột mấy của sheet KQ
Nhân đây xin hỏi các cao thủ: Tôi cải tiến code trên thành:
PHP:
Sub MCopy()
  Dim K As Byte
  Dim Rng As Range
  Dim i, j, Er1, Er2 As Long
  On Error Resume Next
  ActiveSheet.Range("A2:G1000").Clear
  Set Rng = ActiveSheet.Range("A1:G1")
  For i = 1 To ActiveSheet.Index - 1
    With Sheets(i)
      Er1 = .[A65536].End(xlUp).Row
      Er2 = ActiveSheet.[A65536].End(xlUp).Row + 1
      For j = 1 To 6
        K = Application.WorksheetFunction.Match(.Cells(1, j), Rng, 0)
        .Range(Cells(2, j), Cells(Er1, j)).Copy Destination:=Cells(Er2, K)
      Next j
    End With
  Next i
End Sub
Nó sai chổ nào mà lại ko chạy dc nhỉ? (dù ko báo lổi gì cả)
 
Upvote 0
Em thấy đoạn này kỳ kỳ sao ấy.
With Sheets(i)
.Range(Cells(2, j), Cells(Er1, j)).Copy Destination:=Cells(Er2, K)

Em chưa text thử vì tới giờ về rồi.
Bác cố gắng tiếp nha
 
Upvote 0
Tức mình quá sửa lại như vầy:
PHP:
Option Explicit
Sub MCopy()
  Dim K As Byte
  Dim Rng As Range
  Dim Col As String
  Dim i As Long, j As Long, Er1 As Long, Er2 As Long
  ActiveSheet.Range("A2:G1000").Clear
  Set Rng = ActiveSheet.Range("A1:G1")
  For i = 1 To ActiveSheet.Index - 1
    With Sheets(i)
      Er1 = .[A65536].End(xlUp).Row
      Er2 = ActiveSheet.[A65536].End(xlUp).Row + 1
      For j = 1 To 7
        On Error Resume Next
        K = Application.WorksheetFunction.Match(.Cells(1, j), Rng, 0)
        Col = Chr(j + 64)
        .Range(Col & "2:" & Col & Er1).Copy Destination:=Cells(Er2, K)
      Next j
    End With
  Next i
End Sub
Nó chạy, có ra kết quả, nhưng chẳng chính xác tí nào!
Đau đầu quá đi mất
 
Upvote 0
Ai cha cha!
Cố gắng lắm tôi mới tạm sửa code trên thành:
PHP:
Option Explicit
Sub MCopy()
  Dim K As Byte
  Dim Rng, Clls As Range
  Dim Col As String
  Dim i As Long, j As Long, Er1 As Long, Er2 As Long
  ActiveSheet.Range("A2:G1000").Clear
  Set Rng = ActiveSheet.Range("A1:G1")
  For i = 1 To ActiveSheet.Index - 1
    With Sheets(i)
      Er1 = .[A65536].End(xlUp).Row
      Er2 = ActiveSheet.[A65536].End(xlUp).Row + 1
      For j = 1 To 7
        For Each Clls In Rng
          If Clls = .Cells(1, j) Then
             K = Clls.Column
             Col = Replace(Cells(1, j).Address(0, 0), 1, "")
             .Range(Col & "2:" & Col & Er1).Copy Destination:=Cells(Er2, K)
          End If
        Next Clls
      Next j
    End With
  Next i
End Sub
Chẳng hài lòng tí nào nhưng cũng ko biết làm cách nào khác!
Các cao thủ đại ca ơi, cứu với (dùng Match ko thành công, sao kỳ vậy ta?)
 

File đính kèm

Upvote 0
Ai cha cha!
Cố gắng lắm tôi mới tạm sửa code trên thành:
PHP:
Option Explicit
Sub MCopy()
  Dim K As Byte
  Dim Rng, Clls As Range
  Dim Col As String
  Dim i As Long, j As Long, Er1 As Long, Er2 As Long
  ActiveSheet.Range("A2:G1000").Clear
  Set Rng = ActiveSheet.Range("A1:G1")
  For i = 1 To ActiveSheet.Index - 1
    With Sheets(i)
      Er1 = .[A65536].End(xlUp).Row
      Er2 = ActiveSheet.[A65536].End(xlUp).Row + 1
      For j = 1 To 7
        For Each Clls In Rng
          If Clls = .Cells(1, j) Then
             K = Clls.Column
             Col = Replace(Cells(1, j).Address(0, 0), 1, "")
             .Range(Col & "2:" & Col & Er1).Copy Destination:=Cells(Er2, K)
          End If
        Next Clls
      Next j
    End With
  Next i
End Sub
Chẳng hài lòng tí nào nhưng cũng ko biết làm cách nào khác!
Các cao thủ đại ca ơi, cứu với (dùng Match ko thành công, sao kỳ vậy ta?)


Dùng hàm match thì rất nhanh, nhưng có điều không thuận lợi là sẽ báo lỗi và thoát (Exit Sub) khi không tìm thấy.
Vì vậy thường hay có dòng :
PHP:
On error resume next

Tuy nhiên có những khi (hiếm) điều này vẫn không khắc phục hết được.

Hoặc chế thành 1 UDF riêng (em thường làm), nếu không tìm thấy thì UDF sẽ trả về giá trị 0

Thân!
 
Upvote 0
Dùng hàm match thì rất nhanh, nhưng có điều không thuận lợi là sẽ báo lỗi và thoát (Exit Sub) khi không tìm thấy.
Vì vậy thường hay có dòng :
PHP:
On error resume next

Tuy nhiên có những khi (hiếm) điều này vẫn không khắc phục hết được.

Hoặc chế thành 1 UDF riêng (em thường làm), nếu không tìm thấy thì UDF sẽ trả về giá trị 0

Thân!
Đúng rồi! Đoạn code ở bài #11 tôi có dùng On Error Resume Next nhưng vẩn ko dc gì?
Các cao thủ nghiên cứu giúp! Nhìn thấy rất đơn giản vậy mà nghiên cứu ko ra, tức thật (code ở bài #12 chạy dc nhưng nhìn nó "phô" quá)
Còn nữa:
Tôi copy vùng từ dòng 2 cột j đến dòng Er1 cột j, tôi viết code:
Range(Cells(2, j), Cells(Er1, j)).Copy
Vậy mà nó chẳng hiểu gì cả (tôi đã thí nghiệm rất kỹ, code này đâu có sai cú pháp)
Trong khi tôi covert j thành ký tự rồi gán:
Col = Replace(Cells(1, j).Address(0, 0), 1, "")
Range(Col & "2:" & Col & Er1).Copy
Thì lại dc! khó hiểu !!!
 
Lần chỉnh sửa cuối:
Upvote 0
Mã:
Nguyên văn bởi [B]anhtuan1066[/B]
With Sheets(i)
      Er1 = .[A65536].End(xlUp).Row
      Er2 = ActiveSheet.[A65536].End(xlUp).Row + 1
      For j = 1 To 6
        K = Application.WorksheetFunction.Match(.Cells(1, j), Rng, 0)
        .Range(Cells(2, j), Cells(Er1, j)).Copy Destination:=Cells(Er2, K)
      Next j
    End With
-Đoạn code bị sai lỗi cú pháp nên không chạy, đúng hơn là có chạy nhưng không ra kết quả. Bạn phải viết như sau:
Mã:
        .Range(.Cells(2, j), .Cells(Er1, j)).Copy Destination:=Cells(Er2, K)
-Tuy nhiên, hàm Match dùng trong trường hợp này sẽ không cho kết quả đúng.
-Còn khi bạn convert thành dạng .Range("A1:A10"), lỗi trên không còn nữa nên code chạy bình thường.
 
Upvote 0
Cảm ơn thầy! Em vò đầu bứt tóc cũng làm dc như ý muốn
1> Cái vụ Range(Cells.... rắc rối ấy em quăng luôn, thay bằng Cells(...).Resize ... (quá gọn)
2> Match đúng là chạy ko chính xác dù đã có On Error Resume Next ... Em giãi quyết bằng cách thêm COUNTIF vào... Nếu COUNTIF > 0 thì MATCH ... (khỏe re)
Cuối cùng là code:
PHP:
Option Explicit
Sub MCopy()
  Dim K As Byte
  Dim Rng As Range
  Dim i As Long, j As Long, Er1 As Long, Er2 As Long
  Application.ScreenUpdating = False
  ActiveSheet.Range("A2:G1000").Clear
  Set Rng = ActiveSheet.Range("A1:G1")
  For i = 1 To ActiveSheet.Index - 1
    With Sheets(i)
      Er1 = .[A65536].End(xlUp).Row
      Er2 = ActiveSheet.[A65536].End(xlUp).Row + 1
      For j = 1 To 7
        If Application.WorksheetFunction.CountIf(Rng, .Cells(1, j)) > 0 Then
           K = Application.WorksheetFunction.Match(.Cells(1, j), Rng, 0)
           .Cells(2, j).Resize(Er1 - 1, 1).Copy Destination:=Cells(Er2, K)
        End If
      Next j
    End With
  Next i
  Application.ScreenUpdating = True
End Sub
Chạy "bá chấy" luôn, dù vẩn chưa mấy hài lòng! Mong thầy lưu ý và chỉnh sửa thêm giùm em!
 

File đính kèm

Upvote 0
Tôi cũng xin tham gia 1 code. Tránh tình trạng "chạy xe không".
PHP:
Option Explicit
Sub CopyTN()
With Application
    .DisplayAlerts = False
    .ScreenUpdating = False
End With
  Dim NumOfSh As Integer, i As Integer, j As Integer, k As Integer, RowCount As Integer, Er2 As Integer, EndC As Integer
  Dim shName As String
  NumOfSh = Worksheets.Count
  Sheets("KQ").Select
  Range("A2:G1000").Clear 'xoa
  For i = 1 To NumOfSh
  shName = Sheets(i).Name
    If shName <> "KQ" Then
        With Sheets(shName)
            RowCount = .[A65536].End(xlUp).Row - 1 'so dong cua sheet
            EndC = .[X1].End(xlToLeft).Column
            Er2 = [A65536].End(xlUp).Row 'dong cuoi sh KQ
            '4 cot dau nhu nhau
            Range("A" & Er2 + 1 & ":D" & Er2 + RowCount).Value = .Range("A2:D" & RowCount + 1).Value
            k = 5
            For j = 5 To EndC '' so cot
                If Cells(1, k) <> .Cells(1, j) Then
                    k = k + 1
                End If
                If Cells(1, k) = .Cells(1, j) Then
                    Range("A" & Er2 + 1 & ":A" & Er2 + RowCount).Offset(0, k - 1).Value = .Range("A2:A" & RowCount + 1).Offset(0, j - 1).Value
                    k = k + 1
                End If
            Next j
        End With
    End If
Next i
With Application
    .DisplayAlerts = True
    .ScreenUpdating = True
End With
End Sub
 
Upvote 0
Code của ThuNghi "quên" End Sub và quên "nháy" ở chổ For j = 5 To EndC 'so cot
Coi chừng bà con "la làng" vì chạy ko dc!
He... he...
 
Upvote 0
.Cells(2, j).Resize(Er1 - 1, 1).Copy Destination:=Cells(Er2, K)/QUOTE]
Theo tôi không cần dùng copy và dán.
Bạn test lại các Er trong dòng sau.
range(Cells(Er2, K),Cells(Er2+Er1, K)).value=.range(Cells(2, k),cell(Er1 + 1, k)).value

À, mà sao không làm luôn ra cái báo cáo luôn mà phải PiVot nhỉ! Mất công quá, Bác Tuấn chế tiếp luôn.
 
Upvote 0
.Cells(2, j).Resize(Er1 - 1, 1).Copy Destination:=Cells(Er2, K)/QUOTE]
Theo tôi không cần dùng copy và dán.
Bạn test lại các Er trong dòng sau.
range(Cells(Er2, K),Cells(Er2+Er1, K)).value=.range(Cells(2, k),cell(Er1 + 1, k)).value
OK! Tôi cũng định làm vậy! Nhưng vì muốn giữ nguyên định dạng gốc ở các sheet nên đành phải dán cho chắc ăn!
--------------------
Ah! Code của ThuNghi vẩn chưa có khả năng nhận dạng tiêu đề cột ở các sheet khi nó bị thay đổi vị trí lộn xộn nha!
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom