Функция Iif неверно выполняется
Добрый вечер.
В отчёте имеется: параметр "isSecondPageData", а так же источник данных, список объектов: PersonCard. В одной из ячеек таблицы стоит значение:
Почему так происходит? Ведь во многих языках программирования обычный IF вида
В отчёте имеется: параметр "isSecondPageData", а так же источник данных, список объектов: PersonCard. В одной из ячеек таблицы стоит значение:
[IIf([isSecondPageData],[PersonCard.WorkInfo.TabNumLnkRecordObject.Department],"")]
Когда параметр из программы устанавливается в true, то, естественно, объект PersonCard.WorkInfo существует и прекрасно отображается в отчёте. Но когда этот параметр false, источник данных передаётся БЕЗ объекта PersonCard.WorkInfo, вернее, он равен null. И при этом, не смотря на то, что отчёт должен напечатать пустую строку, он выдаёт exception вида:
FastReport.Utils.CompilerException was unhandled
Message="(Cell334): error CS1525: Invalid expression term ''\r\n(Cell334): error CS1002: ; expected\r\n(Cell334): error CS1525: Invalid expression term ','\r\n(Cell334): error CS1002: ; expected\r\n(Cell334): error CS1002: ; expected\r\n(Cell334): error CS1525: Invalid expression term ')'\r\n"
Почему так происходит? Ведь во многих языках программирования обычный IF вида
if(a != null) a.doSomething(); else return 0;
работал бы нормально, НЕ проверяя первую часть условия, т.к. оно не выполняется! А тут обе части проверяются. Как же быть, если необходимо такое условие?
Комментарии
Ф-я IIf из VB.Net ведет себя аналогично. При вызове ф-и IIf, как и любой другой ф-и, вычисляются все значения ее параметров. Вам больше подойдет оператор ? языка C#:
[[isSecondPageData] == true ? [PersonCard.WorkInfo.TabNumLnkRecordObject.Department] : ""]
Что-то ещё можно сделать?
вот это срабатывает: [true ? 1 : 1/([Page] - 1)]
а вот это нет (деление на 0): [false ? 1 : 1/([Page] - 1)]
Странно. Может, дело в русских буквах? У меня ошибка происходит в той ячейке, где свойство называется по-русски: [[isSecondPageData] == true ? [PersonCard.WorkInfo.TabNumLnkRecordObject.Справочник подразделений*] : ""]
Почему по-русски? Дело в том, что свойства в этот объект запихиваются динамически, т.е. в коде такого свойства нет. Эти свойства генерируются для грида, поэтому, нужен русский язык.
И дело не в том, что свойства эти не работают, они работают, когда они есть(показываются в отчёте отлично). Но когда объект WorkInfo равен null, даже при условии false возникает ошибка при вызоые метода Show() у отчёта.
Перед запуском отчета FastReport компилирует его. При этом он проверяет все выражения и заменяет обращение к данным вида [MyTable.MyColumn] на "вещи, поддающиеся компиляции" типа ((String)Report.GetColumnValue("MyTable.MyColumn")). НО! Только для полей, которые существуют. Если в таблице MyTable есть поле MyColumn, то все ок. Если его нет - форма [MyTable.MyColumn] преобразована не будет и в таком виде попадет компилятору. Тот, естественно, выдаст целый букет ошибок, связанных с применением квадратных скобок.
В Вашем примере как раз это и происходит. В тот момент, когда регистрируете данные вызовом rprt.RegisterData(pcworkInfoList, "WorkInfo"); - поле "WorkInfo.TabNumLnkRecordObject.Ещё" перестает существовать (тут надо сказать отдельное спасибо методу, который синхронизирует структуру бизнес-объекта при его регистрации).
Как с этим бороться?
1) по возможности не допускать изменений структуры бизнес-объекта
2) использовать доступ к полям вида Report.GetColumnValue("MyTable.MyColumn"), вместо [MyTable.MyColumn].
Ну эта структура будет постоянна... Единственный случай - когда workInfo null. Тут даже не надо динамических полей...
Вот это не совсем понял... Применительно к проекту, что я Выслал, как можно избежать ошибки, если там необходимо это условие? Т.е. мне нужно печатать информацию, если она есть и печатать пустой лист, если её нет...
Спасибо!
Супер, работает! Спасибо!