Chuyển dữ liệu từ 1 sheet sang nhiều sheet theo điều kiện? (1 người xem)

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

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
Xin chào tất cả các bạn,
Như tiêu đề Oanh Thơ đã nêu, cụ thể bài toán Oanh Thơ đã viết trong file đính kèm ạ.
Rất mong nhận được sự giúp đỡ từ các bạn.
xin cảm ơn.
 

File đính kèm

Xin chào tất cả các bạn,
Như tiêu đề Oanh Thơ đã nêu, cụ thể bài toán Oanh Thơ đã viết trong file đính kèm ạ.
Rất mong nhận được sự giúp đỡ từ các bạn.
xin cảm ơn.

Có vấn đề cần làm rõ: Các sheet SX, QC, Kho, KT đã có sẵn hay ban đầu chỉ có sheet Data và bạn muốn code lọc rồi tạo ra các sheet con luôn? Bởi:
- Nếu chỉ cần lọc ra 4 sheet con, bất kể cột bộ phận trong sheet Data có bao nhiêu phần tử thì vòng lập chỉ duyệt qua 4 lần là xong
- Nếu các sheet con chưa sẵn, yêu cầu có bao nhiêu bộ phân thì lọc ra bấy nhiêu sheet, khi ấy vòng lập buộc phải chạy qua toàn bộ các phần tử trong cột bộ phận rồi phải thêm nhiệm vụ chèn sheet... vân... vân...
------------------
Hỏi rõ, làm 1 lần cho đở mất công. Nói chung bài này trên GPE chắc cũng được hỏi cả 100 lần rồi ----> For Next + Dictionary + Advanced Filter là cách dễ ăn nhất
 
Upvote 0
Có vấn đề cần làm rõ: Các sheet SX, QC, Kho, KT đã có sẵn hay ban đầu chỉ có sheet Data và bạn muốn code lọc rồi tạo ra các sheet con luôn? Bởi:
- Nếu chỉ cần lọc ra 4 sheet con, bất kể cột bộ phận trong sheet Data có bao nhiêu phần tử thì vòng lập chỉ duyệt qua 4 lần là xong
- Nếu các sheet con chưa sẵn, yêu cầu có bao nhiêu bộ phân thì lọc ra bấy nhiêu sheet, khi ấy vòng lập buộc phải chạy qua toàn bộ các phần tử trong cột bộ phận rồi phải thêm nhiệm vụ chèn sheet... vân... vân...
------------------
Hỏi rõ, làm 1 lần cho đở mất công. Nói chung bài này trên GPE chắc cũng được hỏi cả 100 lần rồi ----> For Next + Dictionary + Advanced Filter là cách dễ ăn nhất

Chắc "chủ nhân" phải làm sẵn các sheet con thôi (vì phải Format các dòng "rí rí"...ngộ ngộ)
PHP:
Public Sub GPE()
Dim Ws As Worksheet, sArr(), dArr(), I As Long, K 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): K = -7
            ReDim dArr(1 To R * 8, 1 To 3)
            For I = 1 To R
                If UCase(sArr(I, 2)) = Txt Then
                    K = K + 8
                    dArr(K, 1) = sArr(I, 1)
                    dArr(K, 2) = sArr(I, 2)
                    dArr(K, 3) = sArr(I, 4)
                End If
            Next I
            .Range("C4").Resize(1000, 3).ClearContents
            If K > 0 Then .Range("C4").Resize(K, 3) = dArr
        End With
    End If
Next Ws
End Sub
Híc!!!!!!!!
 
Upvote 0
Có vấn đề cần làm rõ: Các sheet SX, QC, Kho, KT đã có sẵn hay ban đầu chỉ có sheet Data và bạn muốn code lọc rồi tạo ra các sheet con luôn? Bởi:
- Nếu chỉ cần lọc ra 4 sheet con, bất kể cột bộ phận trong sheet Data có bao nhiêu phần tử thì vòng lập chỉ duyệt qua 4 lần là xong
- Nếu các sheet con chưa sẵn, yêu cầu có bao nhiêu bộ phân thì lọc ra bấy nhiêu sheet, khi ấy vòng lập buộc phải chạy qua toàn bộ các phần tử trong cột bộ phận rồi phải thêm nhiệm vụ chèn sheet... vân... vân...
------------------
Hỏi rõ, làm 1 lần cho đở mất công. Nói chung bài này trên GPE chắc cũng được hỏi cả 100 lần rồi ----> For Next + Dictionary + Advanced Filter là cách dễ ăn nhất

Ui, người nổi tiếng!
Oanh Thơ cảm ơn bạn nhiều vì đã quan tâm ạ.

Vâng đúng là các sheet bộ phận SX, QC, Kho, KT là có sẵn từ trước bạn ạ.
Công việc chỉ là đổ dữ liệu từ sheet Data vào đúng các sheet bộ phận này bạn ạ.

Rất mong bạn giúp đỡ!
Xin cảm ơn.
 
Upvote 0
Chắc "chủ nhân" phải làm sẵn các sheet con thôi (vì phải Format các dòng "rí rí"...ngộ ngộ)
PHP:
Public Sub GPE()
Dim Ws As Worksheet, sArr(), dArr(), I As Long, K 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): K = -7
            ReDim dArr(1 To R * 8, 1 To 3)
            For I = 1 To R
                If UCase(sArr(I, 2)) = Txt Then
                    K = K + 8
                    dArr(K, 1) = sArr(I, 1)
                    dArr(K, 2) = sArr(I, 2)
                    dArr(K, 3) = sArr(I, 4)
                End If
            Next I
            .Range("C4").Resize(1000, 3).ClearContents
            If K > 0 Then .Range("C4").Resize(K, 3) = dArr
        End With
    End If
Next Ws
End Sub
Híc!!!!!!!!

Hihi, Một lần nữa Oanh Thơ lại được bạn giúp đỡ cảm ơn bạn nhiều nhé. Avata của bạn nhìn dễ thương và ấn tượng quá ah.
Oanh Thơ đã chạy thử code của bạn, đối với file đính kèm Oanh Thơ thì kết quả rất OK rồi ạ.
Nhưng Khi Oanh Thơ thêm 1 sheet khác Sheet này không phải là sheet bộ phận hay liên quan gì đến sheet Data cả chỉ là 1 sheet dữ liệu khác thôi ạ.
Sau đó Oanh Thơ chạy code của bạn thì lập tức có một vùng dữ liệu trong sheet này bị mất.

Bạn có thể xử lý lại giúp Oanh Thơ dữ liệu chỉ đưa vào các Sheet có tên bộ phận giống với trường bộ phận trong Sheet Data không ạ, còn các Sheet khác không liên quan ạ.

Xin cảm bạn và diễn đàn nhiều!
 
Upvote 0
Hihi, Một lần nữa Oanh Thơ lại được bạn giúp đỡ cảm ơn bạn nhiều nhé. Avata của bạn nhìn dễ thương và ấn tượng quá ah.
Oanh Thơ đã chạy thử code của bạn, đối với file đính kèm Oanh Thơ thì kết quả rất OK rồi ạ.
Nhưng Khi Oanh Thơ thêm 1 sheet khác Sheet này không phải là sheet bộ phận hay liên quan gì đến sheet Data cả chỉ là 1 sheet dữ liệu khác thôi ạ.
Sau đó Oanh Thơ chạy code của bạn thì lập tức có một vùng dữ liệu trong sheet này bị mất.

Bạn có thể xử lý lại giúp Oanh Thơ dữ liệu chỉ đưa vào các Sheet có tên bộ phận giống với trường bộ phận trong Sheet Data không ạ, còn các Sheet khác không liên quan ạ.

Xin cảm bạn và diễn đàn nhiều!

Bạn tự chỉnh code lại dưới dòng Next I
PHP:
Next I 
            .Range("C4").Resize(1000, 3).ClearContents 
            If K > 0 Then .Range("C4").Resize(K, 3) = dArr
Thành như vầy thử coi.
PHP:
Next I
            If K > 0 Then
                .Range("C4").Resize(1000, 3).ClearContents
                .Range("C4").Resize(K, 3) = dArr
            End If
Có hàng trăm sheet "không liên quan" thì code chạy "vớ vẫn" mệt luôn.
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn tự chỉnh code lại dưới dòng Next I
PHP:
Next I 
            .Range("C4").Resize(1000, 3).ClearContents 
            If K > 0 Then .Range("C4").Resize(K, 3) = dArr
Thành như vầy thử coi.
PHP:
Next I
            If K > 0 Then
                .Range("C4").Resize(1000, 3).ClearContents
                .Range("C4").Resize(K, 3) = dArr
            End If
Có hàng trăm sheet "không liên quan" thì code chạy "vớ vẫn" mệt luôn.

Cảm ơn bạn, ưng quá rồi ! hihi
Bạn cho hỏi thêm K đóng vai trò gì vậy ạ, bạn có thể giải thích cho Oanh Thơ hiểu thêm sự thay đổi này được không ạ.
Với code của bạn trong khi chờ đợi kết quả Oanh Thơ thử sửa lại thành :
If Ws.Name = "SX" Or Ws.Name = "QC" Or Ws.Name = "KT" Or Ws.Name = "Kho" Then

Oanh Thơ thấy kết quả cũng OK ạ.

Cảm ơn bạn nhiều nhé!
 
Upvote 0
Cảm ơn bạn, ưng quá rồi ! hihi
Bạn cho hỏi thêm K đóng vai trò gì vậy ạ, bạn có thể giải thích cho Oanh Thơ hiểu thêm sự thay đổi này được không ạ.
Với code của bạn trong khi chờ đợi kết quả Oanh Thơ thử sửa lại thành :
If Ws.Name = "SX" Or Ws.Name = "QC" Or Ws.Name = "KT" Or Ws.Name = "Kho" Then

Oanh Thơ thấy kết quả cũng OK ạ.

Cảm ơn bạn nhiều nhé!

---K là số lượng (dòng) dữ liệu tìm được thỏa điều kiện ứng với tên Sheet.
Do bảng kết quả của bạn mỗi 1 dòng dữ liệu dán vào kết quả cách nhau 8 dòng "rí rí" nên khi tìm được 1 dòng thì phải cho K công thêm 8.
K mà <=0 thì chẳng làm gì cả.
---Vì chuyện này mà bài #2 Ndu... phải hỏi bạn có "bi nhiêu" sheet kết quả, nếu chỉ 4 sheet thì bạn OR 4 cái là xong. Nếu có 20 sheet kết quả thì bạn phải OR 20 cái!
Tùy trường hợp mà có cách xử lý.
 
Lần chỉnh sửa cuối:
Upvote 0
---K là số lượng (dòng) dữ liệu tìm được thỏa điều kiện ứng với tên Sheet.
Do bảng kết quả của bạn mỗi 1 dòng dữ liệu dán vào kết quả cách nhau 8 dòng "rí rí" nên khi tìm được 1 dòng thì phải cho K công thêm 8.
K mà <=0 thì chẳng làm gì cả.
---Vì chuyện này mà bài #2 Ndu... phải hỏi bạn có "bi nhiêu" sheet kết quả, nếu chỉ 4 sheet thì bạn OR 4 cái là xong. Nếu có 20 sheet kết quả thì bạn phải OR 20 cái!
Tùy trường hợp mà có cách xử lý.

Ahihi,
Cảm ơn bạn nhiều , dù là Oanh Thơ chưa hiểu lắm nhưng cảm thấy rất hứng thú.
Đúng là với file thực của Oanh Thơ thì nhiều Or lắm ạ.. :"'
Một lần nữa cảm ơn bạn ạ.
 
Upvote 0
...
Có hàng trăm sheet "không liên quan" thì code chạy "vớ vẫn" mệt luôn.

Cóp py sang sheet tạm, sort theo tên sheet đầu ra, đọc dữ liệu vào array, xoá sheet tạm.
Bây giờ có thể đọc từ đầu đến cuối. Sheet nào xong mới sang sheet kia. Dữ liệu nào không có tên sheet thì bỏ qua.
 
Upvote 0
Ahihi,
Cảm ơn bạn nhiều , dù là Oanh Thơ chưa hiểu lắm nhưng cảm thấy rất hứng thú.
Đúng là với file thực của Oanh Thơ thì nhiều Or lắm ạ.. :"'
Một lần nữa cảm ơn bạn ạ.

Nếu có nhiều OR và quá nhiều sheet "không liên quan" thì nên tạo 1 bảng danh sách các sheet cần lấy dữ liệu (bằng cách nào đó), số vòng lặp = đúng danh sách, ít "mệt mõi" hơn.
 
Upvote 0
Nếu tổng số sheet là số lớn so với số sheet cần lọc ra. Nói cách khác là nếu chỉ cần lấy ra vài sheets thì có thể dùng ADO để lọc và sort luôn.
Nếu số sheet cần lấy ra rất nhỏ (không hơn 5 sheets) thì có thể dùng vòng lặp gọi từng lệnh SQL lọc theo tên mỗi sheet là giản dị nhất.
 
Upvote 0
Ui, người nổi tiếng!
Oanh Thơ cảm ơn bạn nhiều vì đã quan tâm ạ.

Vâng đúng là các sheet bộ phận SX, QC, Kho, KT là có sẵn từ trước bạn ạ.
Công việc chỉ là đổ dữ liệu từ sheet Data vào đúng các sheet bộ phận này bạn ạ.

Rất mong bạn giúp đỡ!
Xin cảm ơn.

Nếu vậy thì quá dễ, chỉ cần For Next + Advanced Filter là xong:
Mã:
Sub Main()
  Dim wksData As Worksheet, wksSub As Worksheet
  Dim aWksName, shItem
  Set wksData = Worksheets("Data")
  wksData.Range("IV1").Value = wksData.Range("D7").Value
  aWksName = Array("SX", "QC", "Kho", "KT")
  For Each shItem In aWksName
    Set wksSub = Worksheets(CStr(shItem))
    wksSub.Range("C4:E10000").Clear
    wksData.Range("IV2").Value = CStr(shItem)
    wksData.Range("C7:F10000").AdvancedFilter 2, wksData.Range("IV1:IV2"), wksSub.Range("C3:E3")
  Next
  wksData.Range("IV1:IV2").Clear
End Sub
 
Upvote 0
Nếu vậy thì quá dễ, chỉ cần For Next + Advanced Filter là xong:
Mã:
Sub Main()
  Dim wksData As Worksheet, wksSub As Worksheet
  Dim aWksName, shItem
  Set wksData = Worksheets("Data")
  wksData.Range("IV1").Value = wksData.Range("D7").Value
  aWksName = Array("SX", "QC", "Kho", "KT")
  For Each shItem In aWksName
    Set wksSub = Worksheets(CStr(shItem))
    wksSub.Range("C4:E10000").Clear
    wksData.Range("IV2").Value = CStr(shItem)
    wksData.Range("C7:F10000").AdvancedFilter 2, wksData.Range("IV1:IV2"), wksSub.Range("C3:E3")
  Next
  wksData.Range("IV1:IV2").Clear
End Sub

Cũng còn thiếu 1 "chiện", mỗi dòng dữ liệu khi dán vào kết quả sẽ cách nhau 8 dòng "rí rí leo nheo".
 
Upvote 0
Cũng còn thiếu 1 "chiện", mỗi dòng dữ liệu khi dán vào kết quả sẽ cách nhau 8 dòng "rí rí leo nheo".

Nếu tôi theo dõi là chuyện khác, muốn làm cái gì đó thì cứ thêm, sửa, xóa vào sheet Data vậy là xong chuyện, muốn cái gì nữa thì tính tiếp chứ không ai để sẳn mỗi thứ 1 sheet chi cho rắc rối, nhất là cái vụ Insert thêm 8 dòng nữa chẳng biết để làm gì?????

Nếu vài trăm sheet thì không lẽ làm thủ công (đặt mỗi sheet 1 tên).
 
Upvote 0
Hi, Oanh Thơ xin cảm ơn tất cả các bạn nhiều vì đã quan tâm đến đóng góp và giúp đỡ cho bài viết này này của Oanh Thơ ạ.

Nếu tôi theo dõi là chuyện khác, muốn làm cái gì đó thì cứ thêm, sửa, xóa vào sheet Data vậy là xong chuyện, muốn cái gì nữa thì tính tiếp chứ không ai để sẳn mỗi thứ 1 sheet chi cho rắc rối, nhất là cái vụ Insert thêm 8 dòng nữa chẳng biết để làm gì?????

Nếu vài trăm sheet thì không lẽ làm thủ công (đặt mỗi sheet 1 tên).

Cảm ơn bạn đã góp ý ạ.
File thực của Oanh Thơ xin lỗi vì không thể up lên đây được ạ rất mong các bạn thông cảm ạ.
Còn về lý do tại sao Oanh Thơ lại bố trí dữ liệu như vậy, Oanh Thơ xin giải thích thêm ạ.

Sheet Data mục đích để lưu trữ các thông tin dữ liệu cơ sở liên quan đến thông tin của từng người,mỗi người 1 dòng ...
Các sheet bộ phận thì có cấu trúc fom mẫu giống nhau về số dòng số cột để nhập các dữ liệu liên quan của từng người trong 1 tháng ở các cột tiếp theo,
mỗi người sẽ có tất cả 8 hạng mục (8 dòng) các dòng khác không đưa dữ liệu thông tin nhân viên vào nên Oanh Thơ để nhỏ là để các bạn dễ nhìn xuống các dòng dưới .
Và hàng tháng do danh sách ở sheet data có sự thay đổi vì vậy Oanh Thơ mới phải cập nhật lại nhân viên ở sheet data đưa vào các sheet bộ phận này.
Vài trăm sheet thì không đến nhưng tổng thể gộp đủ các bộ phận và các tổ vào cũng đến gần 40 sheet đó ạ.
Và các Sheet này đã được tạo sẵn từ trước ạ.

Cảm ơn bạn nhiều,
Oanh Thơ
 
Upvote 0
Nếu tổng số sheet là số lớn so với số sheet cần lọc ra. Nói cách khác là nếu chỉ cần lấy ra vài sheets thì có thể dùng ADO để lọc và sort luôn.
Nếu số sheet cần lấy ra rất nhỏ (không hơn 5 sheets) thì có thể dùng vòng lặp gọi từng lệnh SQL lọc theo tên mỗi sheet là giản dị nhất.

Xin chào Vetmini, cảm ơn bạn đã quan tâm đến chủ đề này ạ.
Nếu bạn có hứng thú,rất mong bạn giúp đỡ cho bài toàn này của Oanh Thơ bằng code cụ thể theo giải pháp của bạn đề cập được không ạ?
Cảm ơn bạn nhiều,

Oanh Thơ
 
Upvote 0
Nếu vậy thì quá dễ, chỉ cần For Next + Advanced Filter là xong:
Mã:
Sub Main()
  Dim wksData As Worksheet, wksSub As Worksheet
  Dim aWksName, shItem
  Set wksData = Worksheets("Data")
  wksData.Range("IV1").Value = wksData.Range("D7").Value
  aWksName = Array("SX", "QC", "Kho", "KT")
  For Each shItem In aWksName
    Set wksSub = Worksheets(CStr(shItem))
    wksSub.Range("C4:E10000").Clear
    wksData.Range("IV2").Value = CStr(shItem)
    wksData.Range("C7:F10000").AdvancedFilter 2, wksData.Range("IV1:IV2"), wksSub.Range("C3:E3")
  Next
  wksData.Range("IV1:IV2").Clear
End Sub

Cũng còn thiếu 1 "chiện", mỗi dòng dữ liệu khi dán vào kết quả sẽ cách nhau 8 dòng "rí rí leo nheo".

Hi dạ vâng, đúng thế ạ.
Code trên của bạn Oanh Thơ sẽ giữ lại để dùng cho trường hợp khác ạ. :{}:
Rất mong nhận được thêm sự hỗ trợ của bạn.
Cảm ơn các bạn nhiều,
 
Upvote 0
Cóp py sang sheet tạm, sort theo tên sheet đầu ra, đọc dữ liệu vào array, xoá sheet tạm.
Bây giờ có thể đọc từ đầu đến cuối. Sheet nào xong mới sang sheet kia. Dữ liệu nào không có tên sheet thì bỏ qua.
làm tương tự, dùng Dictionary thay sheet tạm
Mã:
Sub GPE()
Dim Ws As Worksheet, Darr(), Dic As Object, i As Long, R As Long, Tmp As String
Darr = Sheets("Data").Range("C9:F" & Sheets("Data").Range("C65500").End(xlUp).Row).Value
Set Dic = CreateObject("scripting.dictionary")
For i = 1 To UBound(Darr)
  If Not Dic.exists(Darr(i, 2)) And Darr(i, 2) <> "" Then
    Dic.Add Darr(i, 2), 1
    Dic.Add Darr(i, 2) & "#" & 1, Array(Darr(i, 1), Darr(i, 2), Darr(i, 4))
  Else
    Dic.Item(Darr(i, 2)) = Dic.Item(Darr(i, 2)) + 1
    Tmp = Darr(i, 2) & "#" & Dic.Item(Darr(i, 2))
    Dic.Add Tmp, Array(Darr(i, 1), Darr(i, 2), Darr(i, 4))
  End If
Next i
For Each Ws In ThisWorkbook.Worksheets
  Tmp = Ws.Name
  If Dic.exists(Tmp) Then
    R = Dic.Item(Tmp)
    ReDim Darr(1 To R * 8, 1 To 3)
    For i = 1 To R
      Darr((i - 1) * 8 + 1, 1) = Dic.Item(Tmp & "#" & i)(0)
      Darr((i - 1) * 8 + 1, 2) = Dic.Item(Tmp & "#" & i)(1)
      Darr((i - 1) * 8 + 1, 3) = Dic.Item(Tmp & "#" & i)(2)
    Next i
    Ws.Range("C4").Resize(1000, 3).ClearContents
    Ws.Range("C4").Resize(R * 8, 3) = Darr
  End If
Next Ws
Set Dic = Nothing:  Set Ws = Nothing:  Erase Darr
End Sub
 
Upvote 0
Xin chào Vetmini, cảm ơn bạn đã quan tâm đến chủ đề này ạ.
Nếu bạn có hứng thú,rất mong bạn giúp đỡ cho bài toàn này của Oanh Thơ bằng code cụ thể theo giải pháp của bạn đề cập được không ạ?
Cảm ơn bạn nhiều,

Oanh Thơ

Lúc đề nghị dùng ADO, tôi quên mất là đề bài này chỉ đơn giản "lọc ra và chép lại" (trừ cái phần thêm 8 dòng trống).
Ngay cái từ "lọc ra và chép lại" đã hàm ý nghĩa advanced filter. Vì vậy cách làm của bạn ndu ở bài #13 là đúng nhất rồi.
ADO chỉ lợi hơn khi bạn cần gom thu (vd tổng các hàng gióng nhau) hay tính toán thêm cột gì đó.
 
Upvote 0
Bài toán 2

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ơ
 

File đính kèm

Upvote 0
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ơ
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
 
Upvote 0
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

ơn Trời, bạn đây rồi }}}}}
Oanh Thơ đã thử code, kết quả dữ liệu trả về ở các sheet bộ phận đã ưng ý rồi bạn ạ.:-=
Nhưng dữ liệu ở các sheet không liên quan như sheet1 bị mất dữ liệu.
Bạn chỉnh lại giúp mình với ạ, có phải lại chỉnh cái phần code dưới Next I giống ở trên phải không bạn,hihi

Cảm ơn bạn nhiều nhé,
Oanh Thơ.
 
Upvote 0
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ơ
 
Upvote 0
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ơ
bạn chạy code mới
Mã:
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
 
Upvote 0
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ơ

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!
 
Upvote 0
bạn chạy code mới
Mã:
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
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 ạ.
Oanh Thơ đã thử code bạn, chuẩn và không có thêm thắc gì nữa ạ. hihi


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!

@@!Hic,
Chàng viết như cho em khác gì đàn gảy tai Trâu chứ.**~**-+*/
Nếu có thời gian,Chàng code cho em điiiiii ạ (T_T) ....
Chắc chàng vẫn nhớ vụ này chứ ạ: -\\/.
https://www.giaiphapexcel.com/forum/showthread.php?121612-Lọc-duy-nhất&p=761301#post761301

Hihihi, nếu Oanh Thơ có gì đắc tội, ndu96081631 bỏ qua nhé.
Cảm ơn bạn nhiều!
Oanh Thơ.
 
Upvote 0
Bài toán 3 -

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ơ
 

File đính kèm

Upvote 0
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ơ
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?
 
Upvote 0
"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?

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ơ.
 
Upvote 0
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?)
 
Lần chỉnh sửa cuối:
Upvote 0
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?)

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.
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 đư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 ạ.
 
Upvote 0
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 ạ.
(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?

(2) Gửi file đó lên xem như nào?
Mỗi bộ phận có một danh sách "Mã số" tương ứng? Có sẵn danh sách này rồi chứ?
Có thể bỏ qua bước trung gian không? Hay nhất thiết phải có bước này?
 
Upvote 0
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ơ
code chỉ thay thế Hàm Vlookup như trong file mẩu
Mã:
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
 
Upvote 0
Anh HieuCD,

Sao anh không chuyển dòng
Mã:
ReDim Arr(1 To 3, 1 To 31)
ra ngoài vòng lặp.
 
Upvote 0
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 phải tạo 1 vùng tùy chọn các sheet cần lấy dữ liệu (G1 -->sang phải)
 

File đính kèm

Upvote 0
Anh HieuCD,
Sao anh không chuyển dòng
Mã:
ReDim Arr(1 To 3, 1 To 31)
ra ngoài vòng lặp.
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]
nếu dữ liệu thật chuẩn như file mẩu thì có thể ăn gian
Mã:
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
 
Lần chỉnh sửa cuối:
Upvote 0
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]


Redim 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)
 
Lần chỉnh sửa cuối:
Upvote 0
Redim 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)
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ông
 
Upvote 0
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ơ
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 đầu
Nói chung code hay công thức, chọn cái nào là tùy vào chuyện ta kiểm soát được mức độ chính xác của kết quả
-------------------------
Kinh nghiệm của tôi là vậy, có gì không đúng xem như tôi chưa nói gì cả
 
Upvote 0
Hi, thật bất ngờ!
Oanh Thơ xin cảm ơn tất cả các bạn rất nhiều vì những ngày cuối năm bộn rộn mà các bạn vẫn dành thời gian để tham gia diễn đàn giúp đỡ Oanh Thơ và mọi người.
Hôm nay Oanh Thơ phải dọn dẹp nhà cửa nên giờ mới thông tin đến các bạn được kính mong các bạn thông cảm ạ.

Oanh Thơ đã thử code của bài 34 và bài 36 code chạy trên file mẫu gửi lên lẹ quá , kết quả rất đúng với ý của Oanh Thơ.
Nhưng khi áp dụng vào file thật thì Oanh Thơ không sử dụng được do có một chút thay đổi về thứ tự dòng cột
và tiêu đề ngày 1 đến 31 trong các sheet bộ phận là định dạng ngày tháng năm.
Oanh Thơ xin gửi file đã sửa lại thứ tự dòng cột và định dạng tiêu đề ngày tháng ở các sheet bộ phận để các bạn xem giúp Oanh Thơ ạ.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
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 đầu
Nói chung code hay công thức, chọn cái nào là tùy vào chuyện ta kiểm soát được mức độ chính xác của kết quả
-------------------------
Kinh nghiệm của tôi là vậy, có gì không đúng xem như tôi chưa nói gì cả

Cảm ơn ndu96081631, đúng như bạn đã nhận xét vì là bất đắc dĩ lên Oanh Thơ mới thay công thức bằng code.
Bất đắc dĩ là vì tệp tin thật của Oanh Thơ cũng khá nặng nhiều công thức trong sheet (nhiều thều viên) nhiều sheet (nhiều bộ phận - tổ) và bao gồm các sheet khác nữa, nhiều định dạng điều kiện v.v... khiến cho tệp tin sử dụng chậm chạp.
Vì vậy Oanh Thơ muốn sử dụng 1 phần code để thay cho công thức mục đích làm nhẹ tệp tin đi ạ.
 
Upvote 0
(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?

(2) Gửi file đó lên xem như nào?
Mỗi bộ phận có một danh sách "Mã số" tương ứng? Có sẵn danh sách này rồi chứ?
Có thể bỏ qua bước trung gian không? Hay nhất thiết phải có bước này?


Xin chào befaint,
Vấn đề 1 thì bạn HieuCD và Ba Tê đã trả lời giúp Oanh Thơ.:-= công việc chỉ là đưa dữ liệu từ sheet data2 sang các sheet bộ phận trong cùng 1 tệp tin bạn ạ.
Còn vấn đề 2. Bước trung gian ở đây là Oanh Thơ đã lấy dữ liệu từ nhiều tệp tin mỗi tệp tin là dữ liệu của 1 tổ hoặc 1 bộ phận (có rất nhiều tệp tin) và dữ liệu được đưa hết vào sheet data2 đó ạ.
Không thể bỏ qua bước này được bạn ah vì vẫn phải cần 1 sheet để tổng hợp tất cả dữ liệu của các tổ và bộ phận vào chung lại làm một.
Nếu bỏ qua bước này thì dữ liệu sẽ không còn lấy từ sheet data2 vào các sheet bộ phận và cũng không phải là đưa dữ liệu từ 1 sheet sang nhiều sheet như chủ đề của Oanh Thơ đã nêu nữa ạ.
Mà lúc này sẽ là đưa dữ liệu từ nhiều tệp tin vào từng sheet theo điề kiện ví dụ (lấy dữ liệu từ tệp tin "SX.xls!Sheet1" vào tệp tin "Cap nhat danh sach (R).xls!SX" , từ tệp tin "KT.xls!Sheet1" vào tệp tin "Cap nhat danh sach (R).xls!KT"....) như vậy bài toán sẽ rất phức tạp và không đúng với chủ đề Oanh Thơ đã nêu ạ.

Cảm ơn bạn rất nhiều!
Oanh Thơ
 
Upvote 0
Còn vấn đề 2. Bước trung gian ở đây là Oanh Thơ đã lấy dữ liệu từ nhiều tệp tin mỗi tệp tin là dữ liệu của 1 tổ hoặc 1 bộ phận (có rất nhiều tệp tin) và dữ liệu được đưa hết vào sheet data2 đó ạ.
...
Không biết bạn tổng hợp từ các file đó vào sheet "Data2" như nào? Hỏi vậy để định làm luôn cả phần đó...
 
Upvote 0
Hi, thật bất ngờ!
Oanh Thơ xin cảm ơn tất cả các bạn rất nhiều vì những ngày cuối năm bộn rộn mà các bạn vẫn dành thời gian để tham gia diễn đàn giúp đỡ Oanh Thơ và mọi người.
Hôm nay Oanh Thơ phải dọn dẹp nhà cửa nên giờ mới thông tin đến các bạn được kính mong các bạn thông cảm ạ.

Oanh Thơ đã thử code của bài 34 và bài 36 code chạy trên file mẫu gửi lên lẹ quá , kết quả rất đúng với ý của Oanh Thơ.
Nhưng khi áp dụng vào file thật thì Oanh Thơ không sử dụng được do có một chút thay đổi về thứ tự dòng cột
và tiêu đề ngày 1 đến 31 trong các sheet bộ phận là định dạng ngày tháng năm.
Oanh Thơ xin gửi file đã sửa lại thứ tự dòng cột và định dạng tiêu đề ngày tháng ở các sheet bộ phận để các bạn xem giúp Oanh Thơ ạ.
trên từng sheet có đủ dữ liệu để xử lý, tại sao phải lấy dữ liệu từ Data2?
Mã:
Sub GPE_1()
    Dim dArr(), sArr(), Arr(), tArr(), Dic As Object, Ws, I As Long, k As Byte, J As Byte, N
    dArr = Sheets("Data2").Range("B14:FC" & Sheets("Data2").Range("B65500").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
    For k = LBound(Ws) To UBound(Ws)
      tArr = Sheets(Ws(k)).Range("J14:AN14").Value
      ReDim Arr(1 To 3, 1 To 31)
      sArr = Sheets(Ws(k)).Range("G1:G" & Sheets(Ws(k)).Range("G65500").End(xlUp).Row).Value
      For I = 15 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)), (Day(tArr(1, J)) - 1) * 5 + N + 3)
            Next J
          Next N
          Sheets(Ws(k)).Range("J" & I + 3).Resize(3, 31) = Arr
        End If
      Next I
    Next k
    Set Dic = Nothing
End Sub
 
Upvote 0
Không biết bạn tổng hợp từ các file đó vào sheet "Data2" như nào? Hỏi vậy để định làm luôn cả phần đó...

Xin chào befaint, cảm ơn bạn đã quan tâm ạ.

Như Oanh Thơ đã giải thích ở bài 42 đây là 1 bài toán khác đó:lấy dữ liệu từ rất nhiều tệp tin vào 1 tệp tin theo nhiều điều kiện
Bài toán này Oanh Thơ đã nhận được sự trợ giúp của một thành viên của diễn đàn code cho rồi ạ.
Hiện code đó chạy rất OK và trong code có các comment hướng dẫn rất chi tiết nên Oanh Thơ cũng chưa có nhu cầu muốn thay đổi ạ.
 
Lần chỉnh sửa cuối:
Upvote 0
@Nguyễn Hoàng Oanh Thơ,

(1) Vậy mọi thứ đã đầy đủ rồi }}}}}}}}}}

(2)
hình như lỗi chính tả...

(3)
Mã:
filename = ThisWorkbook.Path & [COLOR=#0000ff]"" [/COLOR]& bo_phan(index) & ".xls"
Hình như thiếu cái gì đó \
 
Upvote 0
@Nguyễn Hoàng Oanh Thơ,

(1) Vậy mọi thứ đã đầy đủ rồi }}}}}}}}}}

(2) hình như lỗi chính tả...

(3)
Mã:
filename = ThisWorkbook.Path & [COLOR=#0000ff]"" [/COLOR]& bo_phan(index) & ".xls"
Hình như thiếu cái gì đó \

Xin chào befaint,
Đúng rồi ạ,hiện Oanh Thơ đã copy lại code đưa thẳng vào Web, khi nãy Oanh Thơ đã copy ra notepad rồi mới pase vào web không hiểu sao lại bị lỗi thiếu \ như vậy.
 
Lần chỉnh sửa cuối:
Upvote 0
trên từng sheet có đủ dữ liệu để xử lý, tại sao phải lấy dữ liệu từ Data2?
Mã:
Sub GPE_1()
    Dim dArr(), sArr(), Arr(), tArr(), Dic As Object, Ws, I As Long, k As Byte, J As Byte, N
    dArr = Sheets("Data2").Range("B14:FC" & Sheets("Data2").Range("B65500").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
    For k = LBound(Ws) To UBound(Ws)
      tArr = Sheets(Ws(k)).Range("J14:AN14").Value
      ReDim Arr(1 To 3, 1 To 31)
      sArr = Sheets(Ws(k)).Range("G1:G" & Sheets(Ws(k)).Range("G65500").End(xlUp).Row).Value
      For I = 15 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)), (Day(tArr(1, J)) - 1) * 5 + N + 3)
            Next J
          Next N
          Sheets(Ws(k)).Range("J" & I + 3).Resize(3, 31) = Arr
        End If
      Next I
    Next k
    Set Dic = Nothing
End Sub

Xin chào HieuCD,
Oanh Thơ đã chạy code trên của bạn trong file thật kết quả đã OK rồi ạ, cảm ơn bạn rất nhiều.
Bạn cho hỏi thêm trong trường hợp Oanh Thơ chỉ lấy dữ liệu của Item2 và Item3 thôi mà không lấy dữ liệu của Item1 nữa thì code phải thay đổi chỗ nào ạ.
Sở dĩ Item1 là dữ liệu có thể phải sửa lại bằng tay nên sau khi điều chỉnh lại Oanh Thơ không cho cập nhật từ sheet data2 sang nữa bạn ạ.

Còn cầu hỏi bên dưới này của bạn:
trên từng sheet có đủ dữ liệu để xử lý, tại sao phải lấy dữ liệu từ Data2?
Oanh Thơ chưa hiểu ý bạn lắm ạ, nếu Oanh Thơ trả lời không đúng ý bạn mong bạn giải thích thêm ạ.
Vì là trên từng sheet bộ phận chưa có dữ liệu nên Oanh Thơ mới sử dụng công thức VLOOKUP để lấy từ Sheet Data2 sang ạ.
 
Lần chỉnh sửa cuối:
Upvote 0
....................
Bạn cho hỏi thêm trong trường hợp Oanh Thơ chỉ lấy dữ liệu của Item2 và Item3 thôi mà không lấy dữ liệu của Item1 nữa thì code phải thay đổi chỗ nào ạ.
Sở dĩ Item1 là dữ liệu có thể phải sửa lại bằng tay nên sau khi điều chỉnh lại Oanh Thơ không cho cập nhật từ sheet data2 sang nữa bạn ạ.
................

Hình như bạn không khoái cái Sub dài "thoòng" này.
Nó không dình liếu gì với cái tiêu đề là Number hay Date. Cứ từ cột 1 đến 31 mà "phang".
PHP:
Public Sub GPE_2()
Dim Dic As Object, sArr(), dArr(), tArr(), Tem As Long, iTm As Long
Dim I As Long, iK As Long, J As Long, Col As Long, N As Long, Rws As Long
Set Dic = CreateObject("Scripting.Dictionary")
With Sheets("Data2")
    tArr = .Range("G1", .Range("G1").End(xlToRight)).Value
    sArr = .Range("B14", .Range("B65536").End(xlUp)).Resize(, 158).Value
End With
For I = 1 To UBound(sArr)
    Dic.Item(sArr(I, 1)) = I
Next I
For N = 1 To UBound(tArr, 2)
    With Sheets(tArr(1, N))
        Rws = .Range("G65536").End(xlUp).Row
            For iK = 15 To Rws Step 8
                    Tem = .Range("G" & iK): Col = 0
                    If Dic.Exists(Tem) Then
                        iTm = Dic.Item(Tem)
                        ReDim dArr(1 To 2, 1 To 31)
                        For J = 5 To 158 Step 5
                            Col = Col + 1
                            dArr(1, Col) = sArr(iTm, J)
                            dArr(2, Col) = sArr(iTm, J + 1)
                        Next J
                        .Range("J" & iK + 4).Resize(2, 31) = dArr
                    End If
            Next iK
    End With
Next N
Set Dic = Nothing
MsgBox "Da thuc hien xong.", , "GiaiPhapExcel"
End Sub
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Hình như bạn không khoái cái Sub dài "thoòng" này.
Nó không dình liếu gì với cái tiêu đề là Number hay Date. Cứ từ cột 1 đến 31 mà "phang".
PHP:
Public Sub GPE_2()
Dim Dic As Object, sArr(), dArr(), tArr(), Tem As Long, iTm As Long
Dim I As Long, iK As Long, J As Long, Col As Long, N As Long, Rws As Long
Set Dic = CreateObject("Scripting.Dictionary")
With Sheets("Data2")
    tArr = .Range("G1", .Range("G1").End(xlToRight)).Value
    sArr = .Range("B14", .Range("B65536").End(xlUp)).Resize(, 158).Value
End With
For I = 1 To UBound(sArr)
    Dic.Item(sArr(I, 1)) = I
Next I
For N = 1 To UBound(tArr, 2)
    With Sheets(tArr(1, N))
        Rws = .Range("G65536").End(xlUp).Row
            For iK = 15 To Rws Step 8
                    Tem = .Range("G" & iK): Col = 0
                    If Dic.Exists(Tem) Then
                        iTm = Dic.Item(Tem)
                        ReDim dArr(1 To 2, 1 To 31)
                        For J = 5 To 158 Step 5
                            Col = Col + 1
                            dArr(1, Col) = sArr(iTm, J)
                            dArr(2, Col) = sArr(iTm, J + 1)
                        Next J
                        .Range("J" & iK + 4).Resize(2, 31) = dArr
                    End If
            Next iK
    End With
Next N
Set Dic = Nothing
MsgBox "Da thuc hien xong.", , "GiaiPhapExcel"
End Sub

Xin chào Ba Tê cảm ơn bạn rất nhiều vì đã hỗ trợ ạ!
Hihi,không phải là do Oanh Thơ không khoái cái
của bạn ,như đã nêu ở bài 41 vì Oanh Thơ chưa biết cách vận dụng cho file thật của mình thôi ạ.

Nhưng với bài viết này của bạn sau khi đã được bạn chỉnh sửa thì Oanh Thơ đã ứng dụng được vào file thật của mình rồi bạn ạ, kết quả rất OK đúng với mong muốn của Oanh Thơ.
Vậy Oanh Thơ sẽ sử dụng cả 2 code của bạn và bạn HieuCD cho tệp tin của mình ạ. (trong trường hợp lấy 3 Item sử dụng code bài 45. lấy 2 Item sử dụng code bài 50) :-=
(Cả 2 code Oanh Thơ test trong file thật chậm hơn chút xíu so với file mẫu, về số lượng sheet Oanh Thơ vẫn để giống nhau còn về số lượng thành viên trong Sheet Data2 file thật thì nhiều hơn hẳn, có lẽ là vì lý do này mà code chạy chậm hơn).
Oanh Thơ cảm ơn 2 bạn rất nhiều.Nhờ sự nhiệt tình của 2 bạn mà Oanh Thơ đã hoàn thiện được bài toán 3 rồi ạ, ahihihihi.-=.,,

Chỉ còn vài tiếng đồng hồ nữa là chúng ta bước sang năm mới rồi,
Nhân đây Oanh Thơ xin kính chúc tất cả mọi người đón chào một năm mới thật rực rỡ ạ.
Kính chúc diễn đàn ngày một phát triển.
 
Lần chỉnh sửa cuối:
Upvote 0
Theo yêu cầu của bạn Thơ tôi xóa nội dung bài viết này.
Nếu có thể nhờ anh ptm0412 xóa hộ bài này. Cám ơn anh trước.
 
Lần chỉnh sửa cuối:
Upvote 0

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

Back
Top Bottom