ВБА. Вложение if elseif в процедуру Select Case

У меня есть следующая функция, написанная в модуле 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 значение.

Помогите, пожалуйста, разобраться, как заставить эту функцию работать правильно.

Else val < -24 Then недействителен VBA. string_indicator1 — это не то же самое, что "string_indicator1". Поставьте Option Explicit сверху.
GSerg 16.04.2024 10:30
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
1
1
70
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы передаете строку "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 имеет целочисленный тип, удобнее использовать диапазоны, указанные в комментариях.

Условия вложения (UDF)

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

Другие вопросы по теме