29 октября 2018 г.

Решение нетипичных проблем с FastReport.

Статья будет состоять из способов решения проблем с FastReport ver. 2018.3.20. Проблемы изложенная тут может быть исправлена в последующих версиях FastReport либо отсутствовать в прошлых. Так же не исключаю, что я могу не знать что то, тогда если вам известно решение, то буду рад комментариям. Заранее Спасибо! 

Темы описанные в статье:
  1. Автоматическая высота строки для текста не помещающегося в ячейку.
  2. Как обойти в коде все строки таблицы DataSource.
  3. Как использовать Linq или подключить сборки в отчёт FastReport.
  4. Объединение ячеек таблицы.
  5. Не работающий междустрочный интервал.
  6. Примеры использования условного оператора IIF(,,) в дизайнере отчёта.
  7. Сортировка и группировка данных в таблице отчёта.
  8. При экспорте в Excel или в Html большой таблицы, ячейки начинают биться либо появляется разделительная линия.



1. Автоматическая высота строки для текста не помещающегося в ячейку.


Достаточно неприятная ситуация, когда при построении таблиц и экспорте в xlsx, либо docx текст не помещается. Поэтому следует сначала убедиться в том, что выполняются эти 3 вещи:
  1. CanGrow (Может расти) у DataBand таблицы:

  2. Если ячейки сделаны через TextObject тогда следуем всем им проставить признак CanGrow (Может расти):

  3. Если в качестве контейнера ячеек используете TableObject (что намного удобнее, нежели если использовать много TextObject), тогда следует выбрать AutoSize=True для вытягивания строк таблицы.

Но это все не исключает того, что в ячейке не будет проблем с последней строкой (изредка строками), поскольку до сих пор, по непонятной причине, FastReport неверно вычисляет её высоту, как на примере ниже:


Поэтому самым простым способом избавления от этой проблемы:
  1. Добавление новой строки в ячейке, где данные не умещаются
  2. В новой строке добавить "Невидимый символ", что бы не срабатывало автоматическое обрезание, которое по непонятным причинам происходит даже с выставленным Trimming=None свойством.
Что за невидимый символ? Я использую символ с кодом 255, для этого я зажимаю ALT на клавиатуре и на правой части (где NumLock) ввожу 2->2->5, затем отпускаю ALT и появляется пустое место, как пробел. Тем самым последняя строка становится предпоследней и почти всегда будет умещаться в печать. Пример символа:


2. Как обойти в коде все строки таблицы DataSource.


Приведенный ниже код успешно с этим справляется:

// DataSource таблицы UserFilter
var filterTable = (TableDataSource)Report.GetDataSource("UserFilter");
foreach (DataRow row in filterTable.Table.Rows)
{
    // FieldKey - столбец таблицы
    if (row["FieldKey"].ToString() == "SomeCellValueOfFieldKey")
    {
        // ...
    }
}

Внимание! Хочу заметить, что оболочка FastReport крайне неудобна для программирования на том же C#, поскольку слабо поддерживается IntelliSence и не всегда можно увидеть корректный перечень свойств. Поэтому я в прикладном коде своего проекта, который формирует отчёт, создаю какой то тестовый метод, в теле которого экспериментирую со свойствами объекта Report. Для справки Report, в FastReport, это статическая ссылка на объект созданный вами через new Report().

3. Как использовать Linq или подключить сборки в отчёт FastReport.


Если вы добавите в начале кода отчёта using System.Linq; то отчёт не сможет сформироваться, поскольку данное пространство имён будет не найдено. Это происходит потому что не добавлена ссылка на сборку где реализован Linq, в студии используется пункт меню проекта "Add Reference", в FastReport же следует зайти в настройки отчёта и добавить имя файла. Поскольку реализация Linq находится в файле System.Core.dll (Я это узнал перейдя к определению любого метода, допустим Any() и сверху файла написано имя файла), его и следует нам добавить в ссылки FastReport:



4. Объединение ячеек таблицы.


В ситуации, когда планируется создать не просто сетку таблицы, а объединенные ячейки по какому то признаку, можно использовать свойство ячейки Duplicates со значение Merge. Что это означает? Каждый раз, когда в очередной строке значение ячейки совпадает со значений ячейки в предыдущей строке, FastReport, вместо печати дубля, объединяет ячейку в одну.


5. Не работающий междустрочный интервал.


На примере объекта TextObject мне необходимо было увеличить междустрочный интервал. Казалось бы, для этого должен был бы служить параметр LineHeight, поскольку изменяя его значения в дизайнере я видел увеличение этого интервала. Но при экспорте в Word было видно, что LineHeight параметр не работает (повторюсь, что версия FastReport у меня 2018.3.20). Решением стало задание 3 параметров:
  1. ParagraphFormat.LineSpacing - отвечающий за высоту.
  2. ParagraphFormat.LineSpacingType - необходимо обязательно выставить в значение AtLeast.
  3. TextRenderType - необходимо выставить в значение HtmlParagraph.
Только лишь в этой комбинации эффект междустрочного интервала начал работать.



6. Примеры использования условного оператора IIF(,,) в дизайнере отчёта.


Приведу формат и парочку примеров, по которым сразу станет ясно использование оператора:

Формат:
[IIf(Condition, True, False)] 

Пример 1. Если значение CompleteDate не равен null, тогда выводим текст год, иначе пусто:
[IIf([ActTechnicalEvent.CompleteDate] != null, "год",null)]

Пример 2. Если первая буква имени А, тогда к имени добавляем префикс "*".
[IIf(Length([spt_values.name]) > 1 && UpperCase(Substring([spt_values.name], 0, 1)) == "A", "*" + [spt_values.name], [spt_values.name])]

Внимание! Если у вас ошибка "Error CS0103: The name 'IIF' does not exist in the current context" это из-за того, что название является регистрозависимым, и само имя написано неверно. Следует использовать IIf имя для условного оператора.

7. Сортировка и группировка данных в таблице отчёта.


Самая простая операция при формировании данных таблицы. Для обоих настроек существует 2 вкладки в настройках DataBand (Sort и Filter), отвечающие за эти действия. Для их настройки необходимо вызвать контекстное меню на DataBand (оранжевая область) и выбрать пункт меню Edit (Редактирование).


В примере выше можно видеть:
  1. Настройку сортировки строк таблицы по полю name в алфавитном порядке.
  2. Фильтрация данных строк в таблице. Цель убрать все пустые строки (у которых поле name null, либо пустая строка).
Внимание! Результат выражения во вкладке фильтрация должен быть Boolean, то есть в этом поле задаётся условие, как если бы было написано IF ( ВашеУсловиеВФильтре ) ВыводимСтроку ELSE Невыводим.

8. При экспорте в Excel или в Html большой таблицы, ячейки начинают биться либо появляется разделительная линия.


По началу данная природа поведения при экспорте мне была не понятна, с какой то фиксированной периодичностью ячейки бились невидимой линией. Но вскоре я понял, что данным разделителем является высота листа A4 при печати. А для того, что бы FastReport не добавлял разделительных линий необходимо поставить UnlimitedHeight в True для страницы отчёта:

10 комментариев:

  1. Добрый день.

    Очень полезная информация.

    Случайно не знаете, как через iif сделать вывод разного текста в зависимости от True или False значения параметра?

    ОтветитьУдалить
    Ответы
    1. Добрый день.

      Выше пример есть такой

      [IIf([ActTechnicalEvent.CompleteDate] != null, "год",null)]

      Если свойство CompleteDate != null будет выведен текст "год" иначе пусто.

      Удалить
    2. Этот комментарий был удален автором.

      Удалить
  2. корректный вариант при True/False

    [IIf([function]="False", "False","True")

    ОтветитьУдалить
  3. Можно найти пример или инструкции для конекта к базе PostgreSQL?

    ОтветитьУдалить
  4. Здравствуйте,можете подсказать как исключить значения типа время(00:00:10)по условиям < или >, примеру 12 сек? Если я пробую через фильтр(или же IIf) то выходит ошибка CS0019 о невозможности применения к операндам типа "string" и "int". По описанию ошибки понятно что нельзя сделать, но как то же можно управляться с временем(нужно именно выставлять разные ограничения под каждое оборудование) ,чтоб отсечь ложные данные, при кратковременных сбоях.

    ОтветитьУдалить
    Ответы
    1. Доброго дня, к сожалению я на новой работе не имею дело с Fastreport, поэтому подсказать не смогу

      Удалить
    2. Понятно,спасибо за оперативный ответ!

      Удалить
  5. Здравствуйте, а возможно ли сменить единицы измерения в скрипте C# на мм?
    В отчёте (мм, см, дюймы, сотые дюймов), а в скрипте похоже на пиксели.

    ОтветитьУдалить