У меня есть следующая функция, написанная в модуле VBA в качестве тестового примера. На данный момент функция включает только один «Случай», потому что я хочу его протестировать и в случае успеха заполнить дополнительными «Случаями»:
Function Insurn(indicator as String, value as Double)
Select Case indicator
Case string_indicator1
If value >= 11 And value <= 99 Then
asset_val = 5
ElseIf value >= 6 And value <= 10 Or value >= 100 Then
asset_val = 4
ElseIf value >= 0 And value <= 5 Then
asset_val = 3
ElseIf value >= -5 And value < 0 Then
asset_val = 2
ElseIf value >= -14 And value < -5 Then
asset_val = 1
ElseIf value >= -24 And value < -14 Then
asset_val = 0
Else val < -24 Then
End If
End Select
End Function
Я применяю эту функцию, вводя следующие данные Insurn("string_indicator1", 12), и она возвращает значение 0. Однако я ожидаю, что функция вернет 5.
И многое другое: независимо от того, какое число присвоено параметру value, функция неизменно возвращает 0 значение.
Помогите, пожалуйста, разобраться, как заставить эту функцию работать правильно.


Вы передаете строку "string_indicator1" в качестве аргумента параметра функции indicator (так что indicator = "string_indicator1")
В вашем операторе случая вы проверяете, является ли indicatorstring_indicator1, но это не строка, а переменная. Эта переменная, вероятно, не определена и поэтому содержит пустую строку. Поскольку это не равно значению в indicator, вся ваша конструкция If-ElseIf... никогда не выполняется. Значение функции никогда не вычисляется, и функция всегда возвращает 0 (это значение по умолчанию в VBA).
Вам просто нужно изменить оператор случая на
Case "string_indicator1"
И вам следует сделать 2 вещи:
Всегда используйте Option Explicit в верхней части кода (в редакторе VBA используйте «Инструменты» -> «Параметры» и на вкладке «Редактор» установите флажок «Требовать объявление переменной»).
Научитесь использовать отладчик VBA, проверяйте свой код, проходя все операторы, это помогает понять, как работает ваш код и почему он не работает. Я рекомендую ввести описание ссылки здесь, но есть миллионы других уроков.
Я думаю, сначала вам нужно понять, как работают UDF (пользовательские функции). При создании пользовательской функции необходимо назначить значение, возвращаемое этой пользовательской функцией.
Что-то вроде этого:
Function MYSUM(a As Integer, b As Integer) As Integer
result = a + b
End Function
Это всегда будет возвращать ноль, потому что я не назначил никакого возвращаемого значения. Теперь проверьте это:
Function MYSUM(a As Integer, b As Integer) As Integer
result = a + b
MYSUM = result
End Function
Это будет работать так, как ожидалось. во-вторых, сравнение прямых строк/числа или переменных. У вас есть эта строка:
Case string_indicator1
Здесь string_indicator1 вызывается как переменная, а не как прямая строка, и переменная пуста, поэтому на самом деле ваш код проверяет пустую переменную.
Итак, если вы вызываете свою функцию как Insurn("string_indicator1", 12), вероятно, вам нужен примерно такой код:
Function Insurn(indicator As String, value As Double)
'always declare your variables
Dim asset_val As Integer 'or whatever tipe you need
Select Case indicator
Case "string_indicator1"
If value >= 11 And value <= 99 Then
asset_val = 5
ElseIf value >= 6 And value <= 10 Or value >= 100 Then
asset_val = 4
ElseIf value >= 0 And value <= 5 Then
asset_val = 3
ElseIf value >= -5 And value < 0 Then
asset_val = 2
ElseIf value >= -14 And value < -5 Then
asset_val = 1
ElseIf value >= -24 And value < -14 Then
asset_val = 0
End Select
'assign result to function!
Insurn = asset_val
End Function
Обратите внимание на модификацию Case и, наконец, на то, как код назначает возвращаемый результат.
Надеюсь, это поможет вам
В дополнение к предыдущим ответам будет более читабельно повторно использовать Select Case вместо повторения If - Then - ElseIf:
Select Case Value
Case 11 To 99: asset_val = 5
Case 6 To 10, Is > 100: asset_val = 4
Case 0 To 5: asset_val = 3
Case -5 To 0: asset_val = 2 ' -5 To -1
Case -14 To -5: asset_val = 1 ' -14 To -6
Case -24 To -14: asset_val = 0 ' -24 To -15
End Select
если переменная Value имеет целочисленный тип, удобнее использовать диапазоны, указанные в комментариях.
Function Insurn(Indicator As String, Value As Double) As Variant
Dim AssetValue As Variant
Select Case LCase(Indicator)
Case LCase("string_indicator1")
If Value >= 11 And Value < 100 Then
AssetValue = 5
Else
Select Case Value
Case Is >= 6: AssetValue = 4
Case Is >= 0: AssetValue = 3
Case Is >= -5: AssetValue = 2
Case Is >= -14: AssetValue = 1
Case Is >= -24: AssetValue = 0
Case Else: AssetValue = CVErr(xlErrNum) ' "Value Too Low"
End Select
End If
' add more cases:
'Case LCase("")
'Case LCase("")
Case Else: AssetValue = CVErr(xlErrNA) ' "Indicator Not Available"
End Select
Insurn = AssetValue
End Function
Else val < -24 Thenнедействителен VBA.string_indicator1— это не то же самое, что"string_indicator1". ПоставьтеOption Explicitсверху.