2013-08-16 2 views
0

Я пытался реализовать комбинацию совпадений индекса в VBA, чтобы найти число в диапазоне, заданном 2 условиями. Ниже представлен отличный подход, однако мои входы не исходят из excel, а из переменной, которая меняет сам код. Для жизни я не могу понять это, но я новичок.Соотношение индекса в VBA для диапазонов (поиск баланса кредита с учетом номера кредита и даты)

Excel/VBA - Index Match function using Dynamic Ranges

Что произойдет, если ваше имя и дата вместо ряд кредита (1,2,3 и т.д.) и дата (6/30/2013) и не в таблице, а формируются в VBA, чтобы затем код мог перейти в диапазон и искать баланс этого займа в такой дате и хранить его в переменной

----------------- ОПРЕДЕЛЕНИЯ ДИАПАЗОНОВ ------------------------------------------------ -------------------------

О коде: Cantidad, ID и Fecha являются диапазонами диманианов, определенными в мычание образом:

With Worksheets("CFs") 
Set ID = Range("offset($a$3,4,0,counta($A:$A)-4,1)") 
Set Fecha = Range("offset($b$3,4,0,counta($B:$B)-4,1)") 
Set Cantidad = Range("offset($f$3,4,0,counta($F:$F)-4,1)") 
End With 

------------------ ФУНКЦИЯ КОД ------------------- -------------------------------------------------- - о функции: dia1 и ID - это дата, которая изменяется ежемесячно и номер кредита, который зацикливается один раз, пока не будет достигнуто общее количество кредитов.

Public Function TestIndexMatch1(ByRef Cantidad As Range, _ 
                ByRef Prestamo As Integer, _ 
                ByRef Dia1 As Date, _ 
                ByRef ID As Range, _ 
                ByRef Fecha As Range) 

        Const Template As String = "=INDEX({0},MATCH(1,({1}={2})*({3}={4},{5}))" 

        Const MATCH_TYPE = 0 
        On Error GoTo Err_Handler 
        Err.Number = 0 

        Dim originalReferenceStyle 
        originalReferenceStyle = Application.ReferenceStyle 
        Application.ReferenceStyle = xlR1C1 

        Dim myFormula As String 
        myFormula = Replace(Template, "{0}", Cantidad.Address()) 
        myFormula = Replace(Template, "{1}", Prestamo.Address()) 
        myFormula = Replace(Template, "{2}", Dia1.Address()) 
        myFormula = Replace(Template, "{3}", ID.Address()) 
        myFormula = Replace(Template, "{4}", Fecha.Address()) 

        TestIndexMatch1 = Application.Evaluate(myFormula) 

Err_Handler: 
         If (Err.Number <> 0) Then MsgBox Err.Description 
         Application.ReferenceStyle = originalReferenceStyle 


End Function 
+0

Этот код, по-видимому, излишне усложняет ситуацию без необходимости. Не могли бы вы объяснить, что вы хотите сделать именно в простых словах и, в идеале, с примером; например: «Я хочу искать совпадения значения в C12 в столбце X, а затем и т. д.». Имейте в виду, что если вы хотите так сильно полагаться на формулы Excel, вы не должны использовать VBA. – varocarbas

ответ

0

Во-первых, он выглядит, как вы не хватает нескольких вещей:

  1. закрывающая скобка в формуле строки ... {4} ), {5} ...
  2. точки перед диапазоном в определениях имен (Set ID = .Range)

Но я думаю, что вы могли бы хотеть идти о вещах, немного по-другому. Если вы определяете переменные в VBA, которые будут использоваться в функциях листа на листе, вам нужно быть осторожными в определении зависимостей. Каждый диапазон, который используется в функции VBA, должен быть входным аргументом функции, поэтому Excel будет пересчитывать каждый раз, когда это значение изменяется. Еще одна проблема с оценкой формул в коде - отсутствие промежуточной отладочной информации, а функции не всегда оцениваются так, как на листе.

В первой части я думаю, что вы хотите, чтобы имена установки листа, это может быть сделано путем следующей корректировки коды выше:

Sub SetUpNames() 
With Worksheets("CFs").Names 
    .Add "ID", "=offset($a$3,4,0,counta($A:$A)-4,1)" 
    .Add "Fecha", "=offset($b$3,4,0,counta($B:$B)-4,1)" 
    .Add "Cantidad", "=offset($f$3,4,0,counta($F:$F)-4,1)" 
End With 
End Sub 

Это также можно сделать с помощью диалогового окна Имени определенно. Эти имена затем могут быть вставлены в функцию в связанной записи.

Для второй части коды, здесь является альтернативой функции в связанном посте, который также использует функцию рабочего листа подход:

Public Function TestIndexMatch2(ByRef outputRange As Range, _ 
          ByRef nameCriteria As Range, _ 
          ByRef dateCriteria As Range, _ 
          ByRef nameRange As Range, _ 
          ByRef dateRange As Range) 

Dim v as Variant 
With Application 
    v = .CountIfs(nameCriteria, nameRange, dateCriteria, dateRange) 
    TestIndexMatch2 = .Index(outputRange, .Match(1, v, 0)) 
End With 

End Function 

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

Примечание: Использование приложения без .WorksheetFunction возвращает вариант, который допускает массивы в аргументах и ​​результатах.Однако VBA не предоставляет все функции рабочего листа или операторы Excel, поэтому вам нужно быть более находчивыми при таком подходе, например, отсутствует функция Exact, но есть обходные пути, такие как len (substitute (a, b, "")) = 0.

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

  • Нет связанных вопросов^_^