2017-02-02 4 views
2

Мой код ниже покажет всю запись, найденную по номеру вызова, но поскольку у меня есть повторяющиеся номера вызовов. Например: 389905 имеет две записи в excel. Я хочу нажать кнопку поиска, чтобы вывести следующий номер вызова со своей записью.Excel VBA, как найти следующее значение после первого сопоставления

Возможно ли это?

Private Sub CommandButton1_Click() 

row_number = 1 
Do 
    DoEvents 
    row_number = row_number + 1 
    item_in_review = Sheets("Database").Range("A" & row_number) 
    If item_in_review = txtCall.Text Then 
     txtLogged.Text = Sheets("Database").Range("B" & row_number) 
     txtName.Text = Sheets("Database").Range("C" & row_number) 
     txtSite.Text = Sheets("Database").Range("D" & row_number) 
     txtType.Text = Sheets("Database").Range("E" & row_number) 
     txtTitle.Text = Sheets("Database").Range("F" & row_number) 
     cmbOwner.Text = Sheets("Database").Range("G" & row_number) 
     cmbResponder.Text = Sheets("Database").Range("H" & row_number) 
     txtReference.Text = Sheets("Database").Range("I" & row_number) 
    End If 
Loop Until item_in_review = "" 

End Sub 
+0

Используйте 'Найти' и' FindNext', а не перебирайте данные. https://msdn.microsoft.com/en-us/library/office/ff839746.aspx –

+0

Как мне написать код? Можешь ли ты показать мне? – user3528873

+0

В этом случае у вас есть «UserForm», чтобы показать значения записи, но проблема в том, что вы только когда-либо видите * последнюю запись за 389905? Полагаю, вы хотите иметь возможность просматривать значения для нескольких записей 389905? –

ответ

0

Один из способов заключается в использовании класс для хранения каждого набора значений:

Создать модуль класса и имя его clsCallDetails.
Добавьте этот код в модуль:

Option Explicit 

'Class module named 'ClsCallDetails' 

Private pLogged As String 
Private pName As String 
Private pSite As String 
Private pCallType As String 
Private pOwner As String 
Private pResponder As String 
Private pReference As String 

Public Property Get Logged() As String 
    Logged = pLogged 
End Property 
Public Property Let Logged(Value As String) 
    pLogged = Value 
End Property 

Public Property Get Name() As String 
    Name = pName 
End Property 
Public Property Let Name(Value As String) 
    pName = Value 
End Property 

Public Property Get Site() As String 
    Site = pSite 
End Property 
Public Property Let Site(Value As String) 
    pSite = Value 
End Property 

Public Property Get CallType() As String 
    CallType = pCallType 
End Property 
Public Property Let CallType(Value As String) 
    pCallType = Value 
End Property 

Public Property Get Owner() As String 
    Owner = pOwner 
End Property 
Public Property Let Owner(Value As String) 
    pOwner = Value 
End Property 

Public Property Get Responder() As String 
    Responder = pResponder 
End Property 
Public Property Let Responder(Value As String) 
    pResponder = Value 
End Property 

Public Property Get Reference() As String 
    Reference = pReference 
End Property 
Public Property Let Reference(Value As String) 
    pReference = Value 
End Property 

Создайте обычный модуль и добавьте этот код к нему:
Edit: Первоначально был Find_CallNumbers как функцию; изменили его на суб.

Option Explicit 

'Normal Module 

Public CallDetails As Collection 

Public Sub Find_CallNumbers(NumberToFind As String) 

    Dim rng_to_search As Range 
    Dim rFound As Range 
    Dim FirstAddress As String 
    Dim FoundItem As clsCallDetails 

    Set CallDetails = New Collection 

    With ThisWorkbook.Worksheets("Database") 
     Set rng_to_search = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)) 
    End With 

    With rng_to_search 
     'Look for the first instance. 
     Set rFound = .Find(What:=NumberToFind, _ 
          After:=.Cells(1, 1), _ 
          LookIn:=xlValues, _ 
          LookAt:=xlWhole, _ 
          SearchDirection:=xlNext) 
     If Not rFound Is Nothing Then 
      FirstAddress = rFound.Address 
      Do 
       Set FoundItem = New clsCallDetails 'Create a new instance of the class to hold the details. 
       With FoundItem 
        .Logged = rFound.Offset(, 1) 'Offset from column A by 1 column, so column B. 
        .Name = rFound.Offset(, 2) 
        .Site = rFound.Offset(, 3) 
        .CallType = rFound.Offset(, 4) 
        .Owner = rFound.Offset(, 5) 
        .Responder = rFound.Offset(, 6) 
        .Reference = rFound.Offset(, 7) 
       End With 
       CallDetails.Add FoundItem 'Add the class instance to our collection. 
       Set rFound = .FindNext(rFound) 'Look for the next value. 

      'Continue searching until we reach the top again. 
      Loop While Not rFound Is Nothing And rFound.Address <> FirstAddress 
     End If 
    End With 

End Sub 

Создайте форму, содержащую эти элементы управления (я поместил имена контроля над управлением):
enter image description here

Добавьте этот код в форме:

Option Explicit 

Private Sub cmdFind_Click() 
    Find_CallNumbers Me.txtSearchNumber 
    Me.txtCurrentIndex = 1 
    PlaceValues (Me.txtCurrentIndex) 
End Sub 

Private Sub PlaceValues(Index As Long) 
    With Me 
     .txtLogged.Value = Format(CallDetails(Index).Logged, "HH:MM:SS") 
     .txtName.Value = CallDetails(Index).Name 
     '... 
     '... 
    End With 
End Sub 

Private Sub cmdNext_Click() 
    Me.txtCurrentIndex = Me.txtCurrentIndex + 1 
    PlaceValues (Me.txtCurrentIndex) 
End Sub 

Private Sub cmdPrevious_Click() 
    Me.txtCurrentIndex = Me.txtCurrentIndex - 1 
    PlaceValues (Me.txtCurrentIndex) 
End Sub 

При поиске для номера он найдет и отобразит детали первого найденного элемента. При нажатии кнопки Next/Previous вы перейдете к следующему экземпляру.
Вам нужно будет добавить проверку ошибок - например, когда она достигнет конца или начала коллекции или если искомый номер не найден.

+0

Спасибо. У меня небольшая проблема. Он работает, тогда он не работает. Я получаю сообщение об ошибке. Ошибка времени выполнения «5»: Неверный вызов или вызов процедуры. Его призыв на эту линию. .txtLogged.Value = Формат (CallDetails (Index) .Logged, "HH: MM: SS") – user3528873

+0

Имеет ли значение 'CallDetails (Index) .Logged' значение? Если это так - это числовое значение (возможно, менее 1)? Вы назвали ** текстовое поле управления ** в форме 'txtLogged'? Является ли код в Userform так, чтобы он мог использовать ключевое слово 'Me'? –

+0

Текстовое поле txtLogged будет именем человека, который зарегистрировал вызов. Таким образом, его кто-то называют, например, Джулия Чан. Да, я знаю, что это не объясняет хорошо. Да, управление текстовым полем называется txtLogged – user3528873

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