Giúp viết code cho công thức Mảng (index, match) (1 người xem)

  • Thread starter Thread starter outway
  • Ngày gửi Ngày gửi
Liên hệ QC

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

outway

Thành viên mới
Tham gia
17/10/10
Bài viết
8
Được thích
1
Tình hình là mình có file ex quản lý kiểm kê của 3x cửa hàng, data có thể lên đến 100000 dòng.
các câu lệnh mảng làm cho file QUÁ NẶNG, không chạy nổi. Nhờ các cao thủ viết code giùm phần tham chiếu SHORTAGE QTT,ÊXCESS QTT ở các sheet THIEU, THUA vào sheet SUM DATA.

HIỆN TẠI ĐANG DÙNG CÔNG THỨC MẢNG RỒI FILL: {=INDEX(THIEU!$A$4:$E$37,MATCH('SUM DATA'!B4&'SUM DATA'!F4,THIEU!$B$4:$B$37&THIEU!$E$4:$E$37,0),4)}

CẢM ƠN TRƯỚC.
 

File đính kèm

Tình hình là mình có file ex quản lý kiểm kê của 3x cửa hàng, data có thể lên đến 100000 dòng.
các câu lệnh mảng làm cho file QUÁ NẶNG, không chạy nổi. Nhờ các cao thủ viết code giùm phần tham chiếu SHORTAGE QTT,ÊXCESS QTT ở các sheet THIEU, THUA vào sheet SUM DATA.

HIỆN TẠI ĐANG DÙNG CÔNG THỨC MẢNG RỒI FILL: {=INDEX(THIEU!$A$4:$E$37,MATCH('SUM DATA'!B4&'SUM DATA'!F4,THIEU!$B$4:$B$37&THIEU!$E$4:$E$37,0),4)}

CẢM ƠN TRƯỚC.
Thử thế này xem sao
PHP:
Sub test()
Dim data(), thieu(), thua(), i, j, k
data = Range([B4], [B65536].End(3)).Resize(, 5).Value
With Sheets("THIEU")
   thieu = .Range(.[B4], .[B65536].End(3)).Resize(, 5).Value
End With
With Sheets("THUA")
   thua = .Range(.[B4], .[B65536].End(3)).Resize(, 4).Value
End With
For i = 1 To UBound(data)
   For j = 1 To UBound(thieu)
      If data(i, 1) & data(i, 5) = thieu(j, 1) & thieu(j, 4) Then
         data(i, 3) = thieu(j, 3)
      End If
   Next
   For k = 1 To UBound(thua)
      If data(i, 1) & data(i, 5) = thua(k, 1) & thua(k, 4) Then
         data(i, 4) = thua(k, 3)
      End If
   Next
Next
[B4].Resize(i - 1, 5) = data
End Sub
 
Upvote 0
Thử thế này xem sao
PHP:
Sub test()
Dim data(), thieu(), thua(), i, j, k
data = Range([B4], [B65536].End(3)).Resize(, 5).Value
With Sheets("THIEU")
   thieu = .Range(.[B4], .[B65536].End(3)).Resize(, 5).Value
End With
With Sheets("THUA")
   thua = .Range(.[B4], .[B65536].End(3)).Resize(, 4).Value
End With
For i = 1 To UBound(data)
   For j = 1 To UBound(thieu)
      If data(i, 1) & data(i, 5) = thieu(j, 1) & thieu(j, 4) Then
.....................
End Sub

Anh Hải cho e hỏi : tại sao anh không dùng .Autofiltermode = flase, vì nếu dùng End(3) khi đang ở chế độ filter ---> e rằng kích thước vùng dữ liệu sẽ không đúng
 
Lần chỉnh sửa cuối:
Upvote 0
Anh Hải cho e hỏi : tại sao anh không dùng .Autofiltermode = flase, vì nếu dùng End(3) khi đang ở chế độ filter ---> e rằng kích thước vùng dữ liệu sẽ không đúng
Ai biết đâu, nếu chủ topic để chế độ filter thì ráng chịu chứ.
Nếu muốn an toàn thì thêm cái sự kiện hủy chế độ filter khi thoát sheet
 
Upvote 0
Cảm ơn anh hải nhiều. đã thực hiện đúng yêu cầu
 
Upvote 0
dear a. Hải,

Code của anh chạy kết quả đúng, nhưng có lẽ thuật toán chưa tối ưu lắm.
em là newbie nên không hiểu ngôn ngữ này lắm.
Vấn đề ở chỗ, em có CSDL hơn 100.000 dòng. và em đã áp dụng cách của anh vào.
Nhưng thời gian chạy của nó hơn 20 phút. ?????\

So sánh với thời gian em lưu macro Hàm Index rồi Fill to End thì chỉ mất 15phút thôi.
Anh có cách nào tối ưu hơn không? Thanks anh trước
 
Upvote 0
Bạn thử dùng Code này xem sao
Mã:
Sub SoSanh()
    Dim data(), thieu(), thua(), Res(), i As Long, k As Long
    data = Range([B4], [B65536].End(3)).Resize(, 5).Value
    With Sheets("THIEU")
        thieu = .Range(.[B4], .[B65536].End(3)).Resize(, 5).Value
    End With
    With Sheets("THUA")
        thua = .Range(.[B4], .[B65536].End(3)).Resize(, 4).Value
    End With


    ReDim Res(1 To UBound(thieu) + UBound(thua), 1 To 2)
    With CreateObject("scripting.dictionary")
        For i = 1 To UBound(thieu)
            If Not .exists(thieu(i, 1) & thieu(i, 4)) Then
                k = k + 1
                .Add thieu(i, 1) & thieu(i, 4), k
                Res(k, 1) = thieu(i, 3)
            End If
        Next
        For i = 1 To UBound(thua)
            If Not .exists(thua(i, 1) & thua(i, 4)) Then
                k = k + 1
                .Add thua(i, 1) & thua(i, 4), k
                Res(k, 2) = thua(i, 3)
            Else
                Res(.Item(thua(i, 1) & thua(i, 4)), 2) = thua(i, 3)
            End If
        Next
        For i = 1 To UBound(data)
            If .exists(data(i, 1) & data(i, 5)) Then
                data(i, 3) = Res(.Item(data(i, 1) & data(i, 5)), 1)
                data(i, 4) = Res(.Item(data(i, 1) & data(i, 5)), 2)
            End If
        Next
    End With
    [B4].Resize(i - 1, 5) = data
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn thử dùng Code này xem sao
Mã:
Sub SoSanh()
    Dim data(), thieu(), thua(), Res(), i As Long, k As Long
    data = Range([B4], [B65536].End(3)).Resize(, 5).Value
    With Sheets("THIEU")
        thieu = .Range(.[B4], .[B65536].End(3)).Resize(, 5).Value
    End With
    With Sheets("THUA")
        thua = .Range(.[B4], .[B65536].End(3)).Resize(, 4).Value
    End With


    ReDim Res(1 To UBound(thieu) + UBound(thua), 1 To 2)
    With CreateObject("scripting.dictionary")
        For i = 1 To UBound(thieu)
            If Not .exists(thieu(i, 1) & thieu(i, 4)) Then
                k = k + 1
                .Add thieu(i, 1) & thieu(i, 4), k
                Res(k, 1) = thieu(i, 3)
            End If
        Next
        For i = 1 To UBound(thua)
            If Not .exists(thua(i, 1) & thua(i, 4)) Then
                k = k + 1
                .Add thua(i, 1) & thua(i, 4), k
                Res(k, 2) = thua(i, 3)
            Else
                Res(.Item(thua(i, 1) & thua(i, 4)), 2) = thua(i, 3)
            End If
        Next
        For i = 1 To UBound(data)
            If .exists(data(i, 1) & data(i, 4)) Then
                data(i, 3) = Res(.Item(data(i, 1) & data(i, 4)), 1)
                data(i, 3) = Res(.Item(data(i, 1) & data(i, 4)), 2)
            End If
        Next
    End With
    [B4].Resize(i - 1, 5) = data
End Sub

Thật không may bạn ah, code của bạn không chạy ra kết quả.
Nhìn số bước mà nó lặp lại thấy ít hơn --> có lẽ sẽ nhanh hơn.
Nếu bạn lỡ giúp thì mình có thêm ít điều kiện ntnayf:
Câu hỏi cũng như trên:
Tham chiếu theo 2 điều kiện
nhưng điền thêm 1 cột nữa.
Trước đó chỉ có THIEU, THUA. bây giờ thêm cột TONG ( sheet TONG, BARCODE B4:B65000, CỬA HÀNG F4:F65000, THAM CHIẾU CỘT E4:E65000) vào sheet DATA
 
Upvote 0
dear a. Hải,

Code của anh chạy kết quả đúng, nhưng có lẽ thuật toán chưa tối ưu lắm.
em là newbie nên không hiểu ngôn ngữ này lắm.
Vấn đề ở chỗ, em có CSDL hơn 100.000 dòng. và em đã áp dụng cách của anh vào.
Nhưng thời gian chạy của nó hơn 20 phút. ?????\

So sánh với thời gian em lưu macro Hàm Index rồi Fill to End thì chỉ mất 15phút thôi.
Anh có cách nào tối ưu hơn không? Thanks anh trước
Hic nếu kiên nhẫn đợi được kết quả suốt 15 phút thì quả là đáng nể
Thử lại code này nha
PHP:
Sub test2()
Dim data(), thieu(), thua(), i, k, dkthieu, dkthua, Res()
data = Range([B4], [B1000000].End(3)).Resize(, 5).Value
ReDim Res(1 To UBound(data), 1 To 4)
With Sheets("THIEU")
   thieu = .Range(.[B4], .[B1000000].End(3)).Resize(, 4).Value
End With
With Sheets("THUA")
   thua = .Range(.[B4], .[B1000000].End(3)).Resize(, 4).Value
End With
With CreateObject("scripting.dictionary")
   For i = 1 To UBound(data)
      If Not .exists(data(i, 1) & data(i, 5)) Then
         k = k + 1
         .Add data(i, 1) & data(i, 5), k
         Res(k, 1) = data(i, 1)
         Res(k, 2) = data(i, 2)
      End If
   Next
   For i = 1 To UBound(thieu)
      dkthieu = thieu(i, 1) & thieu(i, 4)
      If .exists(dkthieu) Then Res(.Item(dkthieu), 3) = thieu(i, 3)
   Next
   For i = 1 To UBound(thua)
      dkthua = thua(i, 1) & thua(i, 4)
      If .exists(dkthua) Then Res(.Item(dkthua), 4) = thua(i, 3)
   Next
End With
[B4].Resize(i - 1).NumberFormat = "@"
[B4].Resize(i - 1, 4) = Res
End Sub
 
Upvote 0
Thật không may bạn ah, code của bạn không chạy ra kết quả.
Nhìn số bước mà nó lặp lại thấy ít hơn --> có lẽ sẽ nhanh hơn.
Nếu bạn lỡ giúp thì mình có thêm ít điều kiện ntnayf:
Câu hỏi cũng như trên:
Tham chiếu theo 2 điều kiện
nhưng điền thêm 1 cột nữa.
Trước đó chỉ có THIEU, THUA. bây giờ thêm cột TONG ( sheet TONG, BARCODE B4:B65000, CỬA HÀNG F4:F65000, THAM CHIẾU CỘT E4:E65000) vào sheet DATA
Tôi đã Test Code với dữ liệu ít ỏi của bạn cho và cũng đã so sánh với code bài #2, đồng thời tôi cũng đã Fill cho 65535 dòng dữ liệu để chạy thử. => Bạn có thể up File chạy lỗi lên không?
Nếu kiểm tra xong sẽ xử lý tiếp yêu cầu của bạn!
 
Upvote 0
Hic nếu kiên nhẫn đợi được kết quả suốt 15 phút thì quả là đáng nể
Thử lại code này nha
PHP:
Sub test2()
Dim data(), thieu(), thua(), i, k, dkthieu, dkthua, Res()
data = Range([B4], [B1000000].End(3)).Resize(, 5).Value
ReDim Res(1 To UBound(data), 1 To 4)
With Sheets("THIEU")
   thieu = .Range(.[B4], .[B1000000].End(3)).Resize(, 4).Value
End With
With Sheets("THUA")
   thua = .Range(.[B4], .[B1000000].End(3)).Resize(, 4).Value
End With
With CreateObject("scripting.dictionary")
   For i = 1 To UBound(data)
      If Not .exists(data(i, 1) & data(i, 5)) Then
         k = k + 1
         .Add data(i, 1) & data(i, 5), k
         Res(k, 1) = data(i, 1)
         Res(k, 2) = data(i, 2)
      End If
   Next
   For i = 1 To UBound(thieu)
      dkthieu = thieu(i, 1) & thieu(i, 4)
      If .exists(dkthieu) Then Res(.Item(dkthieu), 3) = thieu(i, 3)
   Next
   For i = 1 To UBound(thua)
      dkthua = thua(i, 1) & thua(i, 4)
      If .exists(dkthua) Then Res(.Item(dkthua), 4) = thua(i, 3)
   Next
End With
[B4].Resize(i - 1).NumberFormat = "@"
[B4].Resize(i - 1, 4) = Res
End Sub

Chạy được kết quả đến dòng thứ 34 thì dừng lại???
Em thuộc típ người thông minh nhờ kiên nhẫn anh ah.
Dù sao cũng cảm ơn sự tận tâm của anh
 
Upvote 0
Tôi đã Test Code với dữ liệu ít ỏi của bạn cho và cũng đã so sánh với code bài #2, đồng thời tôi cũng đã Fill cho 65535 dòng dữ liệu để chạy thử. => Bạn có thể up File chạy lỗi lên không?
Nếu kiểm tra xong sẽ xử lý tiếp yêu cầu của bạn!

Có lẽ bạn đang khá bực bội vì bạn đã test mà mình lại nói là không thực hiện được.
Dù sao cũng cảm ơn bạn rất nhiều. Đừng bực bội bạn nhé.
Tất cả cùng giúp nhau thôi mà
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Chạy được kết quả đến dòng thứ 34 thì dừng lại???
Em thuộc típ người thông minh nhờ kiên nhẫn anh ah.
Dù sao cũng cảm ơn sự tận tâm của anh
Còn mình thì thuộc dạng người trán ngắn...
Bạn vui tính quá, dữ liệu chỉ có tới dòng 34 thì hết rồi lấy gì chạy nữa.
Mình thử với 15 000 dòng dữ liệu chạy trong nháy mắt
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Có lẽ bạn đang khá bực bội vì bạn đã test mà mình lại nói là không thực hiện được.
Dù sao cũng cảm ơn bạn rất nhiều. Đừng bực bội bạn nhé.
Tất cả cùng giúp nhau thôi mà
Không bực gì đâu bạn, nhưng mình đang thắc mắc xem code sai chỗ nào để sửa thôi mà. Ngay cả code bài anh Hải tại #10 mình test không thấy lỗi tại sao bạn lại báo lỗi tại dòng số 34???
- Lập trình nó là thế: phải chuẩn (tôi đoán bạn cũng biết ít nhiều về Code vì bài #2 chỉ viết tới 65536 dòng và bạn đã tùy biến được cho 100000 dòng)
 
Upvote 0
Không bực gì đâu bạn, nhưng mình đang thắc mắc xem code sai chỗ nào để sửa thôi mà. Ngay cả code bài anh Hải tại #10 mình test không thấy lỗi tại sao bạn lại báo lỗi tại dòng số 34???
- Lập trình nó là thế: phải chuẩn (tôi đoán bạn cũng biết ít nhiều về Code vì bài #2 chỉ viết tới 65536 dòng và bạn đã tùy biến được cho 100000 dòng)

Gửi bạn và anh Hải xem file mình Test. Mọi người có thể xóa record và chạy lại.
Mình đọc được 1 ít code thôi. Còn lập trình thì không biết gì.
Sẵn tiện, mình thấy hình như trong code test2 này của anh Hải quên tính đến việc lặp lại các điều kiện giống nhau của data.????, nếu không tìm ra điều kiện giống thì dữ liệu data = 0...

Dear a.Hải,

đã đọc file test của anh và thấy THUA, THIEU có nhiều dữ kiện tương đương Data. Vậy nếu ít hơn thì sao, code của anh có hỗ trợ được không?



Nói chung, cảm ơn mọi người đã giúp mình.
 

File đính kèm

Upvote 0
Gửi bạn và anh Hải xem file mình Test. Mọi người có thể xóa record và chạy lại.
Mình đọc được 1 ít code thôi. Còn lập trình thì không biết gì.
Sẵn tiện, mình thấy hình như trong code test2 này của anh Hải quên tính đến việc lặp lại các điều kiện giống nhau của data.????, nếu không tìm ra điều kiện giống thì dữ liệu data = 0...

Dear a.Hải,

đã đọc file test của anh và thấy THUA, THIEU có nhiều dữ kiện tương đương Data. Vậy nếu ít hơn thì sao, code của anh có hỗ trợ được không?



Nói chung, cảm ơn mọi người đã giúp mình.
Thôi mình giúp hết khả năng rồi.
Tạm biệt topic này nếu không sẽ ăn tết chẳng vui vẽ tí nào.
Hy vọng với cách hỏi bài của bạn sẽ sớm có đáp án nhé.
 
Upvote 0
cám ơn anh Hải rất nhiều. Vì ham học hỏi nên có lẽ khiến anh không vui.
Đưng để bụng anh Hải nhé, Chúc năm mới đầy thành công và sự bình an!!!
 
Upvote 0
Mình up File bạn tham khảo nhé.
 

File đính kèm

Upvote 0

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

Back
Top Bottom