Поиск значения в столбце таблицы и возврат номера строки таблицы — VBA

#excel #vba #listobject

#excel #vba #listobject

Вопрос:

Справочная информация:

Я пытаюсь найти значение в столбце таблицы и вернуть ему номер строки этой таблицы.

Имя таблицы «Type_K» и находится на листе «ДАННЫЕ», выглядит так:

введите описание изображения здесь

Из пользовательского ввода я хочу найти то же значение во втором столбце, а затем вернуть строку таблицы. Это будет использоваться на листе «Калькуляция затрат». Вот таблица, которую заполняет пользователь:введите описание изображения здесь Столбец Material имеет выпадающий список с 4 параметрами, в зависимости от этого ввода столбец для типа меняет свой выпадающий список, то же самое касается столбцов Wall и Size.

Для этого примера пользователь выбрал:

Материал = медь

Тип = Тип K

Стена (в данном случае нет)

Размер = 1/4 »

Значение из столбца Size — это то, которое я хочу найти в таблице ДАННЫХ (второй столбец первого изображения)

В настоящее время код проверяет тип и возвращает правильное имя таблицы

 If Worksheets("Pipe Costing").Range("D" amp; ThisRow).Value = "Type K" Then
    Copper_Type_ref = "Type_K"
ElseIf Worksheets("Pipe Costing").Range("D" amp; ThisRow).Value = "Type L" Then
        Copper_Type_ref = "Type_L"
ElseIf Worksheets("Pipe Costing").Range("D" amp; ThisRow).Value = "Type M" Then
        Copper_Type_ref = "Type_M"
ElseIf Worksheets("Pipe Costing").Range("D" amp; ThisRow).Value = "Type DWV" Then
        Copper_Type_ref = "Type_DWV"
End If
 

«ThisRow» — это просто номер строки пользовательского ввода (т. Е. Они что-то меняют в строке 4, поэтому ThisRow = 4).

Полный код:

 Private Sub Copper_Data_Fill(ThisRow)
Dim Copper_Type_ref As String
Dim RowNum As Long

If Worksheets("Pipe Costing").Range("D" amp; ThisRow).Value = "Type K" Then
        Copper_Type_ref = "Type_K"
ElseIf Worksheets("Pipe Costing").Range("D" amp; ThisRow).Value = "Type L" Then
        Copper_Type_ref = "Type_L"
ElseIf Worksheets("Pipe Costing").Range("D" amp; ThisRow).Value = "Type M" Then
        Copper_Type_ref = "Type_M"
ElseIf Worksheets("Pipe Costing").Range("D" amp; ThisRow).Value = "Type DWV" Then
        Copper_Type_ref = "Type_DWV"
End If

    'RowNum = Application.Match("F" amp; ThisRow, Worksheets("DATA").ListObjects(Copper_Type_ref).ListColumns(2).DataBodyRange, False).Row
    'RowNum = Worksheets("DATA").ListObjects(Copper_Type_ref).ListColumns(2).DataBodyRange.Find("F" amp; ThisRow, xlValues).Row
    RowNum = Worksheets("DATA").ListObjects(Copper_Type_ref).ListColumn(2).DataBodyRange.Find("F" amp; ThisRow, xlValues).Index
    Worksheets("Pipe Costing").Range("H" amp; ThisRow).Value = Worksheets("DATA").ListObjects(Copper_Type_ref).DataBodyRange(RowNum, 4).Value
End Sub
 

Я надеюсь, что RowNum будет номером строки таблицы, а затем использовать его для заполнения последней строки

 Worksheets("Pipe Costing").Range("H" amp; ThisRow).Value = Worksheets("DATA").ListObjects(Copper_Type_ref).DataBodyRange(RowNum, 4).Value
 

Любая помощь приветствуется!

Комментарии:

1. Вы вызываете это из обработчика событий? Было бы полезно просмотреть таблицу, которую редактирует пользователь.

2. Я добавил больше информации, надеюсь, это прояснит ситуацию.

3. Информации недостаточно, но вы можете попробовать : Dim RowNum As Variant : RowNum = Application.Match("F" amp; ThisRow, Worksheets("DATA").ListObjects(Copper_Type_ref).ListColumn(2).DataBodyRange, 0) : If IsNumeric(RowNum) Then . Вам определенно следует использовать больше переменных, чтобы избежать таких длинных строк.

4. Я постараюсь использовать больше переменных, я все еще новичок в VBA, спасибо

Ответ №1:

Было бы проще передать текущую строку из входного листа в качестве Range параметра вашему подразделу:

 Private Sub Copper_Data_Fill(ThisRow As Range)
    Dim dVal, f As Range, tbl as range
    
    
    dVal = ThisRow.Columns("D").Value
    Select Case dVal
        Case "Type K", "Type L", "Type M", "Type DWV"
            'get the corresponding listobject data range
            Set tbl = Worksheets("DATA").ListObjects(Replace(dVal, " ", "_")).DataBodyRange
        Case Else
            Exit Sub 'nothing to do (clear H?)
    End Select
    
    Set f = tbl.Columns(2).Find(ThisRow.Columns("F").Value, _
                                lookat:=xlWhole, LookIn:=xlValues)
    
    If Not f Is Nothing Then
        ThisRow.Columns("H").Value = f.Offset(0, 2).Value 'col4
    Else
        ThisRow.Columns("H").Value = "not found"
    End If
    
End Sub
 

Комментарии:

1. Спасибо, Тим, я думаю, что я следую, я посмотрю, работает ли это (теперь я использую ThisRow в других подразделах, в которых я получаю ошибки)