Nhờ rút gon code

Liên hệ QC

Ronaldinho7

Zl: 0707315985
Tham gia
5/4/22
Bài viết
186
Được thích
204
Xin chào Anh/Chị
Theo yêu cầu của 1 bạn @tieuanhkiet xuất dữ liệu từ sheet tổng ra các sheet con (theo nhà cung cấp), mình có code bên dưới.
Code cho ra kết quả nhưng hình như bị dườm dà.
Nhờ Anh/Chị hướng dẫn cách rút gọn Code mà vẫn đảm bảo được kết quả.
Rất cảm ơn Anh/Chị
Trân trọng!
Mã:
Option Explicit
Sub Chia_Ncc_1() '1 sheet
Dim Ws As Worksheet, Dict As Object, a&, b&, Ncc$, f&
Dim i&, j&, k&, Lr&, Lrs&, Arr(), Res(), Str$, l&
Set Dict = CreateObject("Scripting.Dictionary")
Application.ScreenUpdating = False
On Error Resume Next
l = Sheets.Count
For Each Ws In Worksheets
    If l > 1 And Ws.Name <> "NhapVatTu" Then
        Ws.Delete
    End If
    Application.DisplayAlerts = False
Next
With Sheet1
    Lr = .Range("B" & Rows.Count).End(xlUp).Row
    Arr = .Range("A3:I" & Lr).Value
    For i = 2 To Lr - 2
        If Str <> Arr(i, 2) And Not Dict.exists(Arr(i, 2)) Then
            Dict.Add Arr(i, 2), i
            Str = Arr(i, 2)
            Worksheets.Add after:=Sheet1
            ActiveSheet.Name = Str
            Range("A1:C1").Value = .Range("A3:C3").Value
            Range("D1:H1").Value = .Range("e3:I3").Value
            Range("A1:H1").Font.Bold = True
        End If
    Next i
End With
For Each Ws In Worksheets
    If Ws.Name <> "NhapVatTu" Then
        ReDim Res(1 To UBound(Arr), 1 To 8)
        For a = 2 To UBound(Arr)
            If Arr(a, 2) = Ws.Name Then
            f = f + 1
                For b = 1 To 3
                    Res(f, b) = Arr(a, b)
                Next b
                For j = 4 To 8
                    Res(f, j) = Arr(a, j + 1)
                Next j
            End If
        Next a
        End If
        If Ws.Name <> "NhapVatTu" Then
        Ws.Range("A2").Resize(UBound(Arr), 8).Value = Res
        Lrs = Ws.Range("B" & Rows.Count).End(xlUp).Row
        Ws.Range("A2:A" & Lrs).NumberFormat = "m/d/yyyy"
        Ws.Range("A1:H" & Lrs).Borders.LineStyle = xlContinuous
    End If
    f = 0
Next
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Set Dict = Nothing
Ws = Nothing
End Sub
 

File đính kèm

  • so nhap vat lieu.xlsx
    16.2 KB · Đọc: 9
Cảm ơn bạn đã quan tâm vấn đề của mình!
 
Upvote 0
Gọn cũng chưa chắc ngon, có khi nó dài nhưng tốc độ nó nhanh thì sao? Trong khi nó ngắn mà tốc độ xử lý nó chậm thì cũng vứt bỏ thôi.
Mã:
Option Explicit

Sub Chia_Ncc_1()
Dim Dict As Object, Ws As Worksheet
Dim i&, j&, Lr&, Arr(), l&
Set Dict = CreateObject("Scripting.Dictionary")
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'On Error Resume Next
l = Sheets.Count
If l > 1 Then
    Sheets(2).Select
    For Each Ws In Worksheets
        If Ws.Name <> "NhapVatTu" Then
            Ws.Select False
        End If
    Next
    ActiveWindow.SelectedSheets.Delete
End If

With Sheet1
    Lr = .Range("B" & Rows.Count).End(xlUp).Row
    Arr = .Range("B4:B" & Lr).Value
    [L1] = [B3]
    For i = 1 To UBound(Arr)
        If Not Dict.exists(Arr(i, 1)) Then
            Dict.Add Arr(i, 1), i
            .Range("L2").Value2 = Arr(i, 1)
            Worksheets.Add after:=Sheet1
            ActiveSheet.Name = Arr(i, 1)
            .Range("A3:I13").AdvancedFilter Action:=xlFilterCopy, _
                            CriteriaRange:=.Range("L1:L2"), _
                            CopyToRange:=ActiveSheet.Range("A1:I1")
            ActiveSheet.Columns("A:I").EntireColumn.AutoFit
            ActiveSheet.Columns("D:D").Delete Shift:=xlToLeft
        End If
    Next i
    .Range("L1:L2").Delete
End With
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Set Dict = Nothing
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Code kia gọn gàng thế kia mà còn muốn tối ưu ạ
Tự giải thuật thớt đã "dườm dà" từ đầu.

Bởi dân GPE bị "vía" cái Đít dần nặng quá cho nên việc gì cũng nghĩ đến nó. Thế là không chịu học qua các giải thuật khác.

Nguyên tắc của bài toán phân loại là SẮP XẾP chứ không phải LỌC DUY NHẤT.

Bài này chỉ cần sort theo mã. Đọc từ trên xuống, cứ mỗi mã mới thì lại cóp qua bảng mới. Hết.
 
Upvote 0
Tự giải thuật thớt đã "dườm dà" từ đầu.

Bởi dân GPE bị "vía" cái Đít dần nặng quá cho nên việc gì cũng nghĩ đến nó. Thế là không chịu học qua các giải thuật khác.

Nguyên tắc của bài toán phân loại là SẮP XẾP chứ không phải LỌC DUY NHẤT.

Bài này chỉ cần sort theo mã. Đọc từ trên xuống, cứ mỗi mã mới thì lại cóp qua bảng mới. Hết.
Cảm ơn bác đã chỉ bảo.
Nhưng nếu như vậy để không phá vỡ cấu trúc nguồn ban đầu thì phải copy (nguồn) sang sheet khác thực thi lệnh rồi xoá sheet mới tạo hả bác hay có cách nào khác mong bác hướng dẫn.
 
Upvote 0
Cảm ơn bác đã chỉ bảo.
Nhưng nếu như vậy để không phá vỡ cấu trúc nguồn ban đầu thì phải copy (nguồn) sang sheet khác thực thi lệnh rồi xoá sheet mới tạo hả bác hay có cách nào khác mong bác hướng dẫn.
1. Ở GPE này có cả đống bài nói về sắp xếp mảng 2 chiều. không cần phải sort qua sheet tạm.
2. Xóa sheet. Code của bạn xóa cả đống sheets. So sánh với dựng và xóa một cái sheet tạm có gì phải ngại?
 
Upvote 0
1. Ở GPE này có cả đống bài nói về sắp xếp mảng 2 chiều. không cần phải sort qua sheet tạm.
2. Xóa sheet. Code của bạn xóa cả đống sheets. So sánh với dựng và xóa một cái sheet tạm có gì phải ngại?
Vâng, vụ sắp xếp mảng 2 chiều em chưa gặp nên không có kinh nghiệm
Để em tìm hiểu thêm nhé!
 
Upvote 0
Giải thuật căn bản:

1. Sắp xếp bảng theo mã.
2. Bắt đầu từ dòng đầu tiên
3. Đọc mã cho đến khi gặp mã khác.
4. Cóp py cả cụm sang sheet mới. Xóa bớt cột nếu cần.
5. Bắt đầu từ dòng mã mới.
6. Tiếp tục lại bước 3 cho đến hết bảng.

Giải thuật có mẹo:

1. Sắp xếp bảng theo mã.
2. Set range là cả bảng.
3. Đọc mã của dòng đầu tiên trong range
4. Cộng Char(255) vào mã. Dùng hàm Match để dò gần đúng.
(i) hàm match dò gần đúng là dò nhị phân, gặp bẳng có sắp xếp nó dò rất nhanh.
(ii) vì dò có ký tự cuối là 255 (lớn hơn mã) cho nên Match sẽ trả về vị trí của dòng cuối cùng của mã.
5. Với dòng đầu tiên và dòng cuối, cóp py đoạn range ấy sang sheet mới. Xóa bớt cột nếu cần.
6. Set range ở dòng kế tiếp.
7. Tiếp tục lại bước 3 cho đến hết bảng.

Tuy nhiên, đấy là tôi mách cho kỹ thuật phân mã bằng cách sắp xếp thôi. Cách tốt nhất vẫn là Advanced Filter (code bài #6)
 
Upvote 0
Giải thuật căn bản:

1. Sắp xếp bảng theo mã.
2. Bắt đầu từ dòng đầu tiên
3. Đọc mã cho đến khi gặp mã khác.
4. Cóp py cả cụm sang sheet mới. Xóa bớt cột nếu cần.
5. Bắt đầu từ dòng mã mới.
6. Tiếp tục lại bước 3 cho đến hết bảng.

Giải thuật có mẹo:

1. Sắp xếp bảng theo mã.
2. Set range là cả bảng.
3. Đọc mã của dòng đầu tiên trong range
4. Cộng Char(255) vào mã. Dùng hàm Match để dò gần đúng.
(i) hàm match dò gần đúng là dò nhị phân, gặp bẳng có sắp xếp nó dò rất nhanh.
(ii) vì dò có ký tự cuối là 255 (lớn hơn mã) cho nên Match sẽ trả về vị trí của dòng cuối cùng của mã.
5. Với dòng đầu tiên và dòng cuối, cóp py đoạn range ấy sang sheet mới. Xóa bớt cột nếu cần.
6. Set range ở dòng kế tiếp.
7. Tiếp tục lại bước 3 cho đến hết bảng.

Tuy nhiên, đấy là tôi mách cho kỹ thuật phân mã bằng cách sắp xếp thôi. Cách tốt nhất vẫn là Advanced Filter (code bài #6)
Cảm ơn bác đã chia sẻ.
Em cộng chr(255) vào mã nhà cung cấp, rồi dùng Match() nhưng cho kết quả là 9 (theo file mẫu trên). Em vẫn chưa thấy được logic ở phần này.
Bác có thể nói chi tiết hơn để em mục sở thị được không nhỉ?!
 
Upvote 0
Web KT

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

Back
Top Bottom