Hoàng Nhật Phương
Thành viên gắn bó



- Tham gia
- 5/11/15
- Bài viết
- 1,895
- Được thích
- 1,219
Chỉnh lại code bài #3, cho nó chạy "vớ vẫn" một chút chắc cũng không lâu.Oanh Thơ xin cảm ơn hai bạn: VetMini & HieuCD đã góp ý và giúp đỡ cho Oanh Thơ ạ.
Oanh Thơ đã chạy thử code trên của bạn HieuCD kết quả cũng đã OK rồi ạ. Cảm ơn bạn nhé!
Oanh Thơ đang vướng mắc 1 trường hợp nữa (bài toán 2) cũng tương tự như bài toán Oanh Thơ đã nêu ở bài 1.
Cũng là lấy dữ liệu từ Sheet Data đưa vào các sheet có sẵn ạ.
bài toán 2 những điểm khác so với bài toán 1 như sau ạ.
+ Dữ liệu lấy từ các Sheet Data đưa vào các sheet bộ phận điều kiện là tên của các Sheet bộ phận có thay đổi không trùng với tên trong trường bộ phận tại sheet Data nữa vì có thêm "ABC " đằng trước.
+ Dữ liệu lấy từ bảng theo dòng nhưng đưa vào các sheet bộ phận theo cột.
+ Số cột của mỗi người là 1 cột không phải như 8 cột như bài toán 1
Cụ thể câu hỏi và kết quả Oanh Thơ xin nêu cụ thể trong file kèm.
Kính mong nhận thêm được sự giúp đỡ của các bạn ạ.
Trân trọng cảm ơn.
Oanh Thơ
Public Sub GPE()
Dim Ws As Worksheet, sArr(), dArr(), I As Long, Col As Long, R As Long, Txt As String
With Sheets("Data")
sArr = .Range("C9", .Range("C65536").End(xlUp)).Resize(, 4).Value
R = UBound(sArr)
End With
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name <> "Data" Then
With Ws
Txt = UCase(.Name): Col = 0
ReDim dArr(1 To 2, 1 To R)
For I = 1 To R
If "ABC " & UCase(sArr(I, 2)) = Txt Then
Col = Col + 1
dArr(1, Col) = sArr(I, 4)
dArr(2, Col) = sArr(I, 1)
End If
Next I
.Range("D3:D4").Resize(, 1000).ClearContents
If Col > 0 Then .Range("D3:D4").Resize(, Col) = dArr
End With
End If
Next Ws
End Sub
Chỉnh lại code bài #3, cho nó chạy "vớ vẫn" một chút chắc cũng không lâu.
PHP:Public Sub GPE() Dim Ws As Worksheet, sArr(), dArr(), I As Long, Col As Long, R As Long, Txt As String With Sheets("Data") sArr = .Range("C9", .Range("C65536").End(xlUp)).Resize(, 4).Value R = UBound(sArr) End With For Each Ws In ThisWorkbook.Worksheets If Ws.Name <> "Data" Then With Ws Txt = UCase(.Name): Col = 0 ReDim dArr(1 To 2, 1 To R) For I = 1 To R If "ABC " & UCase(sArr(I, 2)) = Txt Then Col = Col + 1 dArr(1, Col) = sArr(I, 4) dArr(2, Col) = sArr(I, 1) End If Next I .Range("D3:D4").Resize(, 1000).ClearContents If Col > 0 Then .Range("D3:D4").Resize(, Col) = dArr End With End If Next Ws End Sub
bạn chạy code mớiOanh Thơ xin cảm ơn hai bạn: VetMini & HieuCD đã góp ý và giúp đỡ cho Oanh Thơ ạ.
Oanh Thơ đã chạy thử code trên của bạn HieuCD kết quả cũng đã OK rồi ạ. Cảm ơn bạn nhé!
Oanh Thơ đang vướng mắc 1 trường hợp nữa (bài toán 2) cũng tương tự như bài toán Oanh Thơ đã nêu ở bài 1.
Cũng là lấy dữ liệu từ Sheet Data đưa vào các sheet có sẵn ạ.
bài toán 2 những điểm khác so với bài toán 1 như sau ạ.
+ Dữ liệu lấy từ các Sheet Data đưa vào các sheet bộ phận điều kiện là tên của các Sheet bộ phận có thay đổi không trùng với tên trong trường bộ phận tại sheet Data nữa vì có thêm "ABC " đằng trước.
+ Dữ liệu lấy từ bảng theo dòng nhưng đưa vào các sheet bộ phận theo cột.
+ Số cột của mỗi người là 1 cột không phải như 8 cột như bài toán 1
Cụ thể câu hỏi và kết quả Oanh Thơ xin nêu cụ thể trong file kèm.
Kính mong nhận thêm được sự giúp đỡ của các bạn ạ.
Trân trọng cảm ơn.
Oanh Thơ
Sub GPE()
Dim Ws As Worksheet, Darr(), Dic As Object, i As Long, C As Long, Tmp As String
Darr = Sheets("Data").Range("C8:F" & Sheets("Data").Range("C65500").End(xlUp).Row).Value
Set Dic = CreateObject("scripting.dictionary")
For i = 1 To UBound(Darr)
If Darr(i, 2) <> "" Then
Tmp = "ABC " & Darr(i, 2)
If Not Dic.exists(Tmp) Then
Dic.Add Tmp, 1
Dic.Add Tmp & "#" & 1, Array(Darr(i, 1), Darr(i, 4))
Else
Dic.Item(Tmp) = Dic.Item(Tmp) + 1
Tmp = Tmp & "#" & Dic.Item(Tmp)
Dic.Add Tmp, Array(Darr(i, 1), Darr(i, 4))
End If
End If
Next i
For Each Ws In ThisWorkbook.Worksheets
Tmp = Ws.Name
If Dic.exists(Tmp) Then
C = Dic.Item(Tmp)
ReDim Darr(1 To 2, 1 To C)
For i = 1 To C
Darr(1, i) = Dic.Item(Tmp & "#" & i)(1)
Darr(2, i) = Dic.Item(Tmp & "#" & i)(0)
Next i
Ws.Range("D3").Resize(2, 1000).ClearContents
Ws.Range("D3").Resize(2, C) = Darr
End If
Next Ws
Set Dic = Nothing: Set Ws = Nothing: Erase Darr
End Sub
Ahihi, Tuyệt cú mèo rồi!
Ah bài toán 2 này của Oanh Thơ các cột liền nhau xin hỏi bạn ndu96081631 có thể áp dụng được phương pháp giống bài13 của bạn được không ạ?
Cảm ơn các bạn nhiều nhiều.
Oanh Thơ
Hi, vẫn là cái tên chưa thân nhưng quen quen, Xin cảm ơn bạn HieuCD rất nhiều ạ.bạn chạy code mớiMã:Sub GPE() Dim Ws As Worksheet, Darr(), Dic As Object, i As Long, C As Long, Tmp As String Darr = Sheets("Data").Range("C8:F" & Sheets("Data").Range("C65500").End(xlUp).Row).Value Set Dic = CreateObject("scripting.dictionary") For i = 1 To UBound(Darr) If Darr(i, 2) <> "" Then Tmp = "ABC " & Darr(i, 2) If Not Dic.exists(Tmp) Then Dic.Add Tmp, 1 Dic.Add Tmp & "#" & 1, Array(Darr(i, 1), Darr(i, 4)) Else Dic.Item(Tmp) = Dic.Item(Tmp) + 1 Tmp = Tmp & "#" & Dic.Item(Tmp) Dic.Add Tmp, Array(Darr(i, 1), Darr(i, 4)) End If End If Next i For Each Ws In ThisWorkbook.Worksheets Tmp = Ws.Name If Dic.exists(Tmp) Then C = Dic.Item(Tmp) ReDim Darr(1 To 2, 1 To C) For i = 1 To C Darr(1, i) = Dic.Item(Tmp & "#" & i)(1) Darr(2, i) = Dic.Item(Tmp & "#" & i)(0) Next i Ws.Range("D3").Resize(2, 1000).ClearContents Ws.Range("D3").Resize(2, C) = Darr End If Next Ws Set Dic = Nothing: Set Ws = Nothing: Erase Darr End Sub
Câu trả lời là ĐƯỢC!
Cũng giống như cách làm bằng tay thôi: Lọc bằng Advanced Filter sang vùng tạm, copy/paste transpose sang các sheet
Xong!
Oanh Thơ xin trân trọng cảm ơn các bạn và diễn đàn đã giúp đỡ Oanh Thơ thực hiện được bài toán 1 và 2 trong chủ đề này ạ.
Hiện tại với chủ đề này Oanh Thơ vẫn còn một vướng mắc nữa đó bài toán 3 này ạ...hic ngại quá
Câu hỏi và kết quả mong muốn Oanh Thơ đã nêu trong file đính kèm ạ.
Kính mong các bạn tiếp tục giúp đỡ ạ.
Trân trọng cảm ơn.
Oanh Thơ
"a" ở file thật là giống nhau hay khác nhau? và đã có sẵn dữ liệu "a" ứng với 31 ngày? Đã tạo 31 ngày ứng với tháng đó? Có cần tạo tự động số ngày tương ứng với tháng chỉ định?Không làm mất dữ liệu ở các vùng và các sheet không liên quan (không làm mất chữ a)
"a" ở file thật là giống nhau hay khác nhau? và đã có sẵn dữ liệu "a" ứng với 31 ngày? Đã tạo 31 ngày ứng với tháng đó? Có cần tạo tự động số ngày tương ứng với tháng chỉ định?
Các sheet bộ phận (KT,SX,Kho,QC) có sẵn? Đã lập sẵn Họ Tên | Bộ Phận | Mã Số | Item?
Với mỗi mã số luôn có 8 dòng và 3 items?
Không cần file thật, dữ liệu minh họa tương tự file thật là được (minh họa "a" hết thì khó hiểu)Cảm ơn befaint đã quan tâm ạ,rất xin lỗi các bạn vì điều kiện không cho phép nên Oanh Thơ không gửi đc file thật lên đây rất mong các bạn thông cảm.
Oanh Thơ xin giải thích từng trường hợp của bạn ạ:
+ "a" mục đích chỉ là hiển thị các vùng đó có dữ liệu,các dữ liệu có khác nhau, thay đổi có hoặc không tùy theo từng ngày.
+ 31 ngày này là cố định 31 cột, form mẫu có sẵn 31 cột tương ứng với 31 ngày. nếu tháng nào có 30 ngày thì form mẫu vẫn có đủ 31 cột nhưng cột thứ 30 để trắng không có gì.
+ Các sheet bộ phận (KT,SX,Kho,QC) có sẵn Đã lập sẵn Họ Tên | Bộ Phận | Mã Số | Item.
+ Với mỗi mã số luôn có 8 dòng tương ứng với 8 hạng mục mà Oanh Thơ đã nêu ở bài16 trong cùng chủ đề.
https://www.giaiphapexcel.com/forum...hiều-sheet-theo-điều-kiện&p=764148#post764148
3Item(3 dòng) 1,2,3 sẽ tự động lấy từ Sheet Data2 sang còn lại các 5 dòng còn lại là dữ liệu nhập tay theo ngày.
Rất mong nhận được sự trợ giúp của bạn và diễn đàn.
Trân trọng cảm ơn.
Oanh Thơ.
Không cần file thật, dữ liệu minh họa tương tự file thật là được (minh họa "a" hết thì khó hiểu)
Có thể nói rõ hơn về quy trình nhập dữ liệu vào sheet "Data2" và sheet bộ phận không? Ban đầu gồm dữ liệu nào? Nhập dữ liệu tiếp vào như nào? Cái nào trước/ sau? (vì nếu còn cập nhật dữ liệu vào các sheet bộ phận nhiều hơn 1 lần?)
(1) Nhập vào file mà bạn đã đính kèm phải không? Hay mỗi bộ phận một file để tự nhập dữ liệu vào?Hi befaint,
Về quy trình nhập dữ liệu thì là thế này. Mỗi thành viên ở các sheet bộ phận có 8 dòng. 4 dòng đầu là nhập dữ liệu cho từng người theo ngày. (1)
Sau đấy cứ 1 tuần hoặc nửa tháng (không cụ thể là bao nhiêu ngày thậm trí là cuối tháng cũng được) dữ liệu sẽ tổng hợp từ nhiều tệp tin bên ngoài khác (2) đưa hết vào tệp tin đính kèm trong sheet data2 với các trường mã số và các dữ liệu của 5item như đã minh họa.
Bước cuối cùng là từ sheet data2 đưa dữ liệu của 3item vào các dòng màu vàng trong sheet bộ phận.
Sheet data2 gọi là sheet trung gian để tổng hợp dữ liệu từ nhiều tệp tin. Nghĩa là bước này thực hiện xong thì sheet data2 mới có dữ liệu để đưa đến những sheet bộ phận được bạn ạ.
code chỉ thay thế Hàm Vlookup như trong file mẩuOanh Thơ xin trân trọng cảm ơn các bạn và diễn đàn đã giúp đỡ Oanh Thơ thực hiện được bài toán 1 và 2 trong chủ đề này ạ.
Hiện tại với chủ đề này Oanh Thơ vẫn còn một vướng mắc nữa đó bài toán 3 này ạ...hic ngại quá
Câu hỏi và kết quả mong muốn Oanh Thơ đã nêu trong file đính kèm ạ.
Kính mong các bạn tiếp tục giúp đỡ ạ.
Trân trọng cảm ơn.
Oanh Thơ
Sub GPE()
Dim Darr(), Sarr(), Arr(), Tarr(), Dic As Object, Ws, i As Long, k As Byte, j As Byte
Darr = Sheets("Data2").Range("F9:FE" & Sheets("Data2").Range("F65500").End(xlUp).Row).Value
Set Dic = CreateObject("scripting.dictionary")
For i = 1 To UBound(Darr)
If Darr(i, 1) <> "" And Not Dic.exists(Darr(i, 1)) Then Dic.Add Darr(i, 1), i
Next i
Ws = Array("SX", "QC", "Kho", "KT") 'Khai báo tên các Sheet
Tarr = Sheets(Ws(0)).Range("H3:AL3").Value
For k = LBound(Ws) To UBound(Ws)
ReDim Arr(1 To 3, 1 To 31)
Sarr = Sheets(Ws(k)).Range("E1:E" & Sheets(Ws(k)).Range("E65500").End(xlUp).Row).Value
For i = 4 To UBound(Sarr) Step 8
If Sarr(i, 1) <> "" And Dic.exists(Sarr(i, 1)) Then
For n = 1 To UBound(Arr)
For j = 1 To UBound(Arr, 2)
If Tarr(1, j) > 0 Then Arr(n, j) = Darr(Dic.Item(Sarr(i, 1)), (Tarr(1, j) - 1) * 5 + n + 1)
Next j
Next n
Sheets(Ws(k)).Range("H" & i + 3).Resize(3, 31) = Arr
End If
Next i
Next k
Set Dic = Nothing
End Sub
Oanh Thơ xin trân trọng cảm ơn các bạn và diễn đàn đã giúp đỡ Oanh Thơ thực hiện được bài toán 1 và 2 trong chủ đề này ạ.
Hiện tại với chủ đề này Oanh Thơ vẫn còn một vướng mắc nữa đó bài toán 3 này ạ...hic ngại quá
Câu hỏi và kết quả mong muốn Oanh Thơ đã nêu trong file đính kèm ạ.
Kính mong các bạn tiếp tục giúp đỡ ạ.
Trân trọng cảm ơn.
Oanh Thơ
Bạn nhận xét quá chuẩn, mình không rỏ dữ liệu ở sheet Data2 và cột ngày từng sheet như thế nào nên lưỡng lự và code không hợp lý,Anh HieuCD,
Sao anh không chuyển dòng
ra ngoài vòng lặp.Mã:ReDim Arr(1 To 3, 1 To 31)
Tarr = Sheets(Ws(0)).Range("H3:AL3").Value
ReDim Arr(1 To 3, 1 To 31)
For k = LBound(Ws) To UBound(Ws)
Sarr = Sheets(Ws(k)).Range("E1:E" & Sheets(Ws(k)).Range("E65500").End(xlUp).Row).Value
For i = 4 To UBound(Sarr) Step 8 [COLOR=#000000]
If Sarr(i, 1) <> "" And Dic.exists(Sarr(i, 1)) Then[/COLOR]
For k = LBound(Ws) To UBound(Ws)
Tarr = Sheets(Ws(k)).Range("H3:AL3").Value
ReDim Arr(1 To 3, 1 To 31)
Sarr = Sheets(Ws(k)).Range("E1:E" & Sheets(Ws(k)).Range("E65500").End(xlUp).Row).Value
For i = 4 To UBound(Sarr) Step 8
[COLOR=#000000] If Sarr(i, 1) <> "" And Dic.exists(Sarr(i, 1)) Then[/COLOR]
Sub GPE1()
Dim Darr(), Arr(), Ws, i As Long, n As Byte, k As Integer, j As Byte
Ws = Array("SX", "QC", "Kho", "KT") 'Khai báo tên các Sheet
For k = LBound(Ws) To UBound(Ws)
Darr = Sheets(Ws(k)).Range("E1:AL" & Sheets(Ws(k)).Range("E65500").End(xlUp).Row + 7).Value
For i = 4 To UBound(Darr) Step 8
If Darr(i, 1) <> "" Then
ReDim Arr(1 To 3, 1 To 31)
For n = 1 To UBound(Arr)
For j = 1 To UBound(Arr, 2)
If Darr(3, j + 3) > 0 Then Arr(n, j) = Darr(i, 1) & "/Itiem" & n & "-" & Darr(3, j + 3)
Next j
Next n
Sheets(Ws(k)).Range("H" & i + 3).Resize(3, 31) = Arr
End If
Next i
Next k
End Sub
Bạn nhận xét quá chuẩn, mình không rỏ dữ liệu ở sheet Data2 và cột ngày từng sheet như thế nào nên lưỡng lự và code không hợp lý,
nếu dữ liệu đầy đủ và đồng nhất thì Redim Arr nên đưa ra khỏi vòng lập
Mã:Tarr = Sheets(Ws(0)).Range("H3:AL3").Value ReDim Arr(1 To 3, 1 To 31) For k = LBound(Ws) To UBound(Ws) Sarr = Sheets(Ws(k)).Range("E1:E" & Sheets(Ws(k)).Range("E65500").End(xlUp).Row).Value For i = 4 To UBound(Sarr) Step 8 [COLOR=#000000] If Sarr(i, 1) <> "" And Dic.exists(Sarr(i, 1)) Then[/COLOR]
còn nếu dữ liệu các sheet lung tung lúc có lúc không thì phải cẩn thận hơn
Mã:For k = LBound(Ws) To UBound(Ws) Tarr = Sheets(Ws(k)).Range("H3:AL3").Value ReDim Arr(1 To 3, 1 To 31) Sarr = Sheets(Ws(k)).Range("E1:E" & Sheets(Ws(k)).Range("E65500").End(xlUp).Row).Value For i = 4 To UBound(Sarr) Step 8 [COLOR=#000000] If Sarr(i, 1) <> "" And Dic.exists(Sarr(i, 1)) Then[/COLOR]
cám ơn bạn, vụ khai báo dim, redim mình còn lúng túng, các kiểu dữ liệu chưa hiểu hết, đặc biệt là dùng ReDim Preserve để thay đổi kích thước mảng lúc được lúc khôngRedim có 2 mục đích, 1 là để đổi số phần tử của mảng động (dynamic array), 2 là để chuyển giá trị về mặc định (trong trường hợp này là trống vì dữ liệu variant)
Đặt Redim trong vòng lặp bảo đảm không bị ảnh hưởng tàn dư của những lần trước.
Trong trường hợp không cần reset mảng, và nếu số phần tử cũng cố định. Thì dùng mảng tĩnh (static array) là đúng hơn.
Dim Arr(1 to 3, 1 to 31)
Với dữ liệu + yêu cầu như trong file, tôi thấy bạn dùng VLOOKUP vậy là quá ổn rồi (với lại hàm này cũng khá "nhẹ"). Code trong trường hợp này vô cùng nguy hiểm, bởi chỉ sai 1 chút là xem như bạn hết cơ hội quay đầuOanh Thơ xin trân trọng cảm ơn các bạn và diễn đàn đã giúp đỡ Oanh Thơ thực hiện được bài toán 1 và 2 trong chủ đề này ạ.
Hiện tại với chủ đề này Oanh Thơ vẫn còn một vướng mắc nữa đó bài toán 3 này ạ...hic ngại quá
Câu hỏi và kết quả mong muốn Oanh Thơ đã nêu trong file đính kèm ạ.
Kính mong các bạn tiếp tục giúp đỡ ạ.
Trân trọng cảm ơn.
Oanh Thơ