Функция Iif неверно выполняется

отредактировано October 2009 Раздел: FastReport .NET
Добрый вечер.

В отчёте имеется: параметр "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;
работал бы нормально, НЕ проверяя первую часть условия, т.к. оно не выполняется! А тут обе части проверяются. Как же быть, если необходимо такое условие?

Комментарии

  • отредактировано October 2009
    Здравствуйте,

    Ф-я IIf из VB.Net ведет себя аналогично. При вызове ф-и IIf, как и любой другой ф-и, вычисляются все значения ее параметров. Вам больше подойдет оператор ? языка C#:
    [[isSecondPageData] == true ? [PersonCard.WorkInfo.TabNumLnkRecordObject.Department] : ""]
  • отредактировано 09:31
    AlexTZ написал: »
    Вам больше подойдет оператор ? языка C#:
    [[isSecondPageData] == true ? [PersonCard.WorkInfo.TabNumLnkRecordObject.Department] : ""]
    К сожалению, та же ошибка... :) При true работает, а при false - ошибка, т.к. объекта нет.

    Что-то ещё можно сделать?
  • отредактировано 09:31
    Должно работать. Скорее всего, ошибка где-то в другом месте. Проверил на демо:
    вот это срабатывает: [true ? 1 : 1/([Page] - 1)]
    а вот это нет (деление на 0): [false ? 1 : 1/([Page] - 1)]
  • отредактировано October 2009
    AlexTZ написал: »
    Должно работать. Скорее всего, ошибка где-то в другом месте. Проверил на демо:
    вот это срабатывает: [true ? 1 : 1/([Page] - 1)]
    а вот это нет (деление на 0): [false ? 1 : 1/([Page] - 1)]

    Странно. Может, дело в русских буквах? У меня ошибка происходит в той ячейке, где свойство называется по-русски: [[isSecondPageData] == true ? [PersonCard.WorkInfo.TabNumLnkRecordObject.Справочник подразделений*] : ""]

    Почему по-русски? Дело в том, что свойства в этот объект запихиваются динамически, т.е. в коде такого свойства нет. Эти свойства генерируются для грида, поэтому, нужен русский язык.
    И дело не в том, что свойства эти не работают, они работают, когда они есть(показываются в отчёте отлично). Но когда объект WorkInfo равен null, даже при условии false возникает ошибка при вызоые метода Show() у отчёта.
  • отредактировано 09:31
    Вряд ли это русские буквы. Можете сделать простой проект с этой ошибкой и прислать мне на tz@fast-report.com?
  • отредактировано 09:31
    AlexTZ написал: »
    Вряд ли это русские буквы. Можете сделать простой проект с этой ошибкой и прислать мне на tz@fast-report.com?
    Отправил! Спасибо.
  • отредактировано October 2009
    Понятно. Опишу суть ошибки:

    Перед запуском отчета 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].
  • отредактировано 09:31
    AlexTZ написал: »
    В тот момент, когда регистрируете данные вызовом rprt.RegisterData(pcworkInfoList, "WorkInfo"); - поле "WorkInfo.TabNumLnkRecordObject.Ещё" перестает существовать
    Спасибо, примерно это я и предполагал...
    AlexTZ написал: »
    Как с этим бороться?
    1) по возможности не допускать изменений структуры бизнес-объекта
    Ну эта структура будет постоянна... Единственный случай - когда workInfo null. Тут даже не надо динамических полей...
    AlexTZ написал: »
    2) использовать доступ к полям вида Report.GetColumnValue("MyTable.MyColumn"), вместо [MyTable.MyColumn].
    Вот это не совсем понял... Применительно к проекту, что я Выслал, как можно избежать ошибки, если там необходимо это условие? Т.е. мне нужно печатать информацию, если она есть и печатать пустой лист, если её нет...

    Спасибо!
  • отредактировано 09:31
    [[isTrue] == true ? (String)Report.GetColumnValue("WorkInfo.TabNumLnkRecordObject.Ещё") : ""]
  • отредактировано 09:31
    AlexTZ написал: »
    [[isTrue] == true ? (String)Report.GetColumnValue("WorkInfo.TabNumLnkRecordObject.Ещё") : ""]

    Супер, работает! Спасибо!

Оставить комментарий

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.