Giúp code tổng hợp (1 người xem)

Liên hệ QC

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

tueyennhi

Thành viên tích cực
Tham gia
18/10/10
Bài viết
1,192
Được thích
105
Chào anh chị.

Em có file dữ liệu với nhiều sheet khác nhau, có cách nào chạy file lọc lấy giá trị cột ID của tất cả các sheet kia vào sheet tổng hợp không ạ? Với điều kiện ID trong sheet tổng hợp là duy nhất (chỉ lấy ID khác biệt vào file tổng hợp, không lặp lại các ID đã có.

Em cảm ơn.
 

File đính kèm

(1) Anh ơi có một chút vấn đề là khi em chạy vào file thực tế thì báo lỗi.
(1.1) File của anh up lên em thử copy nhân bản thêm 10 sheet nữa thì cũng chạy báo lỗi anh ạ.
For J = 1 To UBound(Arr())

(2) Ngoài sheet BCC thì trong file của em còn các sheet từ 26 đến 31 và 1 đến 25.

(1) Các tháng khác nhau sẽ có số ngày khác nhau;
Theo như macro thì tháng nào không có các ngày cuối tháng thì trang '31' hay ('30' &/hay '29' (tháng 2)) cần được xóa trang đó đi; Trang nào có công của chí ít 1 nhân viên nào đó mới để lại; Còn không ta fải xóa tất; Có nghĩa là tháng có bao nhiêu ngày thì chỉ tối đa có bí nhiêu trang tính chấm công mà thôi.
(1.1) Nói lại: Ngày nghĩ của CQ, không ai làm thì trang công về ngày đó fải biến khỏi màn hình của Workbook;
(Mình chưa thử, bạn thêm chữ cái nào đó vô đầu của tên trang tính "không công" xem sao?!?)

2. Nếu gán đúng tên thì macro không nề hà với các trang tính í
Nhưng lưu í là sau khi chạy macro, ở 'BCC' các cột dữ liệu thuộc ngày 'trống' đó sẽ f ải không có số liệu)
Có nghĩa là thiết kế trang 'BCC' vẫn giữ í nguyên. (& các ô thuộc cột ghi ngày của chúng củng cần xóa đi hay làm cách nào đó . . . cũng được.

Macro khong căn cứ các ngày đó để chép đâu; Nó căn cứ vô tên trang tính có chấm công để chép mà thôi.


(3) Cũng có thể có thiết kế khác cho 'BCC', nhưng có lẽ lúc đó thuật toán sẽ nhiều fiền toái hơn!
 
Upvote 0
(1) Các tháng khác nhau sẽ có số ngày ....

Vâng chu kỳ lương của công ty em từ 26 tháng trước đến 25 của tháng sau. Ngày nào cũng có người đi làm anh ạ.

(2) Nếu gán đúng tên thì macro không nề hà với các trang tính

Anh thử xem file ChangTQ ở bài #15 chưa ạ? Em chạy ban đầu rất trơn chu, sau đó em thử nhân bản thêm 2 sheet và đặt tên ngày công (cái hay là em đặt tên thoải mái chỉ cần đúng với một trong các ngày được liệt kê ở BCC nó sẽ chuyển đến đúng cái ngày ấy em thấy thật kỳ diệu mà rất tiếc chẳng hiểu sao anh ấy làm được vậy). Sau đó em cho vào file em chạy báo lỗi, em thử nhân bản lên 10 ngày công ở file của anh ấy thì cũng bị lỗi y chang.
 
Lần chỉnh sửa cuối:
Upvote 0
(1) . . .
(2) Nếu gán đúng tên thì macro không nề hà với các trang tính

Anh xem file ChangTQ ở bài #15? Em chạy ban đầu rất trơn tru, sau đó em thử nhân bản thêm 2 sheet và đặt tên ngày công (. . . ). Sau đó em cho vào file em chạy báo lỗi, em thử nhân bản lên 10 ngày công ở file của anh ấy thì cũng bị lỗi y chang.

Vậy bạn đưa file báo lỗi í lên diễn đàn đi!

Để các i bác sỹ khám chữa bệnh cho!
Mà nó báo lỗi ra sao?

&&&%$R&&&%$R&&&%$R
 
Upvote 0
Vậy bạn đưa file báo lỗi í lên diễn đàn đi!

Để các i bác sỹ khám chữa bệnh cho!
Mà nó báo lỗi ra sao?

&&&%$R&&&%$R&&&%$R

Anh ơi nó báo lỗi runtime erro 6 Overflow. File của em rất nặng, mỗi sheet ngày công lên đến hơn 4000 người. Chỉ khác về dữ liệu còn lại form y chang ở bài 15# anh ạ.

Em xin đính chính file của anh ChangTQ chạy rất mượt :(
 
Lần chỉnh sửa cuối:
Upvote 0
/-)ưa cái file này lên cũng được mà:

Vâng của anh thì chạy như ngựa mà không hiểu sao của em thì lại không được, em có đính chínhi ở #24 rồi mà anh. Form thì y chang, chỉ khác là dữ liệu công lớn thôi anh ạ. Có khi nào do lỗi định dạng hoặc phiên bản excel không anh? Của em đang dùng office 2013
 
Lần chỉnh sửa cuối:
Upvote 0
Hay có anh nào có thể sử dụng teamview xem giúp em được không ạ? Em đang cố gắng để có thể chuyển sang mảng lương, điều này quyết định nhiều đến tương lai của em sau này, mong mọi người giúp đỡ!

Hoặc đối với code của anh ChanhTQ

Option Explicit
Sub THCong()
Dim Dat As Date, J As Byte, Rws As Long, Dm As Byte, Ng As Byte, Col As Byte
Dim Cls As Range, Sh As Worksheet, Arr()
Dim ShName As String


Sheets("BCC").Select: Dat = [h6].Value
Rws = [h6].CurrentRegion.Rows.Count
For Each Sh In ThisWorkbook.Worksheets
If IsNumeric(Sh.Name) Then
ShName = ShName & Sh.Name
End If
Next Sh
For Each Cls In Range([B8], [B8].End(xlDown))
ReDim dArr(1 To 1, 1 To 155)
For Dm = 1 To Len(ShName) Step 2
Set Sh = ThisWorkbook.Worksheets(Mid(ShName, Dm, 2))
Ng = CByte(Mid(ShName, Dm, 2))
If Ng > 25 Then
Col = (Ng - 26) * 5 + 1
Else
Col = 26 + Ng * 5
End If
Arr() = Sh.[c9].Resize(Rws, 38).Value
For J = 1 To UBound(Arr())
If Arr(J, 1) = Cls.Value Then
dArr(1, Col) = Arr(J, 33): dArr(1, 1 + Col) = Arr(J, 34)
dArr(1, 2 + Col) = Arr(J, 35): dArr(1, 3 + Col) = Arr(J, 38)
End If
Next J
Next Dm
Cls.Offset(, 6).Resize(, 31 * 5).Value = dArr()
Next Cls
End Sub


Mọi người có thể diễn giải từng dòng lệnh cho em được không ? Ví dụ tại sao là NG - 26 mà không phải số khác, tại sao lại nhân 5 @@
 
Lần chỉnh sửa cuối:
Upvote 0
Anh ChanhTQ ơi công thức này gặp lỗi khi số dòng quá nhiều cụ thể cột ID đến địa chỉ dòng 255 là sẽ lỗi anh ạ.
 
Upvote 0
/)ịch từ ngôn ngữ VBA sang tiếng Việt:

PHP:
Option Explicit
Sub THCong()
 Dim Dat As Date, J As Byte, Rws As Long, Dm As Byte, Ng As Byte, Col As Byte
 Dim Cls As Range, Sh As Worksheet, Arr()
 Dim ShName As String

1 Sheets("BCC").Select:                          Dat = [h6].Value
 Rws = [h6].CurrentRegion.Rows.Count
3 For Each Sh In ThisWorkbook.Worksheets
    If IsNumeric(Sh.Name) Then
5        ShName = ShName & Sh.Name
    End If
7 Next Sh
 For Each Cls In Range([B8], [B8].End(xlDown))
9    ReDim dArr(1 To 1, 1 To 155)
    For Dm = 1 To Len(ShName) Step 2
11        Set Sh = ThisWorkbook.Worksheets(Mid(ShName, Dm, 2))
        Ng = CByte(Mid(ShName, Dm, 2))
13        If Ng > 25 Then
            Col = (Ng - 26) * 5 + 1
15        Else
            Col = 26 + Ng * 5
17        End If
        Arr() = Sh.[c9].Resize(Rws, 38).Value
19        For J = 1 To UBound(Arr())
            If Arr(J, 1) = Cls.Value Then
21                dArr(1, Col) = Arr(J, 33):      dArr(1, 1 + Col) = Arr(J, 34)
                dArr(1, 2 + Col) = Arr(J, 35):  dArr(1, 3 + Col) = Arr(J, 38)
23            End If
            If Arr(J, 1) = "" Then Exit For     '*'
25        Next J
    Next Dm
27    Cls.Offset(, 6).Resize(, 31 * 5).Value = dArr()
 Next Cls
End Sub

Các dòng lệnh trước D1: Khai báo các biến cần thiết cho chương trình;
D1: Mệnh đề 1: Kích hoạt (chọn) trang tính có tên 'BCC;
Mệnh đề sau: Lấy trị (ngày) tại ô [H6] gán vô biến đã khai báo;
D2: lấy số dòng của vùng dữ liệu xung quanh ô này gán vô biến đã khai báo; (Số dòng này có thể lên đến 2 triệu cũng OK!)
D3: Thiết lập vòng lặp để duyệt qua hết thẩy các trang tính; Vòng lặp này kết thúc tại D7;
D4: Điều kiện: Nếu tên của trang tính đang duyệt là 'Số' thì thực hiện dòng lệnh tiếp ngay sau;
D5: Nối tên trang dăng duyệt vô biến chuỗi đã khai báo
(kết thúc vòng lặp, biến chuỗi này sẽ gồm toàn bộ các trang tính ngày công trong tháng có chấm công)
D6: Kết thúc Đ/K
D8: Tạo vòng lặp duyệt toàn bộ các ô thuộc cột mã NV (cột )
Vòng lặp này kết thúc tại D28;
D9: Khai báo 1 biến mảng gồm 1 dòng & 155 cột; (Ngõ hầu chứa ngày công trong tháng của người mà vòng lặp đang sẽ duyệt
D10: Tạo vòng lặp để duyệt tên từng trang tính (kiểu kí số) trong biến mà vòng lặp đã gôm vô.
Vòng lặp này kết thúc tại D26.
(Thường 1 tháng cao nhất 31 ngày, nên ta chỉ cần biến đe71m 'Dm' không vượt quá 255 đơn vị)
D11: Lấy trang tính có tên biến đếm kiểu số gán vô biến đối tượng (trang tính) Sh đã khai báo;
D12: Lấy tên trang tính này chuyển sang kiểu (dạng) số & ấn vô biến 'Ng'
(Nếu tên trang tính đang là '31', thì Ng sẽ mang số 31 & điều này làm cơ sở để xác định cột cần nạp dữ liệu ngày công vô 'BCC' của người đang được duyệt)
D13: Các câu lệnh kết tiếp (đến trước D18) để xác định cột cần nạp dữ liệu
Ví dụ đang duyệt trang tính '26' thì cột đầu tiên cần nạp sẽ là (26-26)*5+1 (=> 1); Nếu trang '27' sẽ là cột 6,. . .
Vì mỗi người mỗi ngày cần nạp có thể lên tới 4 loại công khác nhau (& 1 loại công nào đó mà bạn sẽ tự nạp) (=> 05 cột cho 1 ngày); Con số 5 là nghĩa như vậy.
D16: Nếu trang ngày công bé hơn 26, thì trang '01' sẽ cách cột để nạp liệu ngày 26 là 26 cột +5 (=>31 cột)
(Xem thêm D27 để rõ hơn chi tiết)
D18: Lấy số liệu của trang ngày công đang duyệt cho vô biến mảng đã khai báo (Arr())
D19: Tạo vòng lặp duyệt dữ liệu vừa đưa vô mảng;
Vòng lặp này kết thúc tại D25;
D20: Nếu khi duyệt (của cả 2 vòng lặp) mà thỏa điều kiện là trùng mã nhân viên đang duyệt của vòng lặp ngoài với mả của trang tính công đang duyệt thì thực hiện các lệnh D21 & D22

Hai dòng lệnh này là lấy số liệu của cột tương ứng của trang ngày công nạp vô biến mảng (mảng 1 dòng & 155 cột)
D24: Kiều kiện để thoát ngay vòng lặp; Khỏi tốn thời gian cho những dòng không số liệu.
D27: Nạp dữ liệu công đã ghi được từ mảng (1 dòng 155 cột) vô dòng đang duyệt của 'BCC'

Cho rằng các biến đếm đã đủ khả năng để đáp ứng số liệu thực tế đề ra;
(Không thể có tháng nào đó > 255 ngày!)
Vậy nên bạn coi lại fần việc của mình; Như khoảng trắng khi tạo tên trang tính; trang tính chấm công ngày 9 của tháng fải là '09' chứ không thể '9' khơi khơi được.
Chuỗi chứa trong ShName sẽ là "26272829303101. . . ."
 
Upvote 0
PHP:
Option Explicit
Sub THCong()
 Dim Dat As Date, J As Byte, Rws As Long, Dm As Byte, Ng As Byte, Col As Byte
 Dim Cls As Range, Sh As Worksheet, Arr()
 Dim ShName As String

1 Sheets("BCC").Select:                          Dat = [h6].Value
 Rws = [h6].CurrentRegion.Rows.Count
3 For Each Sh In ThisWorkbook.Worksheets
    If IsNumeric(Sh.Name) Then
5        ShName = ShName & Sh.Name
    End If
7 Next Sh
 For Each Cls In Range([B8], [B8].End(xlDown))
9    ReDim dArr(1 To 1, 1 To 155)
    For Dm = 1 To Len(ShName) Step 2
11        Set Sh = ThisWorkbook.Worksheets(Mid(ShName, Dm, 2))
        Ng = CByte(Mid(ShName, Dm, 2))
13        If Ng > 25 Then
            Col = (Ng - 26) * 5 + 1
15        Else
            Col = 26 + Ng * 5
17        End If
        Arr() = Sh.[c9].Resize(Rws, 38).Value
19        For J = 1 To UBound(Arr())
            If Arr(J, 1) = Cls.Value Then
21                dArr(1, Col) = Arr(J, 33):      dArr(1, 1 + Col) = Arr(J, 34)
                dArr(1, 2 + Col) = Arr(J, 35):  dArr(1, 3 + Col) = Arr(J, 38)
23            End If
            If Arr(J, 1) = "" Then Exit For     '*'
25        Next J
    Next Dm
27    Cls.Offset(, 6).Resize(, 31 * 5).Value = dArr()
 Next Cls
End Sub

Các dòng lệnh trước D1: Khai báo các biến cần thiết cho chương trình;
D1: Mệnh đề 1: Kích hoạt (chọn) trang tính có tên 'BCC;
Mệnh đề sau: Lấy trị (ngày) tại ô [H6] gán vô biến đã khai báo;
D2: lấy số dòng của vùng dữ liệu xung quanh ô này gán vô biến đã khai báo; (Số dòng này có thể lên đến 2 triệu cũng OK!)
D3: Thiết lập vòng lặp để duyệt qua hết thẩy các trang tính; Vòng lặp này kết thúc tại D7;
D4: Điều kiện: Nếu tên của trang tính đang duyệt là 'Số' thì thực hiện dòng lệnh tiếp ngay sau;
D5: Nối tên trang dăng duyệt vô biến chuỗi đã khai báo
(kết thúc vòng lặp, biến chuỗi này sẽ gồm toàn bộ các trang tính ngày công trong tháng có chấm công)
D6: Kết thúc Đ/K
D8: Tạo vòng lặp duyệt toàn bộ các ô thuộc cột mã NV (cột )
Vòng lặp này kết thúc tại D28;
D9: Khai báo 1 biến mảng gồm 1 dòng & 155 cột; (Ngõ hầu chứa ngày công trong tháng của người mà vòng lặp đang sẽ duyệt
D10: Tạo vòng lặp để duyệt tên từng trang tính (kiểu kí số) trong biến mà vòng lặp đã gôm vô.
Vòng lặp này kết thúc tại D26.
(Thường 1 tháng cao nhất 31 ngày, nên ta chỉ cần biến đe71m 'Dm' không vượt quá 255 đơn vị)
D11: Lấy trang tính có tên biến đếm kiểu số gán vô biến đối tượng (trang tính) Sh đã khai báo;
D12: Lấy tên trang tính này chuyển sang kiểu (dạng) số & ấn vô biến 'Ng'
(Nếu tên trang tính đang là '31', thì Ng sẽ mang số 31 & điều này làm cơ sở để xác định cột cần nạp dữ liệu ngày công vô 'BCC' của người đang được duyệt)
D13: Các câu lệnh kết tiếp (đến trước D18) để xác định cột cần nạp dữ liệu
Ví dụ đang duyệt trang tính '26' thì cột đầu tiên cần nạp sẽ là (26-26)*5+1 (=> 1); Nếu trang '27' sẽ là cột 6,. . .
Vì mỗi người mỗi ngày cần nạp có thể lên tới 4 loại công khác nhau (& 1 loại công nào đó mà bạn sẽ tự nạp) (=> 05 cột cho 1 ngày); Con số 5 là nghĩa như vậy.
D16: Nếu trang ngày công bé hơn 26, thì trang '01' sẽ cách cột để nạp liệu ngày 26 là 26 cột +5 (=>31 cột)
(Xem thêm D27 để rõ hơn chi tiết)
D18: Lấy số liệu của trang ngày công đang duyệt cho vô biến mảng đã khai báo (Arr())
D19: Tạo vòng lặp duyệt dữ liệu vừa đưa vô mảng;
Vòng lặp này kết thúc tại D25;
D20: Nếu khi duyệt (của cả 2 vòng lặp) mà thỏa điều kiện là trùng mã nhân viên đang duyệt của vòng lặp ngoài với mả của trang tính công đang duyệt thì thực hiện các lệnh D21 & D22

Hai dòng lệnh này là lấy số liệu của cột tương ứng của trang ngày công nạp vô biến mảng (mảng 1 dòng & 155 cột)
D24: Kiều kiện để thoát ngay vòng lặp; Khỏi tốn thời gian cho những dòng không số liệu.
D27: Nạp dữ liệu công đã ghi được từ mảng (1 dòng 155 cột) vô dòng đang duyệt của 'BCC'

Cho rằng các biến đếm đã đủ khả năng để đáp ứng số liệu thực tế đề ra;
(Không thể có tháng nào đó > 255 ngày!)
Vậy nên bạn coi lại fần việc của mình; Như khoảng trắng khi tạo tên trang tính; trang tính chấm công ngày 9 của tháng fải là '09' chứ không thể '9' khơi khơi được.
Chuỗi chứa trong ShName sẽ là "26272829303101. . . ."


Dạ vâng em cảm ơn anh nhiều lắm!
Để em kiểm tra lại xem sao, có gì em sẽ báo mọi người
 
Upvote 0
Chào mọi người

Em đã kiểm tra kỹ tất cả, sheet công đều ghi số không có khoảng trắng 26, 27, 28... 01, 02, 03... 25

Sheet BCC cũng không có khoảng trắng.
 
Upvote 0
Anh ChanhTQ ơi công thức này gặp lỗi khi số dòng quá nhiều cụ thể cột ID đến địa chỉ dòng 255 là sẽ lỗi anh ạ.

Đúng rồi; Mình xin lỗi nha!

Bạn chuyển khai báo biến J As Long (thay vì As Byte) là được.

 
Upvote 0
Chào mọi người

Em đã kiểm tra kỹ tất cả, sheet công đều ghi số không có khoảng trắng 26, 27, 28... 01, 02, 03... 25

Sheet BCC cũng không có khoảng trắng. Em up file lên mọi người xem giúp em nhé.
 

File đính kèm

Upvote 0
Đúng rồi; Mình xin lỗi nha!

Bạn chuyển khai báo biến J As Long (thay vì As Byte) là được.


Anh ơi file chạy được rồi, nhưng mà chậm lắm anh ạ dữ liệu ít thì rất nhanh nhưng nhiều thì chậm. Mỗi bảng công có 4000 người lao động. Mà mỗi tháng có 25 đến 26 ngày cônG, em bấm chạy được một lúc xong đơ luôn (em nghĩ nó vẫn đang chạy). Có cách nào để nhanh hơn không ạ?
 
Lần chỉnh sửa cuối:
Upvote 0
Anh ơi file chạy được rồi, nhưng mà chậm lắm anh ạ dữ liệu ít thì rất nhanh nhưng nhiều thì chậm. Mỗi bảng công có 4000 người lao động. Mà mỗi tháng có 25 đến 26 ngày cônG, em bấm chạy được một lúc xong đơ luôn (em nghĩ nó vẫn đang chạy). Có cách nào để nhanh hơn không ạ?
Bạn sắp xếp lại ID bên sheet BCC theo từ nhỏ đến lớn và chạy code này coi, nếu ok thì tính tiếp
Mã:
Sub test()
Dim cn As Object, rs As Object
Set cn = CreateObject("ADODB.Connection")
 cn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=No;IMEX=1"";")
 Set rs = cn.Execute("select b.f33, b.f34,b.f35, '', b.f38 from [BCC$B8:B3466] a left join [26$C9:AN3467] b on b.f1 = a.f1")
Range("H8").CopyFromRecordset rs
End Sub
 
Upvote 0
Bạn thử macro này trên file thật của bạn xem tiêu tốn mấy trăm gy cho 220 người
PHP:
Option Explicit
Sub ArrTHCong()
 Dim W As Long, J As Long, Rws As Long, Dm As Byte, Ng As Byte, Col As Byte, Tmr As Double
 Dim Rng As Range, Sh As Worksheet, Arr(), Aid()
 Dim ShName As String
 
 Sheets("BCC").Select:                      Tmr = Timer()
 Rws = [h6].CurrentRegion.Rows.Count
 For Each Sh In ThisWorkbook.Worksheets
    If IsNumeric(Sh.Name) Then
        ShName = ShName & Sh.Name
    End If
 Next Sh
 Set Rng = Range([B8], [B8].End(xlDown))
 Aid() = Rng.Value
 ReDim dArr(1 To Rng.Rows.Count, 1 To 155)
 For J = 1 To UBound(Aid())
    For Dm = 1 To Len(ShName) Step 2
        Set Sh = ThisWorkbook.Worksheets(Mid(ShName, Dm, 2))
        Ng = CByte(Mid(ShName, Dm, 2))
        If Ng > 25 Then
            Col = (Ng - 26) * 5 + 1
        Else
            Col = 26 + Ng * 5
        End If
        Arr() = Sh.[c9].Resize(Rws, 38).Value
        For W = 1 To UBound(Arr())
            If Aid(J, 1) = Arr(W, 1) Then
                dArr(J, Col) = Arr(W, 33):      dArr(J, 1 + Col) = Arr(W, 34)
                dArr(J, 2 + Col) = Arr(W, 35):  dArr(J, 3 + Col) = Arr(W, 38)
            End If
        Next W
    Next Dm
    
    If J = 220 Then GoTo GPE
 Next J
GPE:
 [H8].Resize(J, 155).Value = dArr()
 MsgBox Timer() - Tmr
End Sub
 
Upvote 0
Bạn thử macro này trên file thật của bạn xem tiêu tốn mấy trăm gy cho 220 người
PHP:
Option Explicit
Sub ArrTHCong()
 Dim W As Long, J As Long, Rws As Long, Dm As Byte, Ng As Byte, Col As Byte, Tmr As Double
 Dim Rng As Range, Sh As Worksheet, Arr(), Aid()
 Dim ShName As String
 
 Sheets("BCC").Select:                      Tmr = Timer()
 Rws = [h6].CurrentRegion.Rows.Count
 For Each Sh In ThisWorkbook.Worksheets
    If IsNumeric(Sh.Name) Then
        ShName = ShName & Sh.Name
    End If
 Next Sh
 Set Rng = Range([B8], [B8].End(xlDown))
 Aid() = Rng.Value
 ReDim dArr(1 To Rng.Rows.Count, 1 To 155)
 For J = 1 To UBound(Aid())
    For Dm = 1 To Len(ShName) Step 2
        Set Sh = ThisWorkbook.Worksheets(Mid(ShName, Dm, 2))
        Ng = CByte(Mid(ShName, Dm, 2))
        If Ng > 25 Then
            Col = (Ng - 26) * 5 + 1
        Else
            Col = 26 + Ng * 5
        End If
        Arr() = Sh.[c9].Resize(Rws, 38).Value
        For W = 1 To UBound(Arr())
            If Aid(J, 1) = Arr(W, 1) Then
                dArr(J, Col) = Arr(W, 33):      dArr(J, 1 + Col) = Arr(W, 34)
                dArr(J, 2 + Col) = Arr(W, 35):  dArr(J, 3 + Col) = Arr(W, 38)
            End If
        Next W
    Next Dm
    
    If J = 220 Then GoTo GPE
 Next J
GPE:
 [H8].Resize(J, 155).Value = dArr()
 MsgBox Timer() - Tmr
End Sub

Hết 22s anh ạ. Chạy trên 31 sheet ngày công. Hay anh có rảnh không em bật teamview anh xem cho em nhé.
Em mới phát hiện ra nó không quét hết dữ liệu, ví dụ công ngày 09 rõ ràng là có nhưng khi tổng hợp thì lại không có. Các ID trong các sheet chấm công nó không theo quy luật thứ tự nào mà xáo trộn thì có ảnh hưởng gì không anh?
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn sắp xếp lại ID bên sheet BCC theo từ nhỏ đến lớn và chạy code này coi, nếu ok thì tính tiếp
Mã:
Sub test()
Dim cn As Object, rs As Object
Set cn = CreateObject("ADODB.Connection")
 cn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=No;IMEX=1"";")
 Set rs = cn.Execute("select b.f33, b.f34,b.f35, '', b.f38 from [BCC$B8:B3466] a left join [26$C9:AN3467] b on b.f1 = a.f1")
Range("H8").CopyFromRecordset rs
End Sub

Tốc độ rất nhanh nhưng không đúng. Cột ID tổng của em là tập hợp ID của tất cả các sheet công (có thể ID sheet công của ngày này lại không có trong ngày khác).
 
Upvote 0
Hết 22s anh ạ. Chạy trên 31 sheet ngày công. Hay anh có rảnh không em bật teamview anh xem cho em nhé.
(1) Em mới phát hiện ra nó không quét hết dữ liệu, ví dụ công ngày 09 rõ ràng là có nhưng khi tổng hợp thì lại không có.
(2) Các ID trong các sheet chấm công nó không theo quy luật thứ tự nào mà xáo trộn thì có ảnh hưởng gì không anh?

(1) Điều này là lạ đó nghe; Để hiểu tại sao vậy, ta cần 2 câu lệnh

MsgBox ShName
Exit Sub
sau dòng lệnh
Next Sh
để xem trong biến có chứa chuỗi 09 chưa.

(Cũng cần đề fòng trường hợp trang '09' đó không chứa ai trong 220 người đã được macro xử lí nữa nha.)

(2) Không ảnh hưởng nhiều lắm đến tốc độ xử lí thôi; Chứ kết quả vẫn đúng.

(3) Vậy là máy của bạn gấp gần chục lần máy mình rồi
Để chạy hết chương trình thì bạn bỏ hay vô hiệu hóa dòng lệnh
Mã:
If J = 220 Then GoTo GPE
ấy đi!
 
Lần chỉnh sửa cuối:
Upvote 0
Tốc độ rất nhanh nhưng không đúng. Cột ID tổng của em là tập hợp ID của tất cả các sheet công (có thể ID sheet công của ngày này lại không có trong ngày khác).
Mình hiểu cái đó, bạn có thể chỉ ra cái nào ko đúng ko? bạn thử thay "on b.f1 = a.f1" bằng on b.f1 = a.f1 order by a.f1 coi có chuẩn ko?
 
Upvote 0
Web KT

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

Back
Top Bottom