2016-10-04 3 views
0

Я пытаюсь настроить код VBA, который проходит через каждую ячейку в столбце M и возвращает значение столбца L, если ячейка содержит число, и проходит через функцию index/match если столбец L не содержит числа. Тогда, если индекс/match не находит то, что он ищет, он проходит через другой vlookup. У меня возникают проблемы с синтаксисом третьей части этого (vlookup в конце). Я не уверен, что это должен быть другой оператор Else или оператор if или ISerror или что-то другое. Прямо сейчас у меня он настроен как второй, если/else. Мне также интересно, будут ли у меня проблемы из-за того, что функция index/match имеет текст в качестве входного сигнала и должна возвращать число. Любые предложения/советы по этому поводу очень ценятся. Ниже я до сих пор.Excel VBA Index/Match внутри функции IF

Sub Ranking_2() 

Dim cell As Range, rng As Range 
Set rng = Range("L2:L120") 

For Each cell In rng 
    If WorksheetFunction.IsNumber(cell.Value) Then 
     cell.Offset(0, 1).Value = cell.Value 
    Else: cell.Offset(0, 1).Value = WorksheetFunction.Index(ThisWorkbook.Sheets(1).Range("K:K"), WorksheetFunction.Match(cell.Offset(0, 1) & cell.Offset(0, 5), ThisWorkbook.Sheets(1).Range("A:A") & ThisWorkbook.Sheets(1).Range("H:H"), 0)) 
     If:cell.Offset(0,1).Value= WorksheetFunction.IsError(
     Else: cell.Offset(0, 1).Value = WorksheetFunction.VLookup(cell.Offset(0, -11), ThisWorkbook.Sheets(2).Range("A1:D136"), 3, 0) 
End If 
Next 
End Sub 
+0

Эшли, есть причина, вы используете VBA для вставки рабочего листа функции в клетках, а не только с помощью VBA делать то, что выполняют функции? Это похоже на большую работу для выполнения чего-то простого. Простое выполнение функций на вашем листе или VBA в модуле. Просто любопытно, почему вы так делаете. – Tyeler

+0

Эй, Тайлер, я не уверен, что понимаю, о чем вы спрашиваете. Я новичок в VBA, так что это был единственный способ найти то, что я делаю, добиться того, что я пытаюсь сделать, вполне возможно, что есть более простой способ. Я не делаю этого как формулы в excel, потому что это часть более крупного кода, который будет выполняться много раз, и в VBA это должно быть быстрее. Если есть более простой способ написать это в VBA, можете ли вы рассказать о том, как это сделать? – Ashley

+0

Это все, что мне нужно было знать. Позвольте мне посмотреть, не могу ли я скомпоновать код, чтобы вы могли на правильном пути. : D – Tyeler

ответ

0

вы можете принять эти изменения в код

Option Explicit 

Sub Ranking_2() 
    Dim cell As Range 
    Dim lookUp1Sht As Worksheet 
    Dim lookUp2Rng As Range 
    Dim val1 As Variant 

    Set lookUp1Sht = ThisWorkbook.Worksheets("LookUp1Sht") '<--| set the worksheet you're making the first lookup 
    Set lookUp2Rng = ThisWorkbook.Worksheets("LookUp2Sht").Range("A1:C136") '<--| since you're this range returning column "C" value it suffices limiting it to column "C" 

    For Each cell In Range("L2:L120").SpecialCells(xlCellTypeConstants) '<--| limit looping through wanted range not blank cells only 
     With cell '<--| reference current cell 
      Select Case True 
       Case IsNumeric(.Value) '<--| if current cell value can be evaluated as "number"... 
        .Offset(0, 1).Value = CDbl(.Value) 
       Case Not IsError(LookUp1(lookUp1Sht, .Offset(0, 1).Value, .Offset(0, 5).Value, val1)) '<-- if "first" lookup doesn't return an "error"... 
        .Offset(0, 1).Value = val1 '<--| then write the 3rd argument passed from LookUp1() function 
       Case Else '<-- if all preceeding "cases" failed... 
        .Offset(0, 1).Value = Application.VLookup(.Offset(0, -11), lookUp2Rng, 3, 0) '<-- write "second" lookup return value 
      End Select 
     End With 
    Next 
End Sub 

Function LookUp1(sht As Worksheet, val1 As Variant, val2 As Variant, val As Variant) As Variant 
    Dim f As Range 
    Dim firstAddress As String 

    With sht '<--| reference passed worksheet 
     Set f = .Range("A:A").Find(what:=val1, LookIn:=xlValues, lookat:=xlWhole) '<-- look for first passed value in its column "A" 
     If Not f Is Nothing Then '<--| if found... 
      firstAddress = f.Address '<--| store found cell address to stop subsequent FindNext() loop upon wrapping back to it 
      Do '<--| loop 
       If f.Offset(, 7).Value = val2 Then '<--| if corresponding value in column "H" matches val2... 
        val = .Cells(f.row, "K") '<-- set 3rd argument to value in column "K" corresponding to the "double" match 
        Exit Function '<--| exit function 
       End If 
       Set f = .Range("A:A").FindNext(f) '<-- go on looking for val1 in column "A" 
      Loop While f.Address <> firstAddress '<-- stop looping upon wrapping back on first cell found 
     End If 
    End With 
    LookUp1 = CVErr(xlErrValue) '<-- if no "double" match occurred then return "#VALUE!" error 
End Function 

Обратите внимание, что:

  • изменения "LookUp1Sht" и "LookUp2Sht" к вашим фактическим рабочим листам имена

  • Match и LookUpApplication функции обрабатывать возможные ошибки без остановки макроса и просто возвращая значение ошибки

    Это я используется только в .Offset(0, 1).Value = Application.VLookup(.Offset(0, -11)..., так что если «последний шанс поиска» когда-либо возвратил ошибку вы бы это написано в вашей .Offset(0,1) ячейке

  • использование SpecialCells() метода возвращать отфильтрованную группу диапазона вы называете его: например, с использованием xlCellTypeConstants в качестве параметра Type вы получите обратно не пустую ячейку только

  • IsNumeric() использования функции вместо [WorksheetFunction.IsNumber() [(https://msdn.microsoft.com/en-us/library/office/ff840818(v=office.15).aspx), так как первый будет распознавать строку «5» в виде числа, в то время как последний будет не

+0

ЭТО РАБОТАЕТ. СПАСИБО БОЛЬШОЕ!! Теперь единственное, что можно назвать каждый диапазон. Если у вас есть проницательность, пожалуйста, дайте мне знать! – Ashley

+0

Вы приветствуете. В соответствии с этим сайтом правила: 1) вопрос о девчонке должен быть задан с новым сообщением 2), так как я заполнял ваш вопрос, пожалуйста, отмените мой ответ как сжатый. Спасибо. – user3598756