Управление кросс-таблицей из скрипта |
Если визуальных средств настройки таблицы недостаточно, можно использовать скрипт для тонкой настройки внешнего вида таблицы. Объект "Кросс-таблица" имеет следующие события:
В событиях удобно использовать следующие методы объекта "Кросс-таблица":
Рассмотрим на примере, каким образом можно выделить третью колонку цветом фона (в нашем примере – это данные за ноябрь 1999 года). Для этого выделим кросс-таблицу и создадим обработчик события OnPrintCell:
Pascal script:
procedure Cross1OnPrintCell(Memo: TfrxMemoView; RowIndex, ColumnIndex, CellIndex: Integer; RowValues, ColumnValues, Value: Variant); begin if ColumnIndex = 2 then Memo.Color := clRed; end;
C++ Script:
void Cross1OnPrintCell( TfrxMemoView Memo, int RowIndex, int ColumnIndex, int CellIndex, Variant RowValues, Variant ColumnValues, Variant Value) { if (ColumnIndex == 2) { Memo.Color = clRed; } }
Мы увидим следующий результат:
Чтобы выделить цветом заголовок колонки, создадим обработчик события OnPrintColumnHeader:
Pascal script:
procedure Cross1OnPrintColumnHeader(Memo: TfrxMemoView; HeaderIndexes, HeaderValues, Value: Variant); begin if (VarToStr(HeaderValues[0]) = '1999') and (VarToStr(HeaderValues[1]) = '11') then Memo.Color := clRed; end;
C++ Script:
void Cross1OnPrintColumnHeader( TfrxMemoView Memo, Variant HeaderIndexes, Variant HeaderValues, Variant Value) { if ((VarToStr(HeaderValues[0]) == "1999") && (VarToStr(HeaderValues[1]) == "11")) { Memo.Color = clRed; } }
Результат:
Поясним работу скриптов. Обработчик события OnPrintCell вызывается перед печатью ячейки, которая содержится в теле таблицы (при печати ячеек из заголовка таблицы вызывается обработчик OnPrintColumnHeader или OnPrintRowHeader). При этом в обработчик OnPrintCell передается ссылка на объект "Текст", который представляет собой ячейку таблицы (параметр Memo), и "адрес" ячейки в двух вариантах: номер строки, колонки и ячейки (последнее актуально, если в вашей таблице многоуровневые ячейки) в параметрах RowIndex, ColumnIndex, CellIndex соответственно. Второй вариант "адреса" – это параметры RowValues и ColumnValues. Параметр Value – это содержимое ячейки.
Для определения "адреса" вы можете использовать как первый вариант (RowIndex, ColumnIndex), так и второй (RowValues, ColumnValues) – что удобнее в конкретном случае. В нашем случае нужно было выделить третью колонку – поэтому удобнее анализировать первый вариант. Т.к. нумерация колонок и строк начинается с 0, проверка ColumnIndex = 2 позволила нам определить 3-ю колонку. Можно было поступить иначе, анализируя нужную колонку по ее данным (нам нужен 11 месяц 1999 года):
Pascal script:
procedure Cross1OnPrintCell(Memo: TfrxMemoView; RowIndex, ColumnIndex, CellIndex: Integer; RowValues, ColumnValues, Value: Variant); begin if (VarToStr(ColumnValues[0]) = '1999') and (VarToStr(ColumnValues[1]) = '11') then Memo.Color := clRed; end;
C++ Script:
void Cross1OnPrintCell( TfrxMemoView Memo, int RowIndex, int ColumnIndex, int CellIndex, Variant RowValues, Variant ColumnValues, Variant Value) { if ((VarToStr(ColumnValues[0]) == "1999") && (VarToStr(ColumnValues[1]) == "11")) { Memo.Color = clRed; } }
Значения, передаваемые в параметрах RowValues и ColumnValues – это массивы типа Variant с нулевой базой. Нулевой элемент – это значение верхнего уровня заголовка таблицы, первый – значение следующего уровня и т.д. В нашем случае ColumnValues[0] – это года, ColumnValues[1] – месяцы.
Зачем нужно преобразование VarToStr? Это гарантирует отсутствие ошибок приведения типов. FastReport при операциях с типом Variant пытается автоматически приводить строки в числовой формат, что в нашем случае вызовет ошибку при попытке приведения значения столбцов 'Total' и 'Grand Total'.
Обработчик события OnPrintColumnHeader вызывается при печати ячеек заголовка столбца. Набор параметров похож на параметры обработчика OnPrintCell, но здесь "адрес" ячейки (параметры HeaderIndexes, HeaderValues) передается иначе. Параметр HeaderValues возвращает те же значения, что и параметры ColumnValues, RowValues в обработчике OnPrintCell. Параметр HeaderIndexes также является массивом значений типа Variant и содержит адрес ячейки заголовка в другой форме: нулевой элемент – это порядковый номер верхнего уровня заголовка таблицы, первый – номер следующего уровня и т.д. Принцип нумерации ячеек заголовка станет понятен, если взглянуть на рисунок:
В нашем случае удобно анализировать значение HeaderValues, но можно написать и такой обработчик:
Pascal script:
procedure Cross1OnPrintColumnHeader(Memo: TfrxMemoView; HeaderIndexes, HeaderValues, Value: Variant); begin if (HeaderIndexes[0] = 0) and (HeaderIndexes[1] = 2) then Memo.Color := clRed; end;
C++ Script:
void Cross1OnPrintColumnHeader( TfrxMemoView Memo, Variant HeaderIndexes, Variant HeaderValues, Variant Value) { if ((HeaderIndexes[0] == 0) && (HeaderIndexes[1] == 2)) { Memo.Color = clRed; } }
С помощью обработчиков событий OnCalcWidth, OnCalcHeight можно управлять шириной и высотой строк и столбцов таблицы. Покажем на примере, как увеличить ширину колонки, соответствующей 11 месяцу 1999 года. Для этого создадим обработчик события OnCalcWidth:
Pascal script:
procedure Cross1OnCalcWidth(ColumnIndex: Integer; ColumnValues: Variant; var Width: Extended); begin if (VarToStr(ColumnValues[0]) = '1999') and (VarToStr(ColumnValues[1]) = '11') then Width := 100; end;
C++ Script:
void Cross1OnCalcWidth( int ColumnIndex, variant ColumnValues, Extended &Width) { if ((VarToStr(ColumnValues[0]) == "1999") && (VarToStr(ColumnValues[1]) = "11")) { Width = 100; } }
Результат:
Чтобы скрыть колонку, в нашем примере достаточно вернуть Width := 0. Заметим, что при этом суммы пересчитываться не будут – матрица к этому моменту уже заполнена значениями.
|