VBA tổng hợp các mã hàng và nhân với kênh (1 người xem)

Liên hệ QC

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

tieuthubuongbinh

Học hoài vẫn dốt
Tham gia
3/9/08
Bài viết
567
Được thích
387
Giới tính
Nữ
Chào các tiền bối,

Nhờ mọi người giúp em viết VBA cho bài sau ạ:

1. Sheet 1: mỗi file làm việc của em có danh sách mã hàng khác nhau, giờ em cần tìm 1 danh sách sao cho tất cả các mã hàng đều đủ trong file này. Vd Sheet 1 / Cột A: mã DS có 100 mã, cột B có 80 mã (có mã trùng cột A và mã ko trùng), cột C 120 mã (cũng có trùng và ko trùng).... cột n có n mã...
Giờ em cần sheet 4 cột A sẽ list hết các mã và ko trùng

2. Sheet 2: có 5 kênh => em muốn nhân với danh sách mã hàng sheet 4. vd: có 200 mã sau khi làm bước 1. thì ở sheet 3 sẽ liệt kê 200 mã kênh A2, 200 mã kênh A3.... 200 mã cho kênh n...

3. Sheet 3: đánh số thứ tự toàn bộ dòng hiện ra sau khi làm bước 2.
 

File đính kèm

Chào các tiền bối,

Nhờ mọi người giúp em viết VBA cho bài sau ạ:

1. Sheet 1: mỗi file làm việc của em có danh sách mã hàng khác nhau, giờ em cần tìm 1 danh sách sao cho tất cả các mã hàng đều đủ trong file này. Vd Sheet 1 / Cột A: mã DS có 100 mã, cột B có 80 mã (có mã trùng cột A và mã ko trùng), cột C 120 mã (cũng có trùng và ko trùng).... cột n có n mã...
Giờ em cần sheet 4 cột A sẽ list hết các mã và ko trùng

2. Sheet 2: có 5 kênh => em muốn nhân với danh sách mã hàng sheet 4. vd: có 200 mã sau khi làm bước 1. thì ở sheet 3 sẽ liệt kê 200 mã kênh A2, 200 mã kênh A3.... 200 mã cho kênh n...

3. Sheet 3: đánh số thứ tự toàn bộ dòng hiện ra sau khi làm bước 2.
Đọc nội dung thì thấy cụ thể, rõ ràng.
Sau khi tải File xem và chẳng hiểu phần diễn giải ở bài 1 là diễn giải gì?
 
Lần chỉnh sửa cuối:
Upvote 0
Chào các tiền bối,

Nhờ mọi người giúp em viết VBA cho bài sau ạ:

1. Sheet 1: mỗi file làm việc của em có danh sách mã hàng khác nhau, giờ em cần tìm 1 danh sách sao cho tất cả các mã hàng đều đủ trong file này. Vd Sheet 1 / Cột A: mã DS có 100 mã, cột B có 80 mã (có mã trùng cột A và mã ko trùng), cột C 120 mã (cũng có trùng và ko trùng).... cột n có n mã...
Giờ em cần sheet 4 cột A sẽ list hết các mã và ko trùng

2. Sheet 2: có 5 kênh => em muốn nhân với danh sách mã hàng sheet 4. vd: có 200 mã sau khi làm bước 1. thì ở sheet 3 sẽ liệt kê 200 mã kênh A2, 200 mã kênh A3.... 200 mã cho kênh n...

3. Sheet 3: đánh số thứ tự toàn bộ dòng hiện ra sau khi làm bước 2.
Cho cái ví dụ thử chứ ráng đọc 3 lần mà vẫn chưa hiểu ý? haha
 
Upvote 0
Đọc nội dung thì thấy cụ thể, rõ ràng.
Sau khi tải File xem và chẳng hiểu phần diễn giải ở bài 1 là diễn giải gì?
Cho cái ví dụ thử chứ ráng đọc 3 lần mà vẫn chưa hiểu ý? haha
Nếu làm thủ công thì thế này ạ: em copy cột A đến E của sheet 1 vào sheet 4 theo kiểu nối đuôi nhau (để copy trên 1 cột mà thôi) => remove duplicate => ra 1 danh sách ko trùng và bao gồm tất cả các mã của sheet 1.

Sau đó copy vào sheet 3: danh sách của sheet 4, gõ kênh vào cột C cho hết danh sách này. Copy tiếp danh sách theo kiểu nối đuôi và gõ vào kênh kế tiếp. Vd như vầy. Sau đó đánh số thứ tự để đếm tổng dòng.

215724

Sau khi viết code thì gán lệnh vào mũi tên (vì em chưa rành VBA nên ko biết sao cho nó chạy mỗi lần có dữ liệu mới)
 
Upvote 0
Nếu làm thủ công thì thế này ạ: em copy cột A đến E của sheet 1 vào sheet 4 theo kiểu nối đuôi nhau (để copy trên 1 cột mà thôi) => remove duplicate => ra 1 danh sách ko trùng và bao gồm tất cả các mã của sheet 1.

Sau đó copy vào sheet 3: danh sách của sheet 4, gõ kênh vào cột C cho hết danh sách này. Copy tiếp danh sách theo kiểu nối đuôi và gõ vào kênh kế tiếp. Vd như vầy. Sau đó đánh số thứ tự để đếm tổng dòng.

View attachment 215724

Sau khi viết code thì gán lệnh vào mũi tên (vì em chưa rành VBA nên ko biết sao cho nó chạy mỗi lần có dữ liệu mới)
Có nghĩa gộp thành 1 ô sau đó lọc bỏ trùng ví dụ được 1000 mã sau khi lọc thì sẽ gán từng mã tương ứng với TT,Ecom,... ra 5000 mã hay sao?
 
Upvote 0
Mới vd nhiêu đó cột thôi, chứ thực tế mình sẽ có hơn chục cột đấy, mỗi file qua các thời điểm là nó phát sinh khác nhau. :(
Vậy tạm thời lọc trùng thử cái này
Mã:
Sub Loc()
Dim Sarr(), item, Kq(1 To 600000, 1 To 1), k
Dim DongCuoi As Long
DongCuoi = Sheet4.Cells(Rows.Count, 2).End(xlUp).Row
Application.ScreenUpdating = False
Sarr = Sheet1.[A2:e600000].Value
    For Each item In Sarr
        If item <> "" Then
            k = k + 1
            Kq(k, 1) = item
        End If
    Next
    Sheet4.[B2].Resize(k) = Kq
  Sheet4.Range("B" & DongCuoi).RemoveDuplicates Columns:=1
  Application.ScreenUpdating = True
End Sub
 

File đính kèm

Upvote 0
Bác đang để macro hiểu từ A đến H, cho em xin đến O đi ạ (là được 15 cột sheet 1)
Em thử từ I đến J là ko ra dữ liệu của 2 cột này

Với lại bác cho em xin lọc xong cho ra sheet 4 với (em cần danh sách này để copy cho mục đích khác sheet 3). "Giờ em cần sheet 4 cột A sẽ list hết các mã và ko trùng "

215728[/quote]

@LamNA bài của bạn chưa phải ý mình, dù sao cũng cám ơn bạn nhiều
 
Upvote 0
Bác đang để macro hiểu từ A đến H, cho em xin đến O đi ạ (là được 15 cột sheet 1)
Em thử từ I đến J là ko ra dữ liệu của 2 cột này
Dữ liệu ở hình trên khác với các bài trước.
Cứ đủ tiêu đề ở dòng 1 là được, 1 cột hay 16383 cột vẫn chạy bình thường.

Với lại bác cho em xin lọc xong cho ra sheet 4 với (em cần danh sách này để copy cho mục đích khác sheet 3). "Giờ em cần sheet 4 cột A sẽ list hết các mã và ko trùng "
Đây là yêu cầu mới, lập chủ đề mới. Hoặc chịu khó lọc 1 channel rồi copy lấy.

Lỡ không nêu ngay từ đầu rồi thì phải chịu thôi.
 
Upvote 0
Dữ liệu ở hình trên khác với các bài trước.
Cứ đủ tiêu đề ở dòng 1 là được, 1 cột hay 16383 cột vẫn chạy bình thường.
à em hiểu rồi.

Đây là yêu cầu mới, lập chủ đề mới. Hoặc chịu khó lọc 1 channel rồi copy lấy.

Lỡ không nêu ngay từ đầu rồi thì phải chịu thôi.
Em yêu cầu ngay bài #1 mà bác. Mà ko sao, dù sao cũng có sheet 3 để lọc manual rồi :)

Chúc bác ngủ ngon. Cám ơn bác rất nhiều ạ.
 
Upvote 0
Dữ liệu của bạn quá lớn; nên coi chừng có lúc không đủ bộ nhớ cho máy làm việc;
Bài 10 đã đáp ứng iêu cầu của bạn rồi; Chỉ có điều tác giả nhắc bạn rằng, Cột nào có số liệu bên dưới thì có tên tiêu đề cột (từ cột đầu cho tới cột cuối)
 
Upvote 0
Dữ liệu của bạn quá lớn; nên coi chừng có lúc không đủ bộ nhớ cho máy làm việc;
Bài 10 đã đáp ứng iêu cầu của bạn rồi; Chỉ có điều tác giả nhắc bạn rằng, Cột nào có số liệu bên dưới thì có tên tiêu đề cột (từ cột đầu cho tới cột cuối)
Dạ, con thử xem để data vào các cột xa xa có chạy ko nhưng lại ko biết phải để tiêu đề. Bây giờ thì con hiểu rồi ạ.
Dữ liệu con làm việc hằng ngày thì cũng 1/3 số dòng đó rồi đó bác.
Chúc bác ngày chủ nhật an lành ạ.
 
Upvote 0
Bác đang để macro hiểu từ A đến H, cho em xin đến O đi ạ (là được 15 cột sheet 1)
Em thử từ I đến J là ko ra dữ liệu của 2 cột này
Với lại bác cho em xin lọc xong cho ra sheet 4 với (em cần danh sách này để copy cho mục đích khác sheet 3). "Giờ em cần sheet 4 cột A sẽ list hết các mã và ko trùng "
Theo tôi đề xuất bạn nên đi theo hướng khác, thế này:
1/ Sheet1: Nên làm danh mục duy nhất vì mỗi mã code nó có thể đi kèm theo 1 số thông tin khác (chưa hiểu thông tin gì?) có thể là đơn vị tính, đơn giá hay nhà cung cấp.
2/ Muốn nhập liệu cái gì đó thì tra danh mục (Sheet1), sau đó muốn Insert bao nhiêu dòng thì cho nó 1 con số 3, 5, 7 gì đó thì sẽ thực tế hơn là tra danh sách Sheet2 rồi gán mỗi mã code 200 lần (như vậy thì sẽ có rất nhiều dòng không dùng đến) sẽ gây lãng phí tái nguyên, thêm sự phức tạp và làm tăng dung lượng File và sẽ có ngày không sử dụng được File này nữa vì nó quá ì ạch.
 
Upvote 0
Theo tôi đề xuất bạn nên đi theo hướng khác, thế này:
1/ Sheet1: Nên làm danh mục duy nhất vì mỗi mã code nó có thể đi kèm theo 1 số thông tin khác (chưa hiểu thông tin gì?) có thể là đơn vị tính, đơn giá hay nhà cung cấp.
2/ Muốn nhập liệu cái gì đó thì tra danh mục (Sheet1), sau đó muốn Insert bao nhiêu dòng thì cho nó 1 con số 3, 5, 7 gì đó thì sẽ thực tế hơn là tra danh sách Sheet2 rồi gán mỗi mã code 200 lần (như vậy thì sẽ có rất nhiều dòng không dùng đến) sẽ gây lãng phí tái nguyên, thêm sự phức tạp và làm tăng dung lượng File và sẽ có ngày không sử dụng được File này nữa vì nó quá ì ạch.
Dạ, để con giải thích vì sao con cần cách làm này.
1/ Con có vd 10 file báo cáo, mỗi file tại 1 thời điểm tháng/tuần khác nhau mà sẽ có số lượng code khác nhau.
Có 1 file chuẩn chạy từ SAP thì đủ các code, nhưng vì có khi mỗi tuần có code mới thì các file đang làm việc sẽ thiếu code đó, và chưa kể là file dự báo thì ko có code cũ, mà file số thực thì rất nhiều code cũ (bán cho hết hàng), nên khi con cài hàm thì total lại ko bằng nhau (vd File 1 có 10 code thì ra 50 tổng, nhưng file 2 có 8 code thì ra 45 tổng, làm cho con phải đi kiểm tra xem sai ở đâu rất mất thời gian). Nên con tạo ra bài này là để kiểm tra chéo xem các file đang liên kết data tính toán bị thiếu và cần bổ sung các code nào. Dạ đúng là code sẽ đi kèm rất nhiều thông tin khác nữa.
=> bài này sẽ làm ra danh mục sheet 1 mà bác nói ạ là luôn chứa đủ các code (vì con sợ file chuẩn chạy từ SAP có khi họ deactivate 1 code nào đó sẽ ko chạy ra, trong khi vẫn đang cần code này cho dữ liệu quá khứ).

2/ Nhờ bác tư vấn giúp con: nếu con có sheet 2 dài vậy và có những code ra 0 toàn bộ dữ liệu đang tính (vd code đó có doanh số của 2016 mà bây giờ con chỉ tính toán từ 2017 trở đi => con có thể thêm 1 macro để tự xóa các dòng bằng 0 để file ngắn lại hay là đi insert như bác nói (tại con chưa hiểu lắm ý 2 của bác)
 
Upvote 0
Chào các tiền bối,

Nhờ mọi người giúp em viết VBA cho bài sau ạ:

1. Sheet 1: mỗi file làm việc của em có danh sách mã hàng khác nhau, giờ em cần tìm 1 danh sách sao cho tất cả các mã hàng đều đủ trong file này. Vd Sheet 1 / Cột A: mã DS có 100 mã, cột B có 80 mã (có mã trùng cột A và mã ko trùng), cột C 120 mã (cũng có trùng và ko trùng).... cột n có n mã...
Giờ em cần sheet 4 cột A sẽ list hết các mã và ko trùng

2. Sheet 2: có 5 kênh => em muốn nhân với danh sách mã hàng sheet 4. vd: có 200 mã sau khi làm bước 1. thì ở sheet 3 sẽ liệt kê 200 mã kênh A2, 200 mã kênh A3.... 200 mã cho kênh n...

3. Sheet 3: đánh số thứ tự toàn bộ dòng hiện ra sau khi làm bước 2.
Insert Sheet4 và thử code
Mã:
Sub GhepData()
  Dim Rng As Range, Dic As Object, iKey
  Dim sArr(), tArr(), Res(), Res2()
  Dim i As Long, n As Long, k As Long, ik As Long, sRow As Long, eRow As Long

  Set Rng = Sheet1.UsedRange
  If Rng.Rows.Count < 2 Then MsgBox "Khong co du lieu": Exit Sub
  sArr = Rng.Offset(1).Resize(Rng.Rows.Count - 1).Value
  ReDim Res(1 To UBound(sArr, 1) * UBound(sArr, 2), 1 To 1)
 
  With CreateObject("scripting.dictionary")
    For Each iKey In sArr
      If Len(iKey) > 0 Then
        If .exists(iKey) = False Then
          .Add iKey, ""
          k = k + 1
          Res(k, 1) = iKey
        End If
      End If
    Next iKey
  End With
 
  If k > 0 Then
    With Sheet4
      eRow = .Range("A1000000").End(xlUp).Row
      If eRow > 1 Then .Range("A2:A" & eRow).ClearContents
      .Range("A2").Resize(k) = Res
    End With
    
    tArr = Sheet2.Range("A1:A5").Value
    sRow = UBound(tArr)
    ReDim Res2(1 To k * sRow, 1 To 3)
    For n = 1 To sRow
      For i = 1 To k
        ik = ik + 1:              Res2(ik, 1) = ik
        Res2(ik, 2) = Res(i, 1):  Res2(ik, 3) = tArr(n, 1)
      Next i
    Next n
    eRow = Rows.Count - 1
    If ik > eRow Then
      MsgBox "Nhieu ket qua >> " & eRow
      ik = eRow
    End If
    With Sheet3
      .Range("A2:C" & eRow + 1).ClearContents
      .Range("A2").Resize(ik, 3).Value = Res2
    End With
  End If
End Sub
 
Upvote 0
QUOTE="HieuCD, post: 913916, member: 373036"]
Insert Sheet4 và thử code
[/QUOTE]
Cám ơn bác, em làm được rồi ạ. Nhưng sao khi em xóa hết dữ liệu ở sheet 1 thì sheet 4 vẫn để nguyên danh sách cũ, bác cho em xin cái msgbox "Không có dữ liệu" với ạ

Em xin thêm code ở sheet 5 được ko ạ?
Sheet 5 có số cột và tiêu đề bằng sheet 1 (vd: nếu sheet 1 em thêm tiêu đề cho n cột thì sheet 5 cũng có những cột mới này)
Sau đó, liệt kê những code bị thiếu ở sheet 4 sau khi so sánh cho từng cột tương ứng của sheet 1:
Vd: Đem cột A sheet 1 đi so sánh với sheet 4 và liệt kê mã bị thiếu
 
Lần chỉnh sửa cuối:
Upvote 0
QUOTE="HieuCD, post: 913916, member: 373036"]
Insert Sheet4 và thử code
Cám ơn bác, em làm được rồi ạ. Nhưng sao khi em xóa hết dữ liệu ở sheet 1 thì sheet 4 vẫn để nguyên danh sách cũ, bác cho em xin cái msgbox "Không có dữ liệu" với ạ

Em xin thêm code ở sheet 5 được ko ạ?
Sheet 5 có số cột và tiêu đề bằng sheet 1 (vd: nếu sheet 1 em thêm tiêu đề cho n cột thì sheet 5 cũng có những cột mới này)
Sau đó, liệt kê những code bị thiếu ở sheet 4 sau khi so sánh cho từng cột tương ứng của sheet 1:
Vd: Đem cột A sheet 1 đi so sánh với sheet 4 và liệt kê mã bị thiếu
[/QUOTE]
Sheet4 lấy dữ liệu từ sheet1, nên không thể thiếu
Chỉnh lại code
Mã:
Sub GhepData()
  Dim Rng As Range, Dic As Object, iKey
  Dim sArr(), tArr(), Res(), Res2()
  Dim i As Long, n As Long, k As Long, ik As Long, sRow As Long, eRow As Long
 
  With Sheet3
    eRow = .Range("A" & Rows.Count).End(xlUp).Row
    If eRow > 1 Then .Range("A2:C" & eRow).ClearContents
  End With
  With Sheet4
    eRow = .Range("A" & Rows.Count).End(xlUp).Row
    If eRow > 1 Then .Range("A2:A" & eRow).ClearContents
  End With
 
  Set Rng = Sheet1.UsedRange
  If Rng.Rows.Count < 2 Then MsgBox "Khong co du lieu": Exit Sub
  sArr = Rng.Offset(1).Resize(Rng.Rows.Count - 1).Value
  ReDim Res(1 To UBound(sArr, 1) * UBound(sArr, 2), 1 To 1)
 
  With CreateObject("scripting.dictionary")
    For Each iKey In sArr
      If Len(iKey) > 0 Then
        If .exists(iKey) = False Then
          .Add iKey, ""
          k = k + 1
          Res(k, 1) = iKey
        End If
      End If
    Next iKey
  End With
  If k > 0 Then
    Sheet4.Range("A2").Resize(k) = Res
    
    tArr = Sheet2.Range("A1:A5").Value
    sRow = UBound(tArr)
    ReDim Res2(1 To k * sRow, 1 To 3)
    For n = 1 To sRow
      For i = 1 To k
        ik = ik + 1:              Res2(ik, 1) = ik
        Res2(ik, 2) = Res(i, 1):  Res2(ik, 3) = tArr(n, 1)
      Next i
    Next n
    eRow = Rows.Count - 1
    If ik > eRow Then
      MsgBox "Nhieu ket qua >> " & eRow
      ik = eRow
    End If
    Sheet3.Range("A2").Resize(ik, 3).Value = Res2
  End If
End Sub
 
Upvote 0
Dạ, để con giải thích vì sao con cần cách làm này.
1/ Con có vd 10 file báo cáo, mỗi file tại 1 thời điểm tháng/tuần khác nhau mà sẽ có số lượng code khác nhau.
Có 1 file chuẩn chạy từ SAP thì đủ các code, nhưng vì có khi mỗi tuần có code mới thì các file đang làm việc sẽ thiếu code đó, và chưa kể là file dự báo thì ko có code cũ, mà file số thực thì rất nhiều code cũ (bán cho hết hàng), nên khi con cài hàm thì total lại ko bằng nhau (vd File 1 có 10 code thì ra 50 tổng, nhưng file 2 có 8 code thì ra 45 tổng, làm cho con phải đi kiểm tra xem sai ở đâu rất mất thời gian). Nên con tạo ra bài này là để kiểm tra chéo xem các file đang liên kết data tính toán bị thiếu và cần bổ sung các code nào. Dạ đúng là code sẽ đi kèm rất nhiều thông tin khác nữa.
=> bài này sẽ làm ra danh mục sheet 1 mà bác nói ạ là luôn chứa đủ các code (vì con sợ file chuẩn chạy từ SAP có khi họ deactivate 1 code nào đó sẽ ko chạy ra, trong khi vẫn đang cần code này cho dữ liệu quá khứ).

2/ Nhờ bác tư vấn giúp con: nếu con có sheet 2 dài vậy và có những code ra 0 toàn bộ dữ liệu đang tính (vd code đó có doanh số của 2016 mà bây giờ con chỉ tính toán từ 2017 trở đi => con có thể thêm 1 macro để tự xóa các dòng bằng 0 để file ngắn lại hay là đi insert như bác nói (tại con chưa hiểu lắm ý 2 của bác)
Góp ý cho bạn:
1/Tại bài 19 bạn có nêu file chuẩn chạy từ SAP: Tốt nhất là nên đưa file chuẩn lên để mọi người xem và có hiểu cấu trúc mới đề ra phương án thích hợp.
2/ Nếu giải thích như bài 19 thì có thể làm theo hướng sau:
- Gộp 10 File vào lấy tất cả các mã code vào sheet1.
- Nhập tên kênh vào cột A sheet2, nhập số lượng dòng cần Insert vào cột B (dựa vào số lượng tại đây để Insert số dòng cần vào sheet4), gõ số lượng bao nhiêu thì nó Insert bao nhiêu (bạn chơi mỗi thứ đến 200 dòng nên có nhiều dòng thừa không cần thiết).
- Lấy dữ liệu sheet1 vào sheet4, gán code cần vào cột B, lấy kênh và số lượng vào sheet4, Insert số dòng cần và gán cột C.
 
Upvote 0
Sheet 5 có số cột và tiêu đề bằng sheet 1 (vd: nếu sheet 1 em thêm tiêu đề cho n cột thì sheet 5 cũng có những cột mới này)
Sau đó, liệt kê những code bị thiếu ở sheet 4 sau khi so sánh cho từng cột tương ứng của sheet 1:
Vd: Đem cột A sheet 1 đi so sánh với sheet 4 và liệt kê mã bị thiếu

Sheet4 lấy dữ liệu từ sheet1, nên không thể thiếu
Chỉnh lại code
Ý em là sheet 5 liệt kê những code bị thiếu trong từng cột. Vd cột SFC sheet 1 chỉ có a và d, so sánh với sheet 4 thì là bị thiếu b,c,e nên sẽ liệt kê ra ở sheet 5 cột SFC
215915
 
Upvote 0
Ý em là sheet 5 liệt kê những code bị thiếu trong từng cột. Vd cột SFC sheet 1 chỉ có a và d, so sánh với sheet 4 thì là bị thiếu b,c,e nên sẽ liệt kê ra ở sheet 5 cột SFC
View attachment 215915
Insert Sheet5
Mã:
Option Explicit

Sub GhepData()
  Dim Rng As Range, Dic As Object, iKey, tmp As String
  Dim sArr(), tArr(), Res(), Res2(), Res3()
  Dim i As Long, j As Long, n As Long, k As Long, ik As Long, sRow As Long, eRow As Long

  With Sheet3
    eRow = .Range("A" & Rows.Count).End(xlUp).Row
    If eRow > 1 Then .Range("A2:C" & eRow).ClearContents
  End With
  With Sheet4
    eRow = .Range("A" & Rows.Count).End(xlUp).Row
    If eRow > 1 Then .Range("A2:A" & eRow).ClearContents
  End With
 
  Set Rng = Sheet1.UsedRange
  If Rng.Rows.Count < 2 Then MsgBox "Khong co du lieu": Exit Sub
  sArr = Rng.Offset(1).Resize(Rng.Rows.Count - 1).Value
  ReDim Res(1 To UBound(sArr, 1) * UBound(sArr, 2), 1 To 1)
  ReDim Res3(1 To UBound(sArr, 1) + 1, 1 To UBound(sArr, 2))
 
  With CreateObject("scripting.dictionary")
    For i = 1 To UBound(sArr)
      For j = 1 To UBound(sArr, 2)
        iKey = sArr(i, j)
        If Len(iKey) > 0 Then
          If .exists(iKey) = False Then
            .Add iKey, "," & j & ","
            k = k + 1
            Res(k, 1) = iKey
          Else
            tmp = .Item(iKey)
            If InStr(1, tmp, "," & j & ",") = 0 Then .Item(iKey) = tmp & j & ","
          End If
        End If
      Next j
    Next i
 
    If k > 0 Then
      Sheet4.Range("A2").Resize(k) = Res
    
      tArr = Sheet2.Range("A1:A5").Value
      sRow = UBound(tArr)
      ReDim Res2(1 To k * sRow, 1 To 3)
      For n = 1 To sRow
        For i = 1 To k
          ik = ik + 1:              Res2(ik, 1) = ik
          Res2(ik, 2) = Res(i, 1):  Res2(ik, 3) = tArr(n, 1)
        Next i
      Next n
      eRow = Rows.Count - 1
      If ik > eRow Then
        MsgBox "Nhieu ket qua >> " & eRow
        ik = eRow
      End If
      Sheet3.Range("A2").Resize(ik, 3).Value = Res2
      
      sRow = UBound(Res3)
      For Each iKey In .keys
        tmp = .Item(iKey)
        For j = 1 To UBound(Res3, 2)
          If InStr(1, tmp, "," & j & ",") = 0 Then
            Res3(sRow, j) = Res3(sRow, j) + 1
            Res3(Res3(sRow, j), j) = iKey
          End If
        Next j
      Next iKey
      With Sheet5
        .UsedRange.ClearContents
        .Range("A1").Resize(, UBound(Res3, 2)).Value = Sheet1.Range("A1").Resize(, UBound(Res3, 2)).Value
        .Range("A2").Resize(sRow - 1, UBound(Res3, 2)).Value = Res3
      End With
    End If
  End With
End Sub
 
Upvote 0
Insert Sheet5
Mã:
Option Explicit

Sub GhepData()
  Dim Rng As Range, Dic As Object, iKey, tmp As String
  Dim sArr(), tArr(), Res(), Res2(), Res3()
  Dim i As Long, j As Long, n As Long, k As Long, ik As Long, sRow As Long, eRow As Long

  With Sheet3
    eRow = .Range("A" & Rows.Count).End(xlUp).Row
    If eRow > 1 Then .Range("A2:C" & eRow).ClearContents
  End With
  With Sheet4
    eRow = .Range("A" & Rows.Count).End(xlUp).Row
    If eRow > 1 Then .Range("A2:A" & eRow).ClearContents
  End With

  Set Rng = Sheet1.UsedRange
  If Rng.Rows.Count < 2 Then MsgBox "Khong co du lieu": Exit Sub
  sArr = Rng.Offset(1).Resize(Rng.Rows.Count - 1).Value
  ReDim Res(1 To UBound(sArr, 1) * UBound(sArr, 2), 1 To 1)
  ReDim Res3(1 To UBound(sArr, 1) + 1, 1 To UBound(sArr, 2))

  With CreateObject("scripting.dictionary")
    For i = 1 To UBound(sArr)
      For j = 1 To UBound(sArr, 2)
        iKey = sArr(i, j)
        If Len(iKey) > 0 Then
          If .exists(iKey) = False Then
            .Add iKey, "," & j & ","
            k = k + 1
            Res(k, 1) = iKey
          Else
            tmp = .Item(iKey)
            If InStr(1, tmp, "," & j & ",") = 0 Then .Item(iKey) = tmp & j & ","
          End If
        End If
      Next j
    Next i

    If k > 0 Then
      Sheet4.Range("A2").Resize(k) = Res
   
      tArr = Sheet2.Range("A1:A5").Value
      sRow = UBound(tArr)
      ReDim Res2(1 To k * sRow, 1 To 3)
      For n = 1 To sRow
        For i = 1 To k
          ik = ik + 1:              Res2(ik, 1) = ik
          Res2(ik, 2) = Res(i, 1):  Res2(ik, 3) = tArr(n, 1)
        Next i
      Next n
      eRow = Rows.Count - 1
      If ik > eRow Then
        MsgBox "Nhieu ket qua >> " & eRow
        ik = eRow
      End If
      Sheet3.Range("A2").Resize(ik, 3).Value = Res2
     
      sRow = UBound(Res3)
      For Each iKey In .keys
        tmp = .Item(iKey)
        For j = 1 To UBound(Res3, 2)
          If InStr(1, tmp, "," & j & ",") = 0 Then
            Res3(sRow, j) = Res3(sRow, j) + 1
            Res3(Res3(sRow, j), j) = iKey
          End If
        Next j
      Next iKey
      With Sheet5
        .UsedRange.ClearContents
        .Range("A1").Resize(, UBound(Res3, 2)).Value = Sheet1.Range("A1").Resize(, UBound(Res3, 2)).Value
        .Range("A2").Resize(sRow - 1, UBound(Res3, 2)).Value = Res3
      End With
    End If
  End With
End Sub
Đọc code xong. kaka

215923
 
Upvote 0
Đúng rồi ạ, với cách này thì em ko cần code sheet 4 nữa vì các cột rỗng ở sheet 1 nó tự xuất hiện cả danh sách ko trùng ở sheet 5 luôn.
Cám ơn anh nhiều lắm ạ.

@LamNA mình ko cần uống vì ko cần đọc luôn hihi. Miễn xài được là ok haha. Mình ko biết xíu gì về VBA thành ra vậy đó.
 
Upvote 0
Anh cho em hỏi, nếu mà text là số (vd "1") và number 1. Nó đang hiểu là 2 giá trị ko trùng, có cách ràng cho nó thành trùng ko anh? tại dữ liệu mã hàng của em xuất từ SAP ra nó hay là kiểu text, mà em so với file excel database thì nó là number.
Nếu khắc phục được thì tốt còn ko em xử lý kiểu text hết trước khi chạy macro cũng được ạ.
Code của bác @befaint cũng bị tương tự.
 
Upvote 0
Anh cho em hỏi, nếu mà text là số (vd "1") và number 1. Nó đang hiểu là 2 giá trị ko trùng, có cách ràng cho nó thành trùng ko anh? tại dữ liệu mã hàng của em xuất từ SAP ra nó hay là kiểu text, mà em so với file excel database thì nó là number.
Nếu khắc phục được thì tốt còn ko em xử lý kiểu text hết trước khi chạy macro cũng được ạ.
Code của bác @befaint cũng bị tương tự.
Khi dùng Dictionary nên chuyển key thành String, tốc độ xử lý sẽ nhanh hơn, ví dụ
iKey = cStr(sArr(i, j))
 
Upvote 0
Góp ý cho bạn:
1/Tại bài 19 bạn có nêu file chuẩn chạy từ SAP: Tốt nhất là nên đưa file chuẩn lên để mọi người xem và có hiểu cấu trúc mới đề ra phương án thích hợp.
Dạ, con gửi bác xem file SAP chạy ra.
Vì file này là toàn bộ các mã của nhiều phòng ban nên con chỉ muốn hiện ra danh sach và các cột con cần ở sheet Database theo filter ở sheet 3!B1
Con nhờ bác viết giúp VBA ạ, để sau đó, còn làm tiếp bước 2 của bác.
File thực có chừng 50k dòng.
PS: Dữ liệu gốc này còn phải chuyển đổi qua các điều kiện khác để cho ra 1 bảng dữ liệu khác, lúc đó con mới dựa trên bảng mới này mà xử lý thông tin về bán hàng.
Bài đã được tự động gộp:

Khi dùng Dictionary nên chuyển key thành String, tốc độ xử lý sẽ nhanh hơn, ví dụ
iKey = cStr(sArr(i, j))
Dạ em ko biết gì về VBA nên em cũng chưa hiểu phải sửa làm sao.
Anh cho em xin thêm 1 sheet 6, liệt kê các mã bị trùng (giống sheet 5 nhưng thay vì code không trùng thì giờ là code bị trùng)
Vì có khi em copy mấy chục ngàn dòng và vì nó chỉ toàn trùng nên sheet 5 lại ko sử dụng được. Mà đi countif rồi lấy ra thì cũng hơi thủ công (mà có khi file nặng quá chạy rất lâu).
Xin lỗi anh vì lúc đầu em ko nghĩ ra mình cần gì, thao tác trên thực tế mới thấy bị vướng và đành xin thêm code. Mong anh thông cảm cho.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Dạ, con gửi bác xem file SAP chạy ra.
Vì file này là toàn bộ các mã của nhiều phòng ban nên con chỉ muốn hiện ra danh sach và các cột con cần ở sheet Database theo filter ở sheet 3!B1
Con nhờ bác viết giúp VBA ạ, để sau đó, còn làm tiếp bước 2 của bác.
File thực có chừng 50k dòng.
PS: Dữ liệu gốc này còn phải chuyển đổi qua các điều kiện khác để cho ra 1 bảng dữ liệu khác, lúc đó con mới dựa trên bảng mới này mà xử lý thông tin về bán hàng.
Bài đã được tự động gộp:


Dạ em ko biết gì về VBA nên em cũng chưa hiểu phải sửa làm sao.
Anh cho em xin thêm 1 sheet 6, liệt kê các mã bị trùng (giống sheet 5 nhưng thay vì code không trùng thì giờ là code bị trùng)
Vì có khi em copy mấy chục ngàn dòng và vì nó chỉ toàn trùng nên sheet 5 lại ko sử dụng được. Mà đi countif rồi lấy ra thì cũng hơi thủ công (mà có khi file nặng quá chạy rất lâu).
Xin lỗi anh vì lúc đầu em ko nghĩ ra mình cần gì, thao tác trên thực tế mới thấy bị vướng và đành xin thêm code. Mong anh thông cảm cho.
Tạo topic mới và gởi bài lên
 
Upvote 0

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

Back
Top Bottom