Отсутствует ParamArray в UDF - PullRequest
0 голосов
/ 03 июня 2018

Я пытаюсь определить, когда пользовательская функция (UDF), использующая ParamArray, использовалась на листе без предоставленных параметров ParamArray.

Я пробовал IsEmpty, IsArray,IsError, сравнение с ничем, сравнение со строкой нулевой длины и т. Д.

Я знаю, что paramarray всегда byVal и что вариантный массив всегда основан на нуле, но если он не существуеткак это массив?

  • сравнение первого элемента массива с Nothing или Not Nothing выдает ошибку
  • IsEmpty сообщает False
  • IsArray странным образом сообщает True
  • IsError сообщает False для обоих тестов и тестов (0)

testParams UDF:

Public Function testParams(ByRef ndx As Long, ParamArray tests())
    Select Case ndx
        Case 1
            testParams = CBool(tests(LBound(tests)) Is Nothing)
        Case 2
            testParams = IsEmpty(tests)
        Case 3
            testParams = IsArray(tests)
        Case 4
            testParams = IsError(tests)
        Case 5
            testParams = CBool(tests(LBound(tests)) = vbNullString)
    End Select
End Function

В следующем примере я просто возвращаюсь на листто, что пытается получить доступ к ParamArray, возвращает.

enter image description here

Как определить, не предоставил ли пользователь параметры ParamArray в реальном мире?UDF, что требует их?Я бы предпочел простую булеву проверку вместо проверки на предмет проверки, является ли что-то ничем.

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Отличное объяснение распределения массива: http://www.cpearson.com/Excel/IsArrayAllocated.aspx

Выдержка:

Функция ниже, IsArrayAllocated точно вернет True или False, указывая, выделен ли массив,Эта функция будет работать как для статических, так и для динамических массивов любого числа измерений, и будет корректно работать для нераспределенных массивов с действительными (не вызывающими ошибки) LBound значениями

и функцией

Function IsArrayAllocated(Arr() As Variant) As Boolean
    On Error Resume Next
    IsArrayAllocated = IsArray(Arr) And _
        Not IsError(LBound(Arr, 1)) And _
        LBound(Arr, 1) <= UBound(Arr, 1)
End Function

Использование его с Function с массивом параметров

Function MyFunc(ParamArray pa()) As Variant
    Dim v()
    v = pa
    If IsArrayAllocated(v) Then
        'Do stuff with the parameters
    Else
        'There are no parameters...
    End If
End Function
0 голосов
/ 03 июня 2018

TL; DR - использовать, если IsMissing (тесты) Тогда ...

NTL & WR:

Даже если ParamArray нельзя использоватьвместе с любым объявленным необязательным параметром (включая сам ParamArray) не выдается никакой ошибки, если он опущен.Можно легко утверждать, что ParamArray всегда необязателен , хотя его нельзя пометить как таковой.

From: Массивы параметров (Visual Basic) Массив параметров автоматически необязателен.Его значением по умолчанию является пустой одномерный массив типа элемента массива параметров.

ParamArray, который не был предоставлен пользователем, будет вариантным массивом, который был создан, но ни заполнен, ни положительноразмеры.

Он будет определен с LBound , равным 0 (ноль) и UBound , равным -1 (минус один).Это то же самое, что и любой другой вариантный массив, объявленный, но не имеющий размерности.

Поскольку всегда является параметром типа варианта , он также правильно сообщит о своем присутствии или отсутствии с помощью IsMissing .

Public Function testParams(ByRef ndx As Long, ParamArray tests())
    Select Case ndx
        Case 1
            testParams = CBool(tests(LBound(tests)) Is Nothing)
        Case 2
            testParams = IsEmpty(tests)
        Case 3
            testParams = IsArray(tests)
        Case 4
            testParams = IsError(tests)
        Case 5
            testParams = CBool(tests(LBound(tests)) = vbNullString)
        Case 6
            testParams = CBool(UBound(tests) = -1)
        Case 7
            testParams = IsMissing(tests)
    End Select
End Function

Проверка значения IsMissing или UBound, равного -1, определит, предоставил ли пользователь параметр paramarray.

enter image description here

...