TÁCH DỮ LIỆU TỪ 1 SHEET FILE EXCEL TỔNG THÀNH FILE EXCEL NHỎ (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Raito yagami

Thành viên mới
Tham gia
30/8/22
Bài viết
2
Được thích
0
Chào các anh chị, em có 1 số file excel khoangr 500 nghìn dòng giờ em muốn tách file đấy thành các file exel nhỏ hơn tối đa 9000 dòng từ trên xuống dưới, file excel gốc không có công thức chỉ có dữ liệu. Anh chị giúp em cách tách với
 
Có lẽ nên chỉnh lại nội quy cho rõ ràng hơn anh ạ.

Em chưa thấy chỗ nào yêu cầu cụ thể tiêu đề không được viết hoa toàn bộ.
Chính vì vậy nên chưa xử lý, chỉ thông báo để chủ đề tài sửa. Và đừng quên câu hỏi "siêu hàm"
 
Upvote 0
Có thể viết 1 siêu hàm dùng cho mọi file không?
------
Ở đây toàn là dân chữa cháy không hè.
Viết "xiêu hàm" rồi cũng xiêu. Chả ai thiết đến dùng lại.
1. Chủ quan: hàm không chú thích. Rất khó hiểu để áp dụng trong vấn đề khác. Tức là code không thuộc loại reusable.
2. Khách quan: có viết code reusable ở đây cũng uổng công. Người hỏi bài ở đây chỉ muốn làm giùm chứ đâu muốn giải thuật.

Xiêu hàm: tôi để ý dân GPE có truyền thống viết code "ba cây chụm lại - tháp luôn vào một gốc", và rất ngại chuyện gọi hàm con. Một vấn đề có cả chục Options mà dồn hết vô một hàm "dùng cho mội trường hợp". "Nên hòn núi cao" thì trông hùng vĩ thật. Nhưng bảo tôi lội đèo thì còn phya.
Theo đúng nguyên tắc lập trình là phải "chia để trị". Mỗi công việc một hàm con. Hàm lớn chỉ làm công việc chộn Option(s) mà gọi hàm con thôi, cùng lắm thì chứa phần chung. Nếu viết giỏi, ngay cả cái công việc chung cũng dồn lại, thêm một hàm con.
 
Upvote 0
Ở đây toàn là dân chữa cháy không hè.
Viết "xiêu hàm" rồi cũng xiêu. Chả ai thiết đến dùng lại.
1. Chủ quan: hàm không chú thích. Rất khó hiểu để áp dụng trong vấn đề khác. Tức là code không thuộc loại reusable.
2. Khách quan: có viết code reusable ở đây cũng uổng công. Người hỏi bài ở đây chỉ muốn làm giùm chứ đâu muốn giải thuật.
Riêng chủ đề này, siêu hàm (ý là siêu Sub) chỉ cần tách 1 file (đang đứng) thành nhiều file, mỗi file 9000 dòng. Siêu ở chỗ là dùng cho nhiều file cấu trúc khác nhau.
Thí dụ:
Mã:
Sub SplitFile ()
'Tìm dòng cuối cột cuối sheet chỉ định cứng rồi thực hiện
End Sub
hoặc
Mã:
Sub SplitFile (Sh as WorkSheet, SplitRws as long, NewFName as String)
'---- Tùy chọn sheet, tùy chọn số dòng tách, tùy chọn tên file sẽ lưu (hoặc thêm folder nếu thích)
End Sub
 
Upvote 0
Chào các anh chị, em có 1 số file excel khoangr 500 nghìn dòng giờ em muốn tách file đấy thành các file exel nhỏ hơn tối đa 9000 dòng từ trên xuống dưới, file excel gốc không có công thức chỉ có dữ liệu. Anh chị giúp em cách tách với
Tôi thử code và chạy hơn 501000 dòng tách thành 56 sheet hết 72s. hóng các phương án tối ưu hơn.
 
Upvote 0
Lần chỉnh sửa cuối:
Upvote 0
Tôi thử code và chạy hơn 501000 dòng tách thành 56 sheet hết 72s. hóng các phương án tối ưu hơn.
File hơn 500000 dòng và 15 cột. chạy code của anh Hai Lua Mien Tay hết 73,03125. Dù nén nhưng dung lượng lớn qua quy định không up lên được
Mã:
Sub Tach_1_SheetThanhNhieuSheet()
    Dim sh As Worksheet
    Dim SoSheet As Integer, i As Integer
    Dim tTime As Double
    
    Const SoDong = 9000
    
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    
    tTime = Timer

    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        While Not .EOF
            SoSheet = SoSheet + 1
            Set sh = Worksheets.Add
            sh.Name = "Sheet_" & SoSheet
            sh.Range("A3").CopyFromRecordset .DataSource, SoDong
        Wend
    End With

    Debug.Print Timer - tTime
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
    
    MsgBox "Done"
End Sub
 
Upvote 0
Tôi làm hầu hết công việc quan trọng đều có thể kiểm toán.
Tách 500000 dòng thì cũng phải có gì ghi lại quá trình?

Quá trình được ghi lại trong một sheet phụ để làm báo cáo. Chỉ cần 2 dòng: dòng tiêu đề và dòng số liệu.
Tên File Con Đề nghị | Tên File Con Được Ghi | Sao Từ Dòng | Sao đến dòng | Chú thích

Sub chính có nhiệm vụ chia dữ liệu, gọi sub con, chuyền:
- Range chứa dòng tiêu đề.
- Range chứa những dòng cần sao.
- Tên đề nghị cho file con
- Range để ghi báo cáo trong sheet phụ

Sub con có nhiệm vụ:
- Mở file mới. Nếu có vấn đề (file exists) thì thử bản (1), (2),...
- Chép tiêu đề và các dòng cần sao vào file mới.
- Đóng file mới.
- Ghi chi tiết vào báo cáo.
 
Upvote 0
File hơn 500000 dòng và 15 cột. chạy code của anh Hai Lua Mien Tay hết 73,03125.
Code dùng ADO thường chậm hơn mảng.
Nếu dùng mảng sẽ thường dùng lệnh gán như:
Mã:
Dim SourceArr()
SourceArr= Range1.Value
Range2.Value = SourceArr
Nếu bỏ qua mảng mà gán
Mã:
Range2.Value = Range1.Value
Thì còn nhanh hơn nữa vì bỏ qua trung gian mảng.
 
Upvote 0
Chào các anh chị, em có 1 số file excel khoangr 500 nghìn dòng giờ em muốn tách file đấy thành các file exel nhỏ hơn tối đa 9000 dòng từ trên xuống dưới, file excel gốc không có công thức chỉ có dữ liệu. Anh chị giúp em cách tách với
Thế bạn tách theo tiêu chí nào? Ngày tháng hay tên khách v.v.v.phải có file mẫu ae mới biết mà giúp chứ
 
Upvote 0
Thế bạn tách theo tiêu chí nào?

Người ta nêu rõ ràng thế còn hỏi tiêu chí nào nữa bạn?

1662003999577.png

Nghĩa là, cứ tách 9000 dòng thành 1 bảng, lưu thành 1 file.
Phần dư cuối cùng (nếu có) sau khi tách 9000 dòng thì lưu phần dư đó thành 1 file.

Cần file chỉ là xem cấu trúc dòng/ cột thế nào, xem cột nào để tham chiếu lấy dòng cuối, xem dòng nào để tham chiếu lấy cột cuối.
 
Upvote 0
... ae mới biết mà giúp chứ
Chỗ này là bạn hứa chứ chưa có "a" "e" gì hết nhé.
Thớt nhất định theo chính sách "lỳ". Không chịu sửa tiêu đề theo đề nghị của người khác

Vì vây, chúng tôi chỉ bàn bạc học hỏi với nhau là chính thôi. Cootrs kiếc là để mình họa giải thuật.

Việc giúp thớt hiện giờ là việc phụ.
 
Upvote 0
Code dùng ADO thường chậm hơn mảng.
Nếu dùng mảng sẽ thường dùng lệnh gán như:
Mã:
Dim SourceArr()
SourceArr= Range1.Value
Range2.Value = SourceArr
Nếu bỏ qua mảng mà gán
Mã:
Range2.Value = Range1.Value
Thì còn nhanh hơn nữa vì bỏ qua trung gian mảng.
Tôi thử 500800 dòng 15 cột dùng phương pháp copy và paste hết 10,3s
Mã:
...
Ws.Range......Copy Sh.range....
...
Paste ở đây là paste vào các Sheet cùng workbook với sheet gốc.
và nghĩ rằng số cột nhiều, ít không ảnh hưởng đến tốc độ code. Không biết suy nghĩ thế có đúng không. Anh PTM 0412 hoặc ai biết xin giải thích giùm, tôi xin được khai sáng.
Trân trọng
 
Lần chỉnh sửa cuối:
Upvote 0
Paste ở đây là paste vào các Sheet cùng workbook với sheet gốc.
Copy paste thành sheet mới thì nhanh hơn copy paste file mới, lưu (tên file mới) và đóng file mới đó.
Còn copy paste file mới so sánh với gán giá trị vào file mới (là code 20s của tôi) thì tôi chưa thử. Tuy vậy theo suy luận thì copy paste chậm hơn hoặc bằng chứ không nhanh hơn, ngoài ra sẽ còn vấn đề về clipboard (bộ nhớ tạm khi copy). Càng nhiều dòng, copy càng nhiều lần, càng hao tốn.
Cuối cùng thì: Nếu như nhanh chậm hơn một vài giây (19, 20 với 22, 23) thì tôi vẫn chọn gán giá trị, không chọn copy paste.
 
Upvote 0
Copy paste thành sheet mới thì nhanh hơn copy paste file mới, lưu (tên file mới) và đóng file mới đó.
Còn copy paste file mới so sánh với gán giá trị vào file mới (là code 20s của tôi) thì tôi chưa thử. Tuy vậy theo suy luận thì copy paste chậm hơn hoặc bằng chứ không nhanh hơn, ngoài ra sẽ còn vấn đề về clipboard (bộ nhớ tạm khi copy). Càng nhiều dòng, copy càng nhiều lần, càng hao tốn.
Cuối cùng thì: Nếu như nhanh chậm hơn một vài giây (19, 20 với 22, 23) thì tôi vẫn chọn gán giá trị, không chọn copy paste.
Cảm ơn anh đã khai sáng.
Tôi thử: tạo các Sheet trên cùng Workbook
Mã:
......
sh.Range("A3").Resize(SoDong, 15).Value = Ws.Cells(i, 1).Resize(SoDong, 15).Value
......
Chạy hết 73,515625s . Cũng có thể do máy tôi cấu hình thấp
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi thử 500800 dòng 15 cột dùng phương pháp copy và paste hết 10,3s
Mã:
...
Ws.Range......Copy Sh.range....
...
và nghĩ rằng số cột nhiều, ít không ảnh hưởng đến tốc độ code. Không biết suy nghĩ thế có đúng không. Anh PTM 0412 hoặc ai biết xin giải thích giùm, tôi xin được khai sáng.
Trân trọng
Copy nhiều đương nhiên có ảnh hưởng. Số cột nhiều đòi hỏi RAM phải nhiều. Chép lại là có khả năng vào Hard Disk. Mà vào HD thì còn tùy thuộc vào tốc độ của chúng.
Túm lại, cỡ chục giây không xác định được gì cả.

Chép vào nhiều files thì HD là chỗ quyết định. Code có thể chả làm gì được.

Chú thích:
Copy Range to Range là VBA dùng map bảng tính. Đương nhiên là nói sẽ nhanh hơn bất cứ gì khác.
Copy Range-Array-Range thì phải qua map range to array, rồi ngược lại. Hai lần map thì phải lâu hơn.
ADO phải qua data stream. Cung 2 lần, 1 lần stream vào recordset và một lần vào bảng tính. Tuy sau khi nó map được rồi thì cứ đổ stream nhưng cái phí tổn RAM của record set không phải là nhỏ.
Theo tôi thì cứ đưa cái range cho sub con nó ghi là dễ nhất. Nó ghi bằng cách nào thì chỉnh sửa ở đó, ghi thẳng, ghi gián tiếp qua array đều dễ chỉnh sửa. Sub mẹ chỉ việc phân range và chỉ tay thôi.
(ADO thì khong nên dùng sub con. Chuyển nhiều tham quá đâm lộn xộn)
 
Upvote 0
Bài này tách thành file thì copy sheet thành new book rồi xóa dòng là nhanh nhất. Không động chạm gì tới định dạng của bảng tính gốc cả.
Đã thấy sự tiện lợi của sub con chưa?
Sub con có thể quyết định chuyện này.

Tuy nhiên, nếu phải làm rất nhiều files (như thớt nói) thì đáng lẽ PowerShell là giải pháp tốt nhất.
 
Upvote 0
Tôi thử 500800 dòng 15 cột dùng phương pháp copy và paste hết 10,3s

Paste ở đây là paste vào các Sheet cùng workbook với sheet gốc.
Tôi đã thử code lại: (500 ngàn dòng x 15 cột)
- Copy paste sheet mới cùng file: Range1.Copy NewSh.[A1] : 4.8s
- Gán giá trị sheet mới cùng file: Range2.Value = Range1.Value 6.8s
-
Copy paste file mới, lưu file tên mới và đóng: Range1.Copy NewWb.ActiveSheet.[A1]: 19s
- Gán giá trị file mới, lưu file tên mới và đóng: Range2.Value = Range1.Value: 20s
Tôi thử: tạo các Sheet trên cùng Workbook

Chạy hết 73,515625s
Tôi hơi ngạc nhiên. Tạo các sheet trên cùng workbook (giữa copy paste và gán giá trị) sao lại chênh lệch thời gian gấp 7 lần như vậy? Nếu máy yếu thì theo 1 tỷ lệ tương đối sẽ khoảng 13 - 14s thôi chứ?
Có khi nào vòng lặp gán giá trị hoặc câu lệnh không khéo chăng?
 
Upvote 0
Tôi đã thử code lại: (500 ngàn dòng x 15 cột)
- Copy paste sheet mới cùng file: Range1.Copy NewSh.[A1] : 4.8s
- Gán giá trị sheet mới cùng file: Range2.Value = Range1.Value 6.8s
-
Copy paste file mới, lưu file tên mới và đóng: Range1.Copy NewWb.ActiveSheet.[A1]: 19s
- Gán giá trị file mới, lưu file tên mới và đóng: Range2.Value = Range1.Value: 20s

Tôi hơi ngạc nhiên. Tạo các sheet trên cùng workbook (giữa copy paste và gán giá trị) sao lại chênh lệch thời gian gấp 7 lần như vậy? Nếu máy yếu thì theo 1 tỷ lệ tương đối sẽ khoảng 13 - 14s thôi chứ?
Có khi nào vòng lặp gán giá trị hoặc câu lệnh không khéo chăng?
Tôi đã thử lại cả 3 cách : Chỉ dùng 1 vòng for để lấy dòng cuối
for i=2 to Lastrow step 9000 nhưng không hiểu sao mà vẫn cho kết quả đúng nhưng thời gian chạy code lại khác nhau nhiều như vậy
1/ Arr=Ws.Cells(i, 1).Resize(SoDong, 15).Value
Sh.range("A3").resize(sodong,15)=Arr ====> chạy hết 79,533203125s
2/ Ws.Cells(i, 1).Resize(SoDong, 15).Copy sh.Range("A3") ' chạy hêt 10,6171875s
3/ sh.Range("A3").Resize(SoDong, 15).Value = Ws.Cells(i, 1).Resize(SoDong, 15).Value ' chạy hêt 69,126953125 s
Mã:
Sub Tach_1_SheetThanhNhieuSheet()

    Dim sh As Worksheet, Ws As Worksheet   
    Dim SoSheet As Integer, i As Long, Lr As Long
    Dim tTime As Double
 '   Dim Rng As Range
 '   Dim Arr()

    Const SoDong = 9000
    
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    
    tTime = Timer
    Set Ws = Sheets("Sheet1")
    Lr = Ws.Cells(Rows.Count, 1).End(xlUp).Row
    For i = 2 To Lr Step SoDong
'      Arr = Ws.Cells(i, 1).Resize(SoDong, 15).Value
            SoSheet = SoSheet + 1
            Set sh = Worksheets.Add
            sh.Name = "Sheet_" & SoSheet
            sh.Cells(1, 1) = sh.Name
            Ws.Range("A1:O1").Copy sh.Range("A2")
'          sh.Range("A3").Resize(SoDong, 15).Value = Arr      ' chay hêt 79,533203125s
'           Ws.Cells(i, 1).Resize(SoDong, 15).Copy sh.Range("A3")   ' chay hêt 10,6171875s
            sh.Range("A3").Resize(SoDong, 15).Value = Ws.Cells(i, 1).Resize(SoDong, 15).Value  ' chay hêt 69,126953125 s
    Next i
    Debug.Print Timer - tTime
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True 
    MsgBox "Done"
    End Sub
Nhân đây cũng nhờ anh @ptm0412 xem lại code của tôi xem có vấn đề gì chưa hợp lý và giải thích khai sáng giúp tôi và có thể có các bạn khác có quan tâm
 
Upvote 0
Tôi đã thử lại cả 3 cách : Chỉ dùng 1 vòng for để lấy dòng cuối
for i=2 to Lastrow step 9000 nhưng không hiểu sao mà vẫn cho kết quả đúng nhưng thời gian chạy code lại khác nhau nhiều như vậy
1/ Arr=Ws.Cells(i, 1).Resize(SoDong, 15).Value
Sh.range("A3").resize(sodong,15)=Arr ====> chạy hết 79,533203125s
2/ Ws.Cells(i, 1).Resize(SoDong, 15).Copy sh.Range("A3") ' chạy hêt 10,6171875s
3/ sh.Range("A3").Resize(SoDong, 15).Value = Ws.Cells(i, 1).Resize(SoDong, 15).Value ' chạy hêt 69,126953125 s
Tôi chạy code của bạn:
Dùng mảng: 7.3671875
Copy paste: 3.47265625
Gán value: 5.65625

Cũng không nhanh chậm gấp nhiều lần.
Ghi chú:
Tôi chạy 1 code 3 lần lấy trung bình.
Trước khi chạy lần sau, xóa sheet đã tạo của lần trước.
Nếu kỹ hơn thì trước khi đổi code, đóng hẳn excel mở lên lại, hoặc thậm chí restart máy, trường hợp này chưa đến nỗi phải kỹ đến thế.
 
Upvote 0
Tôi chạy code của bạn:
Dùng mảng: 7.3671875
Copy paste: 3.47265625
Gán value: 5.65625

Cũng không nhanh chậm gấp nhiều lần.
Ghi chú:
Tôi chạy 1 code 3 lần lấy trung bình.
Trước khi chạy lần sau, xóa sheet đã tạo của lần trước.
Nếu kỹ hơn thì trước khi đổi code, đóng hẳn excel mở lên lại, hoặc thậm chí restart máy, trường hợp này chưa đến nỗi phải kỹ đến thế.
Cảm ơn anh đã phản hồi. Có lẽ do máy của tôi ì ạch, hoặc do dữ liệu của tôi giả lập không thật chuẩn nên thòi gian chạy code hết nhiều như vậy.
 
Upvote 0
Tôi có sẵn 1 file 1 triệu dòng, dữ liệu chuẩn và gồm các kiểu đa dạng: Ngày, số, chuỗi, ... Chỉ có 11 cột, 4 cột phía sau thêm vô để so sánh thôi.

1662108363613.png
 
Upvote 0
Tôi có sẵn 1 file 1 triệu dòng, dữ liệu chuẩn và gồm các kiểu đa dạng: Ngày, số, chuỗi, ... Chỉ có 11 cột, 4 cột phía sau thêm vô để so sánh thôi.

View attachment 280604
Dữ liệu của tôi cũng là dữ liệu của ngân hàng, lúc đầu nó chỉ có 20000 dòng sau đó tôi copy thêm để thành hơn 508000 dòng, nó cũng bao gồm số , text,..
 

File đính kèm

  • Screenshot (67).png
    Screenshot (67).png
    406.6 KB · Đọc: 11
Upvote 0
Dữ liệu của tôi cũng là dữ liệu của ngân hàng, lúc đầu nó chỉ có 20000 dòng sau đó tôi copy thêm để thành hơn 508000 dòng, nó cũng bao gồm số , text,..
Vậy thì tôi chịu thua.
Định nói do Office không có bản quyền, nhưng không chắc nên thôi.
 
Upvote 0
Vậy thì tôi chịu thua.
Định nói do Office không có bản quyền, nhưng không chắc nên thôi.
Điều anh định nói có lẽ là nguyên nhân chính, bởi vì tôi dùng Offce 365 không bản quyền, và cấu hình máy thì ram chỉ có 4 Gb thôi. Cảm ơn anh đã chia sẻ những kinh nghiệm quý cho 1 người a ma tơ- không có căn bản và cũng chả có tý kinh nghiệm nào như tôi.
 
Upvote 0

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

Back
Top Bottom