2016-01-29 2 views
2

Я хотел бы использовать оператор IF в моем коде VBA, где я вызываю функцию и передаю ей два параметра. Причина, по которой мне нужен оператор IF, заключается в том, что параметр является объектом массива, который я передаю функции. Вот это аббревиатура от кода, который содержит задачу:Могу ли я иметь оператор «If» в параметре функции?

For i = 1 To UBound(FilterArray) 
    For j = LBound(ptsheets, 1) To UBound(ptsheets, 1) 
     Filter_PivotField_Master _ 
      pvtField:=ThisWorkbook.Worksheets(ptsheets(j, 1)).PivotTables(ptsheets(j, 2)).PivotFields(FilterArray(i, 1)), _ 
      FilterTypeArray:= If FilterArray(i, 2) = 1 Then 
           InvCodeArray 
           Else 
           BoardMonthArray 
           End If 
    Next j 
Next i 

Как вы можете видеть, я перекручивание через массив ptsheets и для каждой записи, я звоню вверх Filter_PivotField_Master функции. Для функции требуется два входа (сводное поле и строковый массив для фильтрации). Массив, называемый FilterArray, просто содержит информацию, необходимую для передачи функции. Поскольку я не могу хранить массив строк (InvCodeArray или BoardMonthArray) в «FilterArray», я хотел использовать этот оператор IF для выбора между массивом, основанным на том, что FilterArray (i, 2) равен «1», или нет. Возможна ли опция утверждения «IF» здесь?

ответ

5

Не делайте этого. Извлеките метод/процедуру из внутреннего цикла и вместо этого параметризуйте его.

For j = LBound(ptsheets, 1) To UBound(ptsheets, 1) 
     Filter_PivotField_Master _ 
      pvtField:=ThisWorkbook.Worksheets(ptsheets(j, 1)).PivotTables(ptsheets(j, 2)).PivotFields(thePivotField), _ 
      FilterTypeArray:= theFilterType 
    Next j 

Затем, вызывающий код (внешний цикл) реализует условную логику, которая определяет, какие параметры дать.

Dim thePivotField 
Dim theFilterType 

For i = 1 To UBound(FilterArray) 
    thePivotField = FilterArray(i, 1) 
    If FilterArray(i, 2) = 1 Then 
     theFiltertype = InvCodeArray 
    Else 
     theFilterType = BoardMonthArray 
    End If 
    TheExtractedMethod i, thePivotField, theFilterType 
Next i 

Ваш код будет намного проще отслеживать - и отлаживать.


На соответствующую записку, я сделал несколько предположений просто получить фрагмент кода для компиляции с Option Explicit на (и IIf вместо незаконного If...Else блока), и Rubberduck «ы последнего выпуска (v1.4.3) правильно извлекали выбранный внутренний контур в свой собственный метод:

Rubberduck's Extract Method refactoring tool

Есть несколько известных ошибок с Rubberduck 1.4.3 и v2.0 приходит скоро-иш, но я думал, что это может вас заинтересовать. Я не знаю никаких других инструментов рефакторинга для VBA. Обратите внимание, что Option Explicit в значительной степени является трудным требованием для этого, так как Rubberduck работает с объявлениями и не может разрешить необъявленные переменные.

Disclaimer: I wrote this refactoring tool.

+0

Это сработало отлично. Спасибо! – AGryckiewicz

+0

@AGryckiewicz FYI Я только что проверил это с помощью инструмента * Extract Method * рефакторинга моей надстройки Rubberduck VBE, и он сработал. Вы можете посмотреть на это. –

+0

Ницца. Я действительно не понимаю, что такое «инструмент рефакторинга» и какова цель, которую он обслуживает, но мне интересно узнать больше. Благодарим за передачу информации. – AGryckiewicz

4

Для этого используйте немедленный IF (IIF).

FilterTypeArray = IIF(FilterArray(i, 2) = 1, InvCodeArray, BoardMonthArray) 
+1

@Fadi: Спасибо. Я написал * немедленный IF *, а затем сразу же опечатал имя функции. Спасибо за уловку. –

+1

Остерегайтесь, хотя 'IIf' оценивает * оба оператора значений перед возвратом, поэтому лучше избегайте его для чего-либо, кроме постоянных выражений. –

+0

Спасибо. Функция IIf работала с точки зрения синтаксиса, но я получаю ошибку компиляции: «Тип несоответствия: массив или пользовательский тип ожидается» Функция ожидает массив. Не могу ли передать массив, используя этот подход IIF? – AGryckiewicz

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