Tách 1 sheet thành nhiều sheet theo điều kiện

Liên hệ QC

nguyendinhtutw

Thành viên chính thức
Tham gia
17/4/17
Bài viết
73
Được thích
3
Giới tính
Nam
Dear các bác,
Em có 1 file excel như đính kèm, bây giờ em muốn tách sheet "Tong hop" thành các sheet (tạm gọi là "sheet con") dựa theo tên của người quản lý sao cho:
- Khi thay đổi nội dung ở các sheet con (Chỉnh sửa nội dung trong cell, insert/delete dòng) thì sheet "Tong hop" cũng thay đổi theo.
Các bác giúp em với ạ. Em cảm ơn các bác!
Trân trọng,
 

File đính kèm

  • Sample 1.xlsx
    9.6 KB · Đọc: 100
Nên chăng tách từ Sheet 'TongHop' vô 1 trang chi tiết; Nhưng thể hiện 'Người quản lí' nào đó mà bạn muốn;
 
Upvote 0
1. Chuyện tách sheet TongHop thành các sheet con là đơn giản. Như vậy các sheet con đều có cùng khuôn dạng. Chương trình này chỉ cần làm 1 lần.
2. Mỗi khi thay đổi nội dung ở các sheet con ( Chỉnh sửa nội dung trong cell, insert/delete dòng) thì sheet "Tong hop" cũng thay đổi theo thì làm theo sơ đồ sau
a. Lập sự kiện Worksheet_Activate cho TongHop (viết code cho sự kiện này, gồm 2 mục sau)
b. Xóa nội dung của TongHop
c. Chép nội dung mọi sheet con về sheet TongHop.
 
Upvote 0
1. Chuyện tách sheet TongHop thành các sheet con là đơn giản. Như vậy các sheet con đều có cùng khuôn dạng. Chương trình này chỉ cần làm 1 lần.
2. Mỗi khi thay đổi nội dung ở các sheet con ( Chỉnh sửa nội dung trong cell, insert/delete dòng) thì sheet "Tong hop" cũng thay đổi theo thì làm theo sơ đồ sau
a. Lập sự kiện Worksheet_Activate cho TongHop (viết code cho sự kiện này, gồm 2 mục sau)
b. Xóa nội dung của TongHop
c. Chép nội dung mọi sheet con về sheet TongHop.
Em cảm ơn bác, bác có thể giúp em đoạn code này không? em cũng đang tìm hiểu trên mạng nhưng em còn quá yếu về VBA nên chưa thể tự làm được việc này. Em cảm ơn!
 
Upvote 0
OK. Giờ hơi muộn. Lo công việc đã. Có thể tối nay hoặc mai
 
Upvote 0
1. Chuyện tách sheet TongHop thành các sheet con là đơn giản. Như vậy các sheet con đều có cùng khuôn dạng. Chương trình này chỉ cần làm 1 lần.
2. Mỗi khi thay đổi nội dung ở các sheet con ( Chỉnh sửa nội dung trong cell, insert/delete dòng) thì sheet "Tong hop" cũng thay đổi theo thì làm theo sơ đồ sau
a. Lập sự kiện Worksheet_Activate cho TongHop (viết code cho sự kiện này, gồm 2 mục sau)
b. Xóa nội dung của TongHop
c. Chép nội dung mọi sheet con về sheet TongHop.

Mục b, và c cứ làm thế thôi, chứ không biết chính xác được sheet con có chỉnh sửa hay không phải không Anh.
 
Upvote 0
1. Chuyện tách sheet TongHop thành các sheet con là đơn giản. Như vậy các sheet con đều có cùng khuôn dạng. Chương trình này chỉ cần làm 1 lần.
2. Mỗi khi thay đổi nội dung ở các sheet con ( Chỉnh sửa nội dung trong cell, insert/delete dòng) thì sheet "Tong hop" cũng thay đổi theo thì làm theo sơ đồ sau
a. Lập sự kiện Worksheet_Activate cho TongHop (viết code cho sự kiện này, gồm 2 mục sau)
b. Xóa nội dung của TongHop
c. Chép nội dung mọi sheet con về sheet TongHop.

Mình triển khai ý thứ b và c của Anh. các bạn hỗ trợ ý a nhé.

PHP:
Private Sub Worksheet_Activate()
    Dim Wks As Worksheet
    Range("A3:G10000").ClearContents
    For Each Wks In Worksheets
        If Wks.Name <> "Tong hop" Then
            Wks.Range("A3", Wks.Range("C60000").End(xlUp)).Resize(, 5).Copy
            Sheets("Tong hop").Range("C60000").End(xlUp).Offset(1, -2).PasteSpecial xlPasteValues
        End If
    Next Wks
End Sub
 

File đính kèm

  • Copy of Sample 1.xlsb
    18 KB · Đọc: 122
Upvote 0
Dear các bác,
Em có 1 file excel như đính kèm, bây giờ em muốn tách sheet "Tong hop" thành các sheet (tạm gọi là "sheet con") dựa theo tên của người quản lý sao cho:
- Khi thay đổi nội dung ở các sheet con (Chỉnh sửa nội dung trong cell, insert/delete dòng) thì sheet "Tong hop" cũng thay đổi theo.
Các bác giúp em với ạ. Em cảm ơn các bác!
Trân trọng,
Mình tách ra như File đính kèm.
Code em viết còn lung tung quá, các anh chị giúp em thay đổi với.
Ý tưởng của Em thế này.
- Em cho cột Họ và Tên vào 1 đối tượng Dictionary
- Em duyệt một mảng lấy từng dòng họ và Tên so với Họ và tên đã lưu trong Dictionary
- Sau khi so ra kết quả, Em Add vào một mảng mới
- Add new sheet, để dán cái mảng đó xuống bảng tính.

Mã:
Sub SplitSheet()
    Dim Dic As New Dictionary
    Dim sFullName(), dFullName()
    Dim i As Integer, j As Integer, k As Integer, m As Integer, n As Integer
    sFullName = Sheets("Tonghop").Range("A3:G20").Value
    ReDim dFullName(1 To UBound(sFullName, 1), 1 To UBound(sFullName, 2))
    '----------------------------------------------------------------------
    For i = 1 To UBound(sFullName, 1)
        If Not Dic.Exists(sFullName(i, 3)) Then
            Dic.Add sFullName(i, 3), ""
        End If
    Next i
    '----------------------------------------------------------------------
    For j = 1 To Dic.Count
        For k = 1 To UBound(sFullName, 1)
            If sFullName(k, 3) = Dic.Keys()(j - 1) Then
                m = m + 1
                For n = 1 To 7
                    dFullName(m, n) = sFullName(k, n)
                Next n
            End If
        Next k
       Worksheets.Add After:=Sheets("Tonghop")
       ActiveSheet.Range("A3").Resize(18, 7) = dFullName
       ReDim dFullName(1 To UBound(sFullName, 1), 1 To UBound(sFullName, 2))
       k = 0: m = 0: n = 0
    Next j
End Sub
 

File đính kèm

  • Sample 1.xlsb
    23.3 KB · Đọc: 96
Upvote 0
Mình tách ra như File đính kèm.
Code em viết còn lung tung quá, các anh chị giúp em thay đổi với.
Ý tưởng của Em thế này.
- Em cho cột Họ và Tên vào 1 đối tượng Dictionary
- Em duyệt một mảng lấy từng dòng họ và Tên so với Họ và tên đã lưu trong Dictionary
- Sau khi so ra kết quả, Em Add vào một mảng mới
- Add new sheet, để dán cái mảng đó xuống bảng tính.

Mã:
Sub SplitSheet()
    Dim Dic As New Dictionary
    Dim sFullName(), dFullName()
    Dim i As Integer, j As Integer, k As Integer, m As Integer, n As Integer
    sFullName = Sheets("Tonghop").Range("A3:G20").Value
    ReDim dFullName(1 To UBound(sFullName, 1), 1 To UBound(sFullName, 2))
    '----------------------------------------------------------------------
    For i = 1 To UBound(sFullName, 1)
        If Not Dic.Exists(sFullName(i, 3)) Then
            Dic.Add sFullName(i, 3), ""
        End If
    Next i
    '----------------------------------------------------------------------
    For j = 1 To Dic.Count
        For k = 1 To UBound(sFullName, 1)
            If sFullName(k, 3) = Dic.Keys()(j - 1) Then
                m = m + 1
                For n = 1 To 7
                    dFullName(m, n) = sFullName(k, n)
                Next n
            End If
        Next k
       Worksheets.Add After:=Sheets("Tonghop")
       ActiveSheet.Range("A3").Resize(18, 7) = dFullName
       ReDim dFullName(1 To UBound(sFullName, 1), 1 To UBound(sFullName, 2))
       k = 0: m = 0: n = 0
    Next j
End Sub
Cảm ơn phuyen89, tuy nhiên, sau khi xem file của bác em thấy có các vấn đề sau:
- Khi click commandbutton nhiều lần thì sheet cũng bị tách theo từng đó lần.
- Khi chỉnh sửa giữ liệu trên các Sheet con thì Sheet "Tonghop" chưa được cập nhật.
 
Upvote 0
Cảm ơn phuyen89, tuy nhiên, sau khi xem file của bác em thấy có các vấn đề sau:
- Khi click commandbutton nhiều lần thì sheet cũng bị tách theo từng đó lần.
- Khi chỉnh sửa giữ liệu trên các Sheet con thì Sheet "Tonghop" chưa được cập nhật.

+ Mình tiến hành Xoá Sheet trước khi Tạo ra.
PHP:
Private Sub Delete_Sheet()
    Application.DisplayAlerts = True
    Dim Wks As Worksheet
    For Each Wks In Worksheets
        If Wks.Name <> "Tonghop" Then
            Wks.Delete
        End If
    Application.DisplayAlerts = False
    Next Wks
End Sub
 

File đính kèm

  • Copy of Sample 1.xlsb
    21.9 KB · Đọc: 41
Upvote 0
- Click thì phải biết tự lượng sức. Click rồi thì đừng Click nữa??? Tại sao không kiểm soát mình làm những gì?
- Không ai làm 2 chiều. 1 là Sheet Tổng Hợp chuẩn -> Tách ra sheet con. 2 là Các sheet con có sẵn (và là chuẩn) -> Chạy code dữ liệu sẽ tổng hợp về sheet Tổng Hợp.
Coi chừng làm kiểu nữa vời 2 chiều có ngày ăn "Hành" đó...

Ghi chú: tôi chỉ góp ý, chứ không biết làm nha!
Cảm ơn bác, nhưng em lưu ý là việc tách này chỉ làm 1 lần, để áp dụng cho dữ liệu hiện đã có sẵn trong sheet "tonghop", kể từ sau này thì sẽ không cập nhật dữ liệu mới trực tiếp vào sheet "tong hop" nữa, mà việc này sẽ được thực hiện thông qua việc cập nhật ở các Sheet con
 
Upvote 0
Cảm ơn bác, nhưng em lưu ý là việc tách này chỉ làm 1 lần, để áp dụng cho dữ liệu hiện đã có sẵn trong sheet "tonghop", kể từ sau này thì sẽ không cập nhật dữ liệu mới trực tiếp vào sheet "tong hop" nữa, mà việc này sẽ được thực hiện thông qua việc cập nhật ở các Sheet con
1 sheet TONGHOP, muốn tìm người nào thì Auto Filter người đó, nhập thêm dữ liệu hay xóa dòng "mút chỉ", Sort lại 1 phát là "gom".
 
Upvote 0
Em có tìm hiểu được trên mạng và làm được bảng như đính kèm, tuy nhiên mới chỉ tách được tiêu đề, chưa tách được nội dung, các bác xem giúp em xem đang bị sai chỗ nào với ạ.
 

File đính kèm

  • Sample 1.xlsm
    22.7 KB · Đọc: 19
Upvote 0
Cảm ơn bác, nhưng em lưu ý là việc tách này chỉ làm 1 lần, để áp dụng cho dữ liệu hiện đã có sẵn trong sheet "tonghop", kể từ sau này thì sẽ không cập nhật dữ liệu mới trực tiếp vào sheet "tong hop" nữa, mà việc này sẽ được thực hiện thông qua việc cập nhật ở các Sheet con
Tôi thấy cảnh bảo của @hpkhuong không sai đâu, bạn đang làm ngược đấy.
Bạn nên dùng sheets Tổng hợp để theo dõi mọi số liệu, sau mỗi lần thay đổi số liệu, bạn cập nhật lại vào các Sheet con là cách hay hơn.
Tôi sẽ làm qua các bước sau:
- Bước 1: Dùng lệnh Offset để tạo Name động cho vùng dữ liệu của Bảng tổng hợp
- Bước 2: Tạo 1 sheet PivotTable để tạo Pivot Table
- Bước 3: Dùng code của @kyo để bảng Pivot Table có thể tự động cập nhật khi dữ liệu nguồn thay đổi
- Bước 4: Dùng code của @be09 để tách sheets theo Pivot Table
Khi dữ liệu ở Sheet Tong hop thay đổi, bạn click lại nút Tách Sheets là các dữ liệu con sẽ thay đổi theo
Bạn xem file đính kèm nhé!
 

File đính kèm

  • Sample 1.xlsm
    34.7 KB · Đọc: 106
Upvote 0
1. Chạy code này để tách (chạy 1 lần đầu thôi).
Mã:
Public Sub Tach_Sheet()
Dim Dic As Object, Tmp, I As Long, K As Long, sArr, Rng As Range, Ws As Worksheet
Application.ScreenUpdating = False
Application.DisplayAlerts = False
On Error Resume Next
For Each Ws In Worksheets
    If Ws.Name <> "Tong hop" Then Ws.Delete
Next
sArr = Range("C3", Range("C3").End(4)).Value
Set Rng = Range("A2").CurrentRegion
Set Dic = CreateObject("Scripting.Dictionary")
    For I = 1 To UBound(sArr)
    If sArr(I, 1) <> Empty Then
    Tmp = sArr(I, 1)
        If Not Dic.exists(Tmp) Then
            Dic.Add Tmp, ""
            Rng.AutoFilter 3, Tmp
            Sheets.Add After:=Sheets(Sheets.Count)
            Sheets(Sheets.Count).Name = Tmp
            Rng.SpecialCells(12).Copy
            Sheets(Tmp).Range("A2").PasteSpecial 8
            Sheets(Tmp).Range("A2").PasteSpecial xlPasteAll
        End If
    End If
    Next
Sheet1.Activate
Sheet1.ShowAllData
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub

2. Code này copy vào sheet "Tong hop". Cập nhật dữ liệu ở sheet con sẽ tự động chạy về tổng hợp

Mã:
Private Sub Worksheet_Activate()
Dim sArr, dArr(1 To 65000, 1 To 7), I As Long, J As Long, K As Long, Ws As Worksheet
Application.ScreenUpdating = False
For Each Ws In Worksheets
    If Ws.Name <> "Tong hop" Then
        sArr = Ws.Range("A2").CurrentRegion.Value
        For I = 2 To UBound(sArr)
            K = K + 1
            dArr(K, 1) = K
            For J = 2 To 7
                dArr(K, J) = sArr(I, J)
            Next
        Next
    End If
Next
If K Then
With Sheets("Tong hop")
    .Range("A2").CurrentRegion.Offset(1).Borders.LineStyle = 0
    .Range("A2").CurrentRegion.Offset(1).ClearContents
    .Range("A3").Resize(K, 7).Value = dArr
    .Range("A3").Resize(K, 7).Borders.LineStyle = 1
End With
End If
Application.ScreenUpdating = True
End Sub
Em cảm ơn bác, chúc bác 1 ngày tốt lành :D
 
Upvote 0
1. Chạy code này để tách (chạy 1 lần đầu thôi).
Mã:
Public Sub Tach_Sheet()
Dim Dic As Object, Tmp, I As Long, K As Long, sArr, Rng As Range, Ws As Worksheet
Application.ScreenUpdating = False
Application.DisplayAlerts = False
On Error Resume Next
For Each Ws In Worksheets
    If Ws.Name <> "Tong hop" Then Ws.Delete
Next
sArr = Range("C3", Range("C3").End(4)).Value
Set Rng = Range("A2").CurrentRegion
Set Dic = CreateObject("Scripting.Dictionary")
    For I = 1 To UBound(sArr)
    If sArr(I, 1) <> Empty Then
    Tmp = sArr(I, 1)
        If Not Dic.exists(Tmp) Then
            Dic.Add Tmp, ""
            Rng.AutoFilter 3, Tmp
            Sheets.Add After:=Sheets(Sheets.Count)
            Sheets(Sheets.Count).Name = Tmp
            Rng.SpecialCells(12).Copy
            Sheets(Tmp).Range("A2").PasteSpecial 8
            Sheets(Tmp).Range("A2").PasteSpecial xlPasteAll
        End If
    End If
    Next
Sheet1.Activate
Sheet1.ShowAllData
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub

2. Code này copy vào sheet "Tong hop". Cập nhật dữ liệu ở sheet con sẽ tự động chạy về tổng hợp

Mã:
Private Sub Worksheet_Activate()
Dim sArr, dArr(1 To 65000, 1 To 7), I As Long, J As Long, K As Long, Ws As Worksheet
Application.ScreenUpdating = False
For Each Ws In Worksheets
    If Ws.Name <> "Tong hop" Then
        sArr = Ws.Range("A2").CurrentRegion.Value
        For I = 2 To UBound(sArr)
            K = K + 1
            dArr(K, 1) = K
            For J = 2 To 7
                dArr(K, J) = sArr(I, J)
            Next
        Next
    End If
Next
If K Then
With Sheets("Tong hop")
    .Range("A2").CurrentRegion.Offset(1).Borders.LineStyle = 0
    .Range("A2").CurrentRegion.Offset(1).ClearContents
    .Range("A3").Resize(K, 7).Value = dArr
    .Range("A3").Resize(K, 7).Borders.LineStyle = 1
End With
End If
Application.ScreenUpdating = True
End Sub
Dear bác hpkhuong,
Theo code của bác thì lúc tách file sẽ xóa toàn bộ các sheet khác, chỉ để lại sheet "tonghop", nhưng file thực tế em đang thực hiện có 1 sheet ( tạm gọi là Sheet A) không thể xóa đi được, việc này em có thể sửa code để lúc tách file sẽ không xóa sheet đó.
Nhưng một vấn đề nảy sinh khi tổng hợp dữ liệu từ các sheet con về sheet "tonghop", có thể sửa code của bác như thế nào để không cho dữ liệu từ Sheet A nhảy về sheet "tonghop' được không?
Em cảm ơn bác!
 
Upvote 0
Bạn biết sửa code -> bạn tự xử được mà.
Nếu sheet tạm của bạn ít thì bạn có thể xem câu lệnh trong code để loại trừ nó. Trường hợp sheet tạm nhiều thì:
->Vậy bạn phải có 1 danh sách tên những sheet cần tổng hợp về sheet tổng hợp. Và dùng vòng lặp duyệt danh sách này. Nếu thỏa thì lấy về tổng hợp.
Lúc tách sheet, em có sửa đoạn code như sau:
If Ws.Name <> "Tong hop" and Ws.Name <> "SheetA" Then Ws.Delete
em đã thử và thấy vẫn tách được sheet và giữ được sheetA không bi xóa.
.....
Tuy nhiên, với tư duy tương tự khi sửa code để cho dữ liệu nhảy từ các sheet con về thì file tổng hợp bị lộn xộn rất nhiều:
If Ws.Name <> "Tong hop" and Ws.Name <> "SheetA" Then
 
Upvote 0
Bạn biết sửa code -> bạn tự xử được mà.
Nếu sheet tạm của bạn ít thì bạn có thể xem câu lệnh trong code để loại trừ nó. Trường hợp sheet tạm nhiều thì:
->Vậy bạn phải có 1 danh sách tên những sheet cần tổng hợp về sheet tổng hợp. Và dùng vòng lặp duyệt danh sách này. Nếu thỏa thì lấy về tổng hợp.
Như file đính kèm em đã tách được file theo code của bác, tuy nhiên khi áp dụng code như bên dưới để cho dữ liệu từ sheet con tự tổng hợp về sheet "tonghop" thì không được:
Private Sub Worksheet_Activate()
Dim sArr, dArr(1 To 65000, 1 To 45), I As Long, J As Long, K As Long, Ws As Worksheet
Application.ScreenUpdating = False
For Each Ws In Worksheets
If Ws.Name <> "TH Hop dong" and Ws.Name <> "Drop" Then
sArr = Ws.Range("A3").CurrentRegion.Value
For I = 2 To UBound(sArr)
K = K + 1
dArr(K, 1) = K
For J = 2 To 45
dArr(K, J) = sArr(I, J)
Next
Next
End If
Next
If K Then
With Sheets("TH Hop dong")
.Range("A3").CurrentRegion.Offset(1).Borders.LineStyle = 0
.Range("A3").CurrentRegion.Offset(1).ClearContents
.Range("A4").Resize(K, 45).Value = dArr
.Range("A4").Resize(K, 45).Borders.LineStyle = 1
End With
End If
Application.ScreenUpdating = True
End Sub
 

File đính kèm

  • DEV333.xlsm
    216.5 KB · Đọc: 46
Upvote 0
Mã:
Public Sub Tach_Sheet()
Dim Dic As Object, Tmp, I As Long, K As Long, sArr, Rng As Range, Ws As Worksheet
Application.ScreenUpdating = False
Application.DisplayAlerts = False
On Error Resume Next
For Each Ws In Worksheets
    If Ws.Name <> "TH Hop dong" And Ws.Name <> "Drop" Then Ws.Delete
Next
Set Rng = Sheet1.UsedRange
sArr = Rng.Value
Set Dic = CreateObject("Scripting.Dictionary")
    For I = 4 To UBound(sArr)
    If sArr(I, 4) <> Empty Then
    Tmp = sArr(I, 4)
        If Not Dic.exists(Tmp) Then
            Dic.Add Tmp, ""
            Rng.Offset(3).AutoFilter 4, Tmp
            Sheets.Add After:=Sheets(Sheets.Count)
            Sheets(Sheets.Count).Name = Tmp
            Rng.SpecialCells(12).Copy
            Sheets(Tmp).Range("A1").PasteSpecial 8
            Sheets(Tmp).Range("A1").PasteSpecial xlPasteAll
        End If
    End If
    Next
Sheet1.Activate
Sheet1.ShowAllData
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub

Mã:
Private Sub Worksheet_Activate()
Dim sArr, dArr(1 To 65000, 1 To 45), I As Long, J As Long, K As Long, Ws As Worksheet
Application.ScreenUpdating = False
For Each Ws In Worksheets
    If Ws.Name <> "TH Hop dong" And Ws.Name <> "Drop" Then
        sArr = Ws.UsedRange.Value
        For I = 4 To UBound(sArr)
        If Len(sArr(I, 4)) Then
            K = K + 1
            For J = 1 To 45
                dArr(K, J) = sArr(I, J)
            Next
        End If
        Next
    End If
Next
If K Then
With Sheets("TH Hop dong")
    .UsedRange.Offset(3).Borders.LineStyle = 0
    .UsedRange.Offset(3).ClearContents
    .Range("A4").Resize(K, 45).Value = dArr
    .Range("A4").Resize(K, 45).Borders.LineStyle = 1
End With
End If
Application.ScreenUpdating = True
End Sub
Em cảm ơn bác :D
 
Upvote 0
+ Mình tiến hành Xoá Sheet trước khi Tạo ra.
PHP:
Private Sub Delete_Sheet()
    Application.DisplayAlerts = True
    Dim Wks As Worksheet
    For Each Wks In Worksheets
        If Wks.Name <> "Tonghop" Then
            Wks.Delete
        End If
    Application.DisplayAlerts = False
    Next Wks
End Sub
Bổ sung. Có thể viết thêm code kiểm tra sheet tồn tại chưa. Nếu sheet đã tồn tại rồi thì phải làm gì....
 
Upvote 0
Web KT

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

Back
Top Bottom