Нарезка массива в VBA на основе условия - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть массив значений в VBAscript, которые рассчитываются по двум диапазонам, предоставленным функции. Мне нужно выполнить расчет только для подмножества значений в этом массиве, удовлетворяющих пороговому условию. Пока у меня есть рабочий код:

Public Function CalculateCVar(exposure_v As Range, pdd_m As Range, a As Double) As Double
Dim ret_v_tail() As Double
Dim l, i As Integer

ret_v = Application.WorksheetFunction.MMult(exposure_v, _
        Application.WorksheetFunction.Transpose(pdd_m))
value_at_risk = Application.WorksheetFunction.Percentile_Inc(ret_v, a)

l = 1

For i = 1 To UBound(ret_v)
    If ret_v(i) <= value_at_risk Then
        ReDim Preserve ret_v_tail(l)
        ret_v_tail(l) = ret_v(i)
        l = l + 1
    End If
Next i

CalculateCVar = Application.WorksheetFunction.Average(ret_v_tail)

End Function

Однако мне было интересно, существует ли лучшая или более рациональная альтернатива для выбора подмножества массива в VBA, удовлетворяющего определенному условию, то есть нарезки массива основанный на условии. Псевдокод будет выглядеть следующим образом:

ret_v = [1., 2., 3., 4., 2., 4., 1., ...]
ret_v_tail = ret_v[ret_v <= 2.]

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

1 Ответ

1 голос
/ 08 апреля 2020

Redim Preserve может быть дорогим, используйте его только дважды (один в начале и один в конце)

например, вы можете использовать эту функцию

Function GetTail(ret_v As Variant, value_at_risk As Double) As Variant
    Dim i As Long, iTail As Long

    iTail = LBound(ret_v)
    ReDim ret_v_tail(iTail To UBound(ret_v)) As Variant ' dim the tail to maximum possible items
    For i = iTail To UBound(ret_v)
        If ret_v(i) <= value_at_risk Then
            ret_v_tail(iTail) = ret_v(i)
            iTail = iTail + 1
        End If
    Next i
    ReDim Preserve ret_v_tail(LBound(ret_v) To iTail - 1) As Variant ' redim tail to actual items number
    GetTail = ret_v_tail
End Function

для вызова в вашем коде как

ret_v_tail = GetTail(ret_v, 2#)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...