2015-10-27 3 views
0

У меня есть таблица с 4 столбцами и 35000 строк.VBA заполнить список всех вхождений

Я сделал форму с 3 ListBoxes (среди других кнопок)

При нажатии кнопки поиска Я хотел бы искать колонку А для всех вхождений числа и заполнить ListBoxes с соответствующей B, C & D

(если он помогает скорости никогда не будет более 10 вхождений одного и того же числа и столбца а, упорядоченные)

123 собаки Фидо Elm $ 50

123 собака SPOT OAK $ 40

456 Cat Jet Adam $ 30

Искать 123 и

ListBox 1 покажет Fido & Пятно ListBox 2 покажет Elm & Oak listbox3 ....

код до сих пор:

Private Sub cmdSearch_Click() 

Dim Response As Long 
Dim NotFound As Integer 


NotFound = 0 


ActiveWorkbook.Sheets("test").Activate 

Frame1.Visible = False 

Response = txtItemNumber.Text 

If Response <> False Then 

Range("A2").Select 


Do Until ActiveCell.Value = Val(Response) 
If ActiveCell.Value = "" Then 
MsgBox "Item Number Not Found!", vbExclamation 
NotFound = 1 
Exit Do 
End If 
ActiveCell.Offset(1, 0).Select 
Loop 

If ActiveCell.Value = Val(Response) Then 
Frame1.Visible = True 

ListBox1.Text = ActiveCell.Offset(0, 1) 
ListBox2.Text = ActiveCell.Offset(0, 2) 
ListBox3.Text = ActiveCell.Offset(0, 3) 

**'would like to see if next number in Column A is also the same as being searched... if so then add to listbox' 
'do this until the next number doesn't match'** 


End If 

End If 

End Sub 

также будет процесс ускоряется с помощью массива или vlookup? Я не знаком с этими , и мне бы хотелось использовать несколько списков, а не многострочный список (в случае, если это произойдет).

ответ

0

Этот код основан на вашей идее, но он использует массив, называемый arr, для быстрого ввода данных и для быстрой обработки. Расположенные ссылки хранятся в строках, которые затем разбиваются на списки ListBoxes.

В качестве разделительного символа используется вертикальная полоса. Если это столкнутся с вашими данными, вам нужно будет его изменить.

Примечание. Я не думаю, что ваши команды Frame1.Visible эффективны. Фактически ничего не делайте.

Private Sub cmdSearch_Click() 

    Dim Response As Long 
    Dim NotFound As Integer 
    Dim arr As Variant 
    Dim i As Long 
    Dim str1 As String, str2 As String, str3 As String 

    NotFound = 0 
    ActiveWorkbook.Sheets("test").Activate 
    Frame1.Visible = False 
    Response = txtItemNumber.Text 

    If Response <> False Then 

     With ActiveSheet 
      arr = .Range("A2:D" & .Cells(.Rows.Count, "A").End(xlUp).Row) 
     End With 

     For i = 1 To UBound(arr) 
      If arr(i, 1) = Response Then 
       str1 = IIf(str1 = "", arr(i, 2), str1 & "|" & arr(i, 2)) 
       str2 = IIf(str2 = "", arr(i, 3), str2 & "|" & arr(i, 3)) 
       str3 = IIf(str3 = "", arr(i, 4), str3 & "|" & arr(i, 4)) 
      End If 
     Next 

     If str1 = "" Then 
      MsgBox "Item Number Not Found!", vbExclamation 
      NotFound = 1 
     Else 
      Frame1.Visible = True 
      ListBox1.List = Split(str1, "|") 
      ListBox2.List = Split(str2, "|") 
      ListBox3.List = Split(str3, "|") 
     End If 

    End If 

End Sub 
+0

Святая корова, мне нужно переварить это и попробовать завтра. [Цель за кадром] Вместо того, чтобы использовать msgbox для ввода пользователем элемента поиска, у меня есть текстовое поле в форме. Только для визуальных целей у меня есть результаты (среди других кнопок) на фрейме, который скрыт до тех пор, пока пользователь не выполнит поиск. – instanceoftime

+0

OMG, что намного быстрее. Спасибо RickXI – instanceoftime

+0

и да, правильно, что frame.visible не сделал ничего LOL – instanceoftime

0

Просто интересно, если вы определили Response как долго, почему вы используете val (Response) в цикле while? И если он длинный, то Response = txtItemNumber.Text может вызвать ошибку, потенциально пытаясь сохранить буквенно-цифровую строку в числовом только длинном.

Поскольку вы тусклым ответ, как долго, использовать это вместо того, чтобы ...

Response = Val("0" & txtItemNumber.Text) 

Это не принимает на себя никаких отрицательных чисел. В ожидании нулевого значения вы не изменяете значение номера (0100 равно 100), но вы также обрабатываете проблемы «0abc», если пользователь вводит текст. Он будет возвращать 0, если пользователь вводит «abc», и ваше решение проверяет наличие 0 (false). Если пользователь вводит «100», он преобразует «0100» в 100, и ваше решение затем переходит с этим значением. Он не сработает, если пользователь войдет в «-100», так как «0-100» не равен 100.

Теперь, поскольку мы используем длинный, удалим все ссылки на Val (Response) в другом месте. Это уменьшит количество преобразований типа внутри цикла, которое будет искать значение ячейки. Поскольку у вас есть это, каждый раз через цикл он преобразует Response из длинного в строку, а затем длинный, а затем сравнивает UNTIL. И это происходит в 35000 раз.

Преобразуя его с помощью Val перед циклом, теперь он преобразует строку в длинное преобразование ONCE, а не все 35000 раз, когда он проходит через ячейки. Это небольшое изменение, которое может немного ускорить его.

+0

ОК, да, я понимаю, что вы сказали. Я вошел в текст, и он разбился, поэтому я бросил «вал» в качестве безопасности. Я отредактирую его по вашей рекомендации. Что бы объявить его целым числом (если что-нибудь)? Как я мог «игнорировать» знак минуса, если пользователь должен был ошибочно поместить его? – instanceoftime

+0

'Response = Val (" 0 "& Replace (txtItemNumber.Text," - "," "))' Вы уже ответ DIM как LONG в верхней части кода! – Wolfie

+0

Просто интересно, если я должен изменить его на целое, а не надолго, и если это поможет в исправлении ошибок? – instanceoftime

Смежные вопросы