Cross-tab ручная настройка высоты строки

HunterNSHunterNS Таганрог
отредактировано April 2011 Раздел: FastReport 4.0
Доброго времени суток всем.

У меня возникла проблема при использовании компонента DB Cross-tab.

FastReport V 4.7.21

Настраиваю кросс-таблицу следующим образом: Autosize = false. Выставляю нужные размеры колонок. Но не могу выставить нужную высоту строк.

Суть проблемы в следующем: Так как стоит Autosize = false, то высота строк не растягивается до максимальной высоты.
Если играться со свойствами StretchMode у RowHeader и у Cell нужный эффект не достигается (см. картинки 1, 2, 3)

В службе поддержки подсказали использовать Autosize = true или обрабатывать событие OnCalcHeight.
Когда я делаю Autosize = true, высота строк, в которых есть данные, становиться слишком большой, хотя пустого места сверху и снизу от записей достаточно (см. рис. 4).

Пробовал использовать Autosize = False и обрабатывать событие OnCalcHeight. В этом событии можно указать Height строки вручную. Если бы знать максимальную высоту строки, которая будет после прорисовки ячеек этой строки, то можно было бы это значение присвоить параметру Height. Но как узнать значение Height строки после прорисовки. Служба поддержки посоветовала использовать двойной проход (DoublePass) отчета.
Я вижу решение таким: в первом проходе я заполняю переменную-массив, в котором находятся значения высоты каждой строки (после растягивания!!!) кросс-таблицы. Затем во втором проходе выставляю полученные высоты строк соответствующим строкам.
Это хорошая мысль, но всё равно у меня не получается получить значение максимальной высоты в строке.

Не подскажите, какое событие мне нужно отрабатывать, чтобы узнать конечную высоту определенной строки в кросс-таблице?

На рисунке 5 изображено, как должна выглядеть таблица (делаю это в обработчике события DBCross1OnCalcHeight. if RowIndex = 0 then Height := 82; if RowIndex = 3 then Height := 40;)

Рисунок 1: Без растягивания
Рисунок 2: Растягивание по высоте
Рисунок 3: Растягивание до максимальной высоты
Рисунок 4: Авто размер
Рисунок 5: Так должно быть

Комментарии

  • gpigpi
    отредактировано 18:24
    написал:
    В службе поддержки подсказали использовать Autosize = true или обрабатывать событие OnCalcHeight.
    Когда я делаю Autosize = true, высота строк, в которых есть данные, становиться слишком большой, хотя пустого места сверху и снизу от записей достаточно (см. рис. 4).
    Приложите простой тестовый проект, демонстрирующий данную проблему. AutoSize должен работать корректно
  • HunterNSHunterNS Таганрог
    отредактировано 18:24
    gpi написал: »
    Приложите простой тестовый проект, демонстрирующий данную проблему. AutoSize должен работать корректно
    Сделал тестовый проект, ошибка повторяется. Возможно это из-за того, что я обрабатываю событие OnCalcWidth. Если его не обрабатывать, то высота строки становится корректной, но ширина колонок становится неодинаковой. (для меня это критично, так как над кросс-таблицей есть еще МастерДата и Чарт, которые подогнаны по "временной шкале".
  • gpigpi
    отредактировано 18:24
    Проблема во включённой опции JoinEqualCells, вернее в том, что кросс при построении не учитывает объединение ячеек
  • HunterNSHunterNS Таганрог
    отредактировано April 2011
    Я нашёл решение.

    Autosize = false;
    Cross1Cell0.StretchMode = smMaxHeight;
    Report.EngineOption.DoublePass = true;
    var
      MaxHeights: TStringList;
    
    procedure Cross1Cell0OnAfterPrint(Sender: TfrxComponent);
    begin
      if (not engine.FinalPass) AND (TfrxMemoView(Sender).Left < 163) then 
        MaxHeights.Add(FloatToStr(TfrxMemoView(Sender).Height));
    end;
    
    procedure frxReport1OnStartReport(Sender: TfrxComponent);
    begin
      MaxHeights := TStringList.Create;                          
    end;
    
    procedure frxReport1OnStopReport(Sender: TfrxComponent);
    begin
      MaxHeights.Free;              
    end;
    
    procedure Cross1OnCalcHeight(RowIndex: Integer; RowValues: Variant; var Height: Extended);
    begin
      if engine.FinalPass then Height := StrToFloat(MaxHeights[RowIndex]);
    end;
    

    Так как высота ячеек кросс-таблицы устанавливается правильно при отключенном Авторазмере, то я просто при первом проходе отчета запоминаю высоты первой ячейки каждой строки (зная их левую границу, в моём случае 162). А на втором проходе применяю эти высоты в обработчике события OnCalcHeight.

    qpi, спасибо за помощь.
  • HunterNSHunterNS Таганрог
    отредактировано April 2011
    Совет для тех, кто будет использовать объединение ячеек (JoinEqualCells = true): Отсортируйте свои данные так, чтобы непустые строки лежали всегда перед пустыми. В моём случае я сортирую DataSet так (order by GROUP, TIME, NAME DESC).

    В случае если не сортировать по полю NAME не факт, что ячейки объединятся правильно.
    Если сортировать NAME ASC (и при условии, что есть пустые значения для этой ячейки), то перед значением всегда будет лишняя пустая строка.

    1. Осутствие сортировки (ячейки не объединятся!!! Так как в самой первой ячейки будет пустая строчка над строчкой "Текст"):
    AddValue(['Ардуан'], ['08:05'], ['']);   
    AddValue(['Ардуан'], ['08:05'], ['Текст']);        
    AddValue(['Ардуан'], ['08:10'], ['Текст']);      
    AddValue(['Ардуан'], ['08:10'], ['']);            
    AddValue(['Ардуан'], ['08:15'], ['']);     
    AddValue(['Ардуан'], ['08:20'], ['Ещё текст']);
    AddValue(['Ардуан'], ['08:25'], ['Ещё текст']);        
    AddValue(['Ардуан'], ['08:30'], ['']);
    

    2. Сортировка 2-ой и 3-ей колонки по возрастанию (Выведется дополнительная строчка над надписью "Текст"):
    AddValue(['Ардуан'], ['08:05'], ['']);
    AddValue(['Ардуан'], ['08:05'], ['Текст']);
    AddValue(['Ардуан'], ['08:10'], ['']);            
    AddValue(['Ардуан'], ['08:10'], ['Текст']);      
    AddValue(['Ардуан'], ['08:15'], ['']);     
    AddValue(['Ардуан'], ['08:20'], ['Ещё текст']);
    AddValue(['Ардуан'], ['08:25'], ['Ещё Текст']);        
    AddValue(['Ардуан'], ['08:30'], ['']);
    

    Правильный вариант
    3. Сортировка 2-ой колонки по возрастанию, 3-ей по убыванию (Всё выведется корректно, без лишних строчек):
    AddValue(['Ардуан'], ['08:05'], ['Текст']);        
    AddValue(['Ардуан'], ['08:05'], ['']);   
    AddValue(['Ардуан'], ['08:10'], ['Текст']);      
    AddValue(['Ардуан'], ['08:10'], ['']);            
    AddValue(['Ардуан'], ['08:15'], ['']);     
    AddValue(['Ардуан'], ['08:20'], ['Ещё текст']);
    AddValue(['Ардуан'], ['08:25'], ['Ещё текст']);        
    AddValue(['Ардуан'], ['08:30'], ['']);
    

    Опытным путём стало известно, что при выводе данных в ячейку, над ними выполняется операция rtrim (удаление всех пробелов справа).
  • HunterNSHunterNS Таганрог
    отредактировано 18:24
    Возможно ли при включенной опции "Объединять одинаковые ячейки" (JoinEqualCells = true) объединять только непустые ячейки?
  • HunterNSHunterNS Таганрог
    отредактировано April 2011
    Я наконец-то добил этот отчёт.
    написал:
    Возможно ли при включенной опции "Объединять одинаковые ячейки" (JoinEqualCells = true) объединять только непустые ячейки?
    Сам компонент наверное не может это сделать, поэтому решил править запрос.

    Сначала была мысль в запросе генерировать разное количество пробелов в те ячейки, в которых ничего не нужно выводить. Но так как Cross-tab производит rtrim над содержимым ячеек до их вывода (см. мой пост выше), то в ячейках снова получалось по одному пробелу (или вообще ничего) и Cross-tab их объединял.

    Один мой коллега подсказал "волшебный" символ -"Неразрывный пробел" (ALT + 255 на Num панели). Вот он-то меня и спас. Для этого символа RTRIM не срабатывает, поэтому в каждых соседних "пустых" ячейках получаются разные строки. :)

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

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