2015-07-27 42 views
5

Những gì tôi cóTìm một giá trị từ một cột và nhanh chóng trả lại số hàng tế bào của nó

Tôi có một tập tin với số phận và một số nhà cung cấp cho từng phần. Có 1500 bộ phận với khoảng 20 nhà cung cấp có thể. Để đơn giản, hãy nói rằng các phần được liệt kê trong cột A, với mỗi nhà cung cấp chiếm một cột sau đó. Giá trị theo các nhà cung cấp được nhập bằng tay nhưng không thực sự quan trọng.

Trong một trang tính khác, tôi có danh sách các phần được nhập từ cơ sở dữ liệu Access. Danh sách các bộ phận được nhập, nhưng không phải là thông tin nhà cung cấp. Trong cả hai trường hợp, mỗi phần chỉ xuất hiện một lần.

Những gì tôi muốn làm

tôi chỉ đơn giản muốn để phù hợp với các thông tin cung cấp từ bảng đầu tiên với các bộ phận trong danh sách nhập khẩu. Ngay bây giờ, tôi có một hàm đi qua từng phần trong danh sách với các nhà cung cấp, sao chép thông tin nhà cung cấp trong một mảng, tìm số phần trong danh sách phần được nhập (luôn có một kết hợp duy nhất) và sao chép mảng bên cạnh nó (với thông tin nhà cung cấp bên trong). Nó hoạt động. Thật không may, chức năng tìm thấy chậm lại đáng kể mỗi khi nó được sử dụng. Tôi biết nó là thủ phạm thông qua các bài kiểm tra khác nhau, và tôi không thể hiểu tại sao nó chậm lại (bắt đầu với 200 vòng lặp mỗi giây, làm chậm xuống 1 giây và Excel bị treo). Tôi có thể bị rò rỉ một số loại? Kích thước tập tin vẫn còn 7mb trong suốt. Dưới đây là:

Function LigneNum(numAHNS As String) As Integer 
    Dim oRange As Range, aCell As Range 
    Dim SearchString As String 

    Set oRange = f_TableMatrice.Range("A1:A1500") 
    SearchString = numAHNS 

    Set aCell = oRange.Find(What:=SearchString, LookIn:=xlValues, _ 
     LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _ 
     MatchCase:=False, SearchFormat:=False) 

    If Not aCell Is Nothing Then 
     'We have found the number by now: 
      LigneNum = aCell.Row 
     Exit Function 
    Else 
     MsgBox "Un numéro AHNS n'a pas été trouvé: " & SearchString 
     Debug.Print SearchString & " not found!" 
      LigneNum = 0 
     Exit Function 
    End If 

End Function 

Hàm chỉ trả về số hàng mà giá trị được tìm thấy hoặc 0 nếu không tìm thấy giá trị sẽ không bao giờ xảy ra.

Những gì tôi cần giúp đỡ với

Tôi muốn một trong hai để xác định nguyên nhân của chậm lại, hoặc tìm một sự thay thế cho phương pháp Find. Tôi đã sử dụng Tìm trước và đây là lần đầu tiên điều này xảy ra với tôi. Ban đầu nó được lấy từ trang web của Siddarth Rout: http://www.siddharthrout.com/2011/07/14/find-and-findnext-in-excel-vba/ Điều kỳ lạ là nó không phải là bắt đầu chậm, nó chỉ trở nên chậm chạp khi nó tiếp tục.

Tôi nghĩ rằng sử dụng trận đấu có thể làm việc, hoặc có thể bán phá giá phạm vi để tìm kiếm (một phần số) vào một mảng và cố gắng để phù hợp với những với nhập khẩu danh sách phần số có thể làm việc. Tôi không chắc chắn làm thế nào để làm điều đó, nhưng câu hỏi của tôi là thêm về cái nào sẽ nhanh hơn (miễn là nó vẫn còn dưới 15 giây tôi không thực sự quan tâm, mặc dù, nhưng looping hơn 1500 mặt hàng 1500 lần phải ra khỏi tấm là ra câu hỏi). Có ai đề nghị phù hợp với giải pháp mảng/chi tiêu nhiều giờ sửa mã của tôi?

EDIT

Đây là vòng lặp nó đang được gọi là từ. Tôi không nghĩ rằng đó là vấn đề:

For Each cellToMatch In rngToMatch 
     Debug.Print cellToMatch.Row 
     'The cellsToMatch's values are the numbers I want, rngToMatch is the column where they are. 

     For i = 2 To nbSup + 1 
      infoSup(i - 2) = f_TableMatrice.Cells(cellToMatch.Row, i) 
     Next 
     'infoSup contains the required supplier data now 
     'I call the find function here to find the row where the number appears in the imported sheet 
     'To copy the array nbSup on that line 
     LigneAHNS = LigneNum(cellToMatch.Value) 'This is the Find function 
     If LigneAHNS = 0 Then Exit Sub 
     'This loop just empties the array in the right line. 
     For i = LBound(infoSup) To UBound(infoSup) 
      f_symix.Cells(LigneAHNS, debutsuppliers + i) = infoSup(i) 
     Next 

    Next 

Nếu tôi thay LigneAHNS = LigneNum bởi LigneAHNS = 20, ví dụ, các đoạn mã thực thi cực nhanh. Do đó, rò rỉ xuất phát từ chính hàm tìm kiếm.

+1

Liệu nó giúp gì cả để thêm dòng 'Set Orange = Nothing' như dòng cuối cùng của chức năng của bạn? (Hay đúng hơn, trước khi bạn 'Thoát Function') –

+1

bạn đã xây dựng gì xung quanh chức năng này? Có lẽ vấn đề là vòng lặp bạn đang gọi nó từ? –

+0

bao lâu một lần nào bạn liệt kê sự thay đổi và làm bạn có thể kiểm soát nó? Ngoài ra bạn nói vòng tôi thấy không có vòng trong mã của bạn? –

Trả lời

3

Một cách khác để làm điều đó mà không cần sử dụng chức năng tìm có thể là một cái gì đó như thế này. Thứ nhất, đặt các phần ID và số dòng của chúng vào một từ điển kịch bản. Đây là những điều tra cứu rất nhanh. Như thế này:

Dim Dict As New Scripting.Dictionary 
Dim ColA As Variant 
Lastrow=range("A50000").end(xlUp).Row 
ColA = Range("A1:A" & LastRow).Value 
For i = 1 To LastRow 
    Dict.Add ColA(i, 1), i 
Next i 

Tiếp tục tối ưu hóa, bạn có thể khai báo Dict như là một biến công cộng, cư nó một lần, và đề cập đến nó nhiều lần trong tra cứu của bạn. Tôi hy vọng điều này sẽ nhanh hơn việc chạy một ô.nhập trên phạm vi mỗi khi bạn thực hiện tra cứu.

Đối với cú pháp của nhìn lên mục trong từ điển, hãy tham khảo Looping through a Scripting.Dictionary using index/item number

+0

Rất tuyệt, tôi đã có ý nghĩa để tìm hiểu về các từ điển trong một thời gian. Tôi sẽ thử nó và quay lại câu trả lời của bạn! –

+0

Tôi điền vào từ điển với một mảng, vì tôi có nhiều giá trị cho mỗi khóa. Điền 1500 mục với mảng 5 chuỗi, sau đó debug.printing mỗi mục trong mảng mất khoảng 6 giây. Cảm ơn nhiều! Ngoài ra, toàn bộ 6 giây chỉ là do debug.print, vòng lặp dictionnary chính nó gần như tức thời! –

+0

Tuyệt vời, vui vì tôi có thể giúp đỡ. – CustodianOfCode

1

Bạn có thể thực hiện điều này chỉ với công thức ô Excel và không có VB nếu bạn sẵn sàng dành một cột riêng cho mỗi nhà cung cấp trên tờ phần chính của bạn. Sau đó bạn có thể sử dụng định dạng có điều kiện để làm cho nó hấp dẫn trực quan hơn. Tôi đã thử nó với 1500 hàng và nó rất nhanh.Tăng nó đến 5000 hàng trở nên chậm hơn, nhưng bạn nói bạn chỉ có 1500 dòng cho bây giờ, vì vậy nó phải được thích hợp.

  • Mở Sheet 1, xác định một phần cột số và một cột riêng biệt cho mỗi nhà cung cấp .
  • Tạo một trang tính riêng biệt cho từng nhà cung cấp với tất cả các số bộ phận có sẵn từ nhà cung cấp được liệt kê trong cột A. Đảm bảo các hàng trên các tờ nhà cung cấp được sắp xếp theo số bộ phận.
  • Tên mỗi nhà cung cấp tờ giống như các cột liên quan đến tiêu đề hiển thị trên Bảng 1.
  • Gán công thức sau trong mỗi tế bào dưới mỗi nhà cung cấp đề cột trên Sheet 1:

    = NOT (ISNA (VLOOKUP ($ A2, INDIRECT (" '" & B $ 1 & "' A: A"), 1, FALSE)))

Các nắp màn hình sau đây cho thấy điều này thực hiện alo ng với định dạng có điều kiện để làm nổi bật mà các nhà cung cấp có phần nào:

enter image description here

Nếu bạn muốn hiển thị số lượng có sẵn từ các nhà cung cấp, sau đó bạn luôn luôn có thể có một cột thứ hai (B) trên các nhà cung cấp lá có hàm cuối cùng được biết đến với số lượng cho từng phần và sử dụng VLOOKUP để lấy cột B thay vì A.

+0

Cảm ơn sự giúp đỡ!Điều này đã thắng, t làm việc, mặc dù, bởi vì có một tấn hơn đang xảy ra trong bảng tính hơn thế. đã có 15 trang tính và có khoảng 50 người dùng cuối. Thông tin nhà cung cấp xuất hiện ở phần cuối của nhiều thông tin khác và cần phải dễ dàng nhìn thấy, cộng với khoảng 7000 bộ phận với 20 nhà cung cấp ở cuối. Nhưng cảm ơn thời gian của bạn! –

Các vấn đề liên quan