встроенные состояния IIF в SSRS

Спасибо, что нашли время, чтобы помочь мне сегодня. Я пытаюсь использовать несколько операторов if, чтобы контролировать, какое значение отображается в зависимости от того, верно ли каждое утверждение. Итак, сейчас у меня есть это ниже, что по существу:

IIF(expression = NULL
, CompanyAddress
, IIF(Expression='TX'
    , IIF(BOOL=TRUE
        ,CompanyAddress
        , SWITCH(DEALER ADDRESSES))
    ,CompanyAddress)
)

Я протестировал каждый отдельный оператор IIF отдельно и получил ожидаемые результаты. В настоящее время в первом выражении IIF выражение = NULL равно TRUE, оно просто выводит #Error, а не «Nothin» ИЛИ в моем реальном случае Адрес компании. Но если Expression = NULL имеет значение FAlSE, я получаю правильный вывод либо companyAddress, либо Dealer.

=IIF(IsNothing(Fields!CoOppId.Value)
,("nothin")
, (IIF(Fields!Addr1.Value.Contains("TX")
    , IIF(Fields!UDFCustProv.Value = 1
        , Fields!Addr0.Value
        , Switch(
            Fields!UDFMake.Value.Contains("Chevy")
            , "Knapp Chevrolet" + chr(10) + "PO box " + chr(10) + "Houston TX 77210"
            , Fields!UDFMake.Value.contains("Ford") 
            , "Sterling McCall Ford" + chr(10) + "6445 Southwest Freeway" + chr(10) + "Houston TX 77074"
            , Fields!UDFMake.Value.contains("International")
            , "Pliler International" + chr(10) + "2016 S. Eastman Rd" + chr(10) + "Longview TX 75602"
            , Fields!UDFMake.Value.contains("Freightliner")
            , "Houston Freightliner, Inc" + chr(10) +"9550 North Loop East" + chr(10) + "Houston TX 77029"
            , Fields!UDFMake.Value.contains("RAM")
            , "Max Haik Dodge Chrysler Jeep" +chr(10)+ "11000 I-45 North Freeway" + chr(10) + "Houston TX 77037")),Fields!Addr0.Value)))

person erick barreat    schedule 19.07.2017    source источник
comment
Попробуйте этот ответ: StackOverflow   -  person Lucky    schedule 19.07.2017
comment
Не повезло в этой теме   -  person erick barreat    schedule 19.07.2017
comment
Вы сказали, что условие ELSE в основной IIF работает нормально, поэтому не могли бы вы сократить его до единственной IIF верхнего уровня и сообщить нам, по-прежнему ли это вызывает ошибку? на самом деле теперь я вижу, что вы сказали, что уже подтвердили, что это работает. Следующий вопрос: в случае, если CoOppId имеет значение NULL, являются ли другие поля в этой строке также NULL?   -  person Daniel    schedule 19.07.2017
comment
Нет, я просто проверяю, является ли это поле пустым, а затем отображаю поля, которые должны быть заполнены, если CoOppId имеет значение Null.   -  person erick barreat    schedule 19.07.2017
comment
Я думаю, что Дэниел прав. Когда CoOppId имеет значение Null, по крайней мере еще одно поле в вашем выражении имеет значение null, и это является причиной #Error. Попробуйте использовать COALESCE(fieldname,'') в коде SQL для остальных строковых полей или COALESCE(fieldname,0) для числовых полей.   -  person niktrs    schedule 20.07.2017


Ответы (2)


Я согласен с @Daniel, ошибка, скорее всего, возникает из-за Fields!UDFMake.Value.Contains, когда значение равно null, поскольку IIF не замыкается. В качестве альтернативы хорошим вариантам, упомянутым @Daniel, вы можете заменить метод contains функцией InStr как:

... , Switch(
            InStr(Fields!UDFMake.Value,"Chevy") > 0
            , "Knapp Chevrolet" + chr(10) + "PO box " + chr(10) + "Houston TX 77210" ...

это не приведет к ошибке, даже если значение поля равно Null.

person Jayvee    schedule 19.07.2017

Я собираюсь предположить, что когда ваше значение CoOppId равно NULL, другие ваши поля в этой строке также имеют значение NULL. Поскольку IIF не использует логику короткого замыкания (он всегда оценивает обе стороны IIF), вы пытаетесь вычислить выражение "NULL.Contains("TX")", и это сгенерирует ошибку #ERROR, поскольку NULL не является строкой и нельзя работать с функцией CONTAINS.

Для этого сценария доступны два обходных пути, однако ни один из них не особенно хорош, на мой взгляд:

1) Используйте вложенные IIF, чтобы гарантировать, что ничто никогда не будет недействительным.

IIF(expression is NULL 
, CompanyAddress
, IIF(**IIF(expression is NULL, "", expression)** ='TX'
    , IIF(BOOL=TRUE
        ,CompanyAddress
        , SWITCH(DEALER ADDRESSES))
    ,CompanyAddress)
)

Посмотрите на приведенный выше псевдокод и обратите внимание на дополнительный вложенный IIF вокруг выражения, использующего функциональность CONTAINS. Если CoOppId не существует, он заменяется пустой строкой для проверки CONTAINS. Несмотря на то, что эта ветвь никогда не показывает свое значение для нулевого сценария, она, по крайней мере, теперь будет действительна.

2) Создайте функцию кода программной части, которая фактически выполняет логику короткого замыкания для вас:

Public Function CheckForNull(ByVal CoOppId As String, ByVal Addr1 as String, ByVal UDFMake As String, ... all fields)
If String.IsNullOrEmpty(CoOppId) 
  Return "Nothing"
Else
  Return *** do your calculation with your fields here
End If
End Function 

Который вы используете в своем отчете, например:

=Code.CheckForNull(values....)

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

person Daniel    schedule 19.07.2017
comment
Это кажется правильным направлением моего дальнейшего исследования. Я попытаюсь это сделать и вернусь к вам с моими выводами - person erick barreat; 19.07.2017
comment
Пользовательский код был бы хорошим обходным путем, чтобы избежать ошибок, а также упростить чтение вашего выражения. - person niktrs; 20.07.2017
comment
Спасибо, Даниил, за отличный ответ. Кажется, у вас была правильная идея, но ответ Джейви был решением, благодаря которому мой сценарий заработал. Если бы я мог отметить оба ответа, я бы это сделал. - person erick barreat; 25.07.2017