уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Как вы уже, наверное, в курсе, до 28 сентября при покупке RAD Studio XE3 Вы получаете бесплатный бонусный пакет, содержащий конвертер Mida, премиум-стили для FireMonkey и виновника сегодняшнего поста — компонент (а точнее набор из нескольких компонентов) TMS Grid.

Вчера мне посчастливилось посмотреть, что из себя представляет TMS Grid For Firemonkey и, несмотря на то, что в бонусном пакете отсутствуют исходники, разобраться с работой компонента не составило особого труда, а сам компонент показался мне вполне заслуживающим внимания.

Сравнивать стандартный TGrid с TMSFMXGrid было бы, по-меньшей мере, не совсем корректно, т.к. эти компоненты различаются как небо и земля (хотя оба вроде бы являются сетками), но все-таки в некоторых местах статью я буду ссылаться на возможности TGrid для более полного описания того, что даст нам использование компонента от TMS Software.

Итак, что же входит в состав бонусного пакета от TMS Software. После выполнения setup’а с компонентами на палитре Delphi XE3 появилась новая вкладка «TMS FMX UI», содержащая следующие компоненты:

  1. TMSFMXGrid
  2. TMSFMXGridRTFIO
  3. TMSFMXBitmapContainer
  4. TMSFMXGridExcelIO
  5. TMSFMXGridPrintPreviewDialog

Соответственно, первый компонент — это сама сетка, а остальные — не визуальные вспомогательные компоненты для расширения возможностей сетки, например, для импорта/экспорта таблиц Excel, создания диалога предварительного просмотра перед печатью таблицы и т.д. Рассмотрим как работают эти компоненты.

Компонент  TMSFMXGrid (Сетка)

Если говорить очень кратка, то компонент TMSFMXGrid (без дополнительных компонентов, которые будут рассмотрены ниже) позволяет:

  1. Вставлять в произвольные ячейки сетки любые компоненты будь то простой CheckBox или TreeView
  2. Группировать записи в таблице
  3. Фильтровать записи
  4. Выделять/Объединять диапазоны ячеек (как в Excel)
  5. Использовать для произвольных ячеек свои шрифты
  6. Выводить текст в ячейке под любым углом
  7. Оставлять комментарии для ячеек (как в Excel)
  8. и многое другое, в т.ч. и подсвечивать ссылки в ячейках
В общем TMSFMSGrid — это такой большой универсальный компонент с огромными возможностями. Посмотрим как использовать эти и другие возможности компонента на примере.

Создадим проект FireMonkey HD Application и бросим на форму компонент TMSFMXGrid. При настройках по умолчанию наша сетка будет выглядеть точно также как и обычный TStringGrid из VCL:

TMSFMXGrid

TMSFMXGrid

Как видно на рисунке — для сетки можно задать фиксированные столбцы и строки (через свойства FixedColumns и FixedRows), что является, кстати, выгодным отличием от стандартного грида. Теперь посмотрим, как можно видоизменить и дополнить нашу сетку. Для сложной настройки сетки используется группа свойств Options:

TMS Grid - группа свойств Options

TMS Grid — группа свойств Options

 Для начала добавим в нашу сетку «шапку» и «подвал», для этого раскрываем свойства Options.Header и Options.Footer и устанавливаем Visible в значение True. В итоге наша сетка примет следующий вид:

TMS Grid с Header и Footer

Header и Footer — это простые примитивы типа TRectangle, которые можно использовать для того, чтобы, например, разместить на сетке дополнительные компоненты для фильтрации данных, подписи и т.д.

 Также мы можем задать альтернативный цвет строк таблицы, используя вкладку свойств Bands. В отличие от TGrid (у которой есть аналогичное свойство AlternatingRowBackground) здесь мы можем дополнительно указать количество идущих подряд строк с нормальным цветом и альтернативным. Например, на рисунке ниже показана таблица с настроенными свойствами вкладки Bands:

TMS Grid - настройка альтернативных цветов для строк

TMS Grid — настройка альтернативных цветов для строк

Для столбцов сетки можно включить фильтрацию данных. Для этого используется вкладка свойств Options.Filtering в которой настраиваются необходимые свойства для фильтра. На рисунке ниже представлен внешний вид TMSFMXGrid с включенной фильтрацией данных в столбцах:

Аналогичным образом — буквально в пару кликов мышкой настраиваются и другие свойства TMSFMXGrid: внешний вид и операции над URL, которые вводятся в таблицу, операции для мыши (изменение размеров строк и столбцов, скроллинг и т.д.), настройки экспорта в HTML и т.д.

Теперь посмотрим как можно добавлять в ячейки сетки произвольные компоненты. Пусть, например, в нашей таблице на рисунке выше каждая вторая ячейка в фиксированном столбце будет содержать CheckBox. Для этого можно воспользоваться событием OnGetCellClass, например так:

procedure TForm1.TMSFMXGrid1GetCellClass(Sender: TObject; ACol, ARow: Integer;
  var CellClassType: TFmxObjectClass);
begin
  if (ACol=0) and((ARow mod 2) <> 0) then
    CellClassType:=TTMSFMXCheckGridCell;
end;

Или воспользоваться методом TMSFMSGrid, в любом месте программы, например, так:

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
begin
for I := 0 to TMSFMXGrid1.RowCount-1 do
  if (i mod 2) <> 0 then
     TMSFMXGrid1.AddCheckBox(0,i);
end;

В обоих случаях таблица будет выглядеть одинаково:

Теперь, если мы хотим программно «чекнуть» наш CheckBox достаточно выполнить вот такой код в обработчике OnGetCellProperties:

procedure TForm1.TMSFMXGrid1GetCellProperties(Sender: TObject; ACol,
  ARow: Integer; Cell: TFmxObject);
begin
   if Cell is TTMSFMXCheckGridCell then
     TTMSFMXCheckGridCell(Cell).CheckBox.IsChecked:=True;
end;

Чтобы отследить изменение состояния CheckBox’а пользователем можно использовать событие OnCellCheckBoxClick:

procedure TForm1.TMSFMXGrid1CellCheckBoxClick(Sender: TObject; ACol,
  ARow: Integer; Cell: TFmxObject);
begin
  if TTMSFMXCheckGridCell(Cell).CheckBox.IsChecked then
    ShowMessage('Checked!');
end;

Событие OnCellCheckBoxClick будет вызываться только для ячеек, содержащих CheckBox’ы.

Если нам необходимо вставить в ячейку какой-либо редактор — SpinEdit, DateTmePicker и т.д. мы также можем воспользоваться событием OnGetCellEditorType в котором указать вид редактора для ячейки, например так:

procedure TForm1.TMSFMXGrid1GetCellEditorType(Sender: TObject; ACol,
  ARow: Integer; var CellEditorType: TTMSFMXGridEditorType);
begin
  case ACol of
    1:CellEditorType:=etColorPicker;
    2:CellEditorType:=etDatePicker;
    3:CellEditorType:=etHexEdit;
  end;
end;

В результате столбцы четки будут содержать следующие редакторы:

TTMSFMXGridEditorType может принимать следующие значения:

Значение Класс ячейки Внешний вид редактора
et*Edit  TTMSFMXEdit  
 et*EditBtn  TTMSFMXEditBtn  
 etComboBox  TComboBox  
 etComboEdit  TComboEdit  
 etSpinBox  TSpinBox  
 etDatePicker  TCalendarBox  
 etDateEdit  TCalendarEdit  
 etColorPicker  TComboColorBox  
 etColorComboBox  TColorComboBox  
 etTrackBar  TTrackBar  
 etArcDial  TArcDial  
 etCustom  В зависимости от указанного класса в обработчике события OnGetCellEditorCustomClassType

Теперь посмотрим как можно группировать записи в ячейках TMSFMXGrid. Вначале наполним нашу таблицу какими-нибудь данными, например так (данные, естественно, взяты наобум):

TMS Grid - данные для группировки

TMS Grid — данные для группировки

 

Теперь нам необходимо сгруппировать все данные в таблице по столбцу «Сайт» и вычислить, скажем, средний рейтинг. С TMSFMXGrid сделать это просто:

  TMSFMXGrid1.SortData(1,sdAscending);//указываем столбец для группировки и направление сортировки групп
  TMSFMXGrid1.Options.Grouping.MergeHeader := true;//заголовок группы будет содержать объединенные ячейки
  TMSFMXGrid1.Options.Grouping.Summary := true;//показывать под группой строку для вывода обобщенных данных
  TMSFMXGrid1.Group(1);//группировать данные столбцу с индексом 1
  TMSFMXGrid1.GroupAvg(3); //вычислить среднее значение рейтинга (столбец с индексом 3)

После выполнения этого кода наша сетка будет выглядеть так:

TMS Grid - сгруппированные даннные

TMS Grid — сгруппированные даннные

Чтобы разгрупировать данные и привести таблицу в первоначальный вид достаточно вызвать метод:

 

  TMSFMXGrid1.UnGroup;

И, раз уж при группировке данных у нас объединялись ячейки таблицы, то заодно посмотрим как ячейки объединяются вручную. Объединить диапазон ячеек можно так:

TMSFMXGrid1.MergeCells(1, 2, 3, 3);

Здесь первые два параметра — это индекс колонки и столбца первой ячейки для объединения, третий и четвертый параметр — количество строк и столбцов для объединения. Выполнение приведенного выше кода приведет к тому, что таблица примет следующий вид:

 

TMS Grid - объединенные ячейки

TMS Grid — объединенные ячейки

Теперь, чтобы снова разделить ячейки, достаточно вызвать противоположный Merge метод:

  TMSFMXGrid1.SplitCell(1,2);

В Split, соответственно, указывается только первая ячейка объединенного диапазона ячеек.

Что касается диапазонов ячеек в TMSFMXGrid, то диапазон можно получить, выделить/объединить так:

var CR: TCellRange;
begin
  CR:=TMSFMXGrid1.CellRange(2,3,3,2);//задали диапазон
  TMSFMXGrid1.SelectCells(CR);//выделили диапазон
  {ИЛИ}
  TMSFMXGrid1.MergeSelection(CR); //объединили диапазон
end;
Для того, чтобы в сетке можно было выделить диапазон, необходимо, чтобы свойство SelectionMode было установлено как smCellRange

Что касается работы с отдельной ячейкой сетки, то, как я говорил выше, для ячейки мы можем установить свои шрифты, угол наклона и т.д. Все эти моменты реализованы в виде удобных свойств TMSFMXGrid:

Использование для произвольных ячеек своих шрифтов

  TMSFMXGrid1.FontNames[1,1]:='Cooper';
  TMSFMXGrid1.FontSizes[1,1]:=16;
  TMSFMXGrid1.FontColors[1,1]:=TAlphaColorRec.Blue;
  TMSFMXGrid1.FontStyles[1,1]:=[TFontStyle.fsItalic];
TMS Grid - произвольный шрифт для ячейки

TMS Grid — произвольный шрифт для ячейки

Вывод текста в ячейке под произвольным углом

 TMSFMXGrid1.Angles[2,2]:=45;
TMS Grid - вывод текста под произвольным углом

TMS Grid — вывод текста под произвольным углом

Добавление комментария к ячейке

  TMSFMXGrid1.Comments[3,3]:='111111';
  TMSFMXGrid1.CommentColors[3,3]:=TAlphaColorRec.Red;
TMS Grid - комментарий к ячейке

TMS Grid — комментарий к ячейке

Кроме рассмотренных выше свойств, методов и событий TMSFMSGrid, этот компонент имеет ещё достаточно много прочих полезных «фишек», например, расчёт сумм по столбцам, рисование на канве ячейки, автоматическое выравнивание ширины столбцов, высот строк и т.д.

Компонент TMSFMXGridRTFIO

Этот компонент предназначен для экспорта таблицы в rtf-документ. В TMSFMXGridRTFIO можно указать начальную строку и столбец для экспорта, а также следующие опции экспорта:

Пример экспорта таблицы в файл:

{настраиваем опции}
TMSFMXGridRTFIO1.Options.ExportOverwrite := omAlways;
TMSFMXGridRTFIO1.Options.ExportImages := true;
TMSFMXGridRTFIO1.Options.ExportBackground := true;
{экспортируем и открываем полученный файл}
TMSFMXGridRTFIO1.ExportRTF('gridexport.rtf');
XOpenFile('open', 'gridexport.rtf', '', '');

Компонент TMSFMXBitmapContainer

Предназначен для хранения графических файлов и их использования в таблице.  Все изображения хранятся в коллекции Items компонента. Вот так можно вставить изображение из коллекции в произвольную ячейку таблицы:

  TMSFMXGrid1.AddBitmap(1,7,'Item1');
  TMSFMXGrid1.AddBitmap(1,8,'Item2');
  TMSFMXGrid1.AddBitmap(1,9,'Item2');

Где первые два параметра — индексы столбца и строки, а третий — имя элемента коллекции (изображения) TMSFMXBitmapContainer для вставки в ячейку.

Компонент TMSFMXGridExcelIO

Компонент для работы с таблицами Excel (*.xls). С помощью этого компонента можно очень легко импортировать таблицу из Excel или экспортировать свою таблицу в файл. Например, я написал такой простой код:

if OpenDialog1.Execute then
  TMSFMXGridExcelIO1.XLSImport(OpenDialog1.FileName);

Выбрал таблицу со сложным форматированием (прайс-лист) и получил такой вид таблицы в своей программе:

Перенеслись даже изображения, находящиеся в ячейках листа Excel. У TMSFMXGridExcelIO можно настроить следующие свойства:

Компонент TMSFMXGridPrintPreviewDialog

С помощью этого диалога можно сделать предпросмотр таблицы перед печатью. Вызов этого диалога осуществляется точно также как и любого другого:

TMSFMXGridPrintPreviewDialog1.Execute;

С помощью этого диалога можно, например, разбить таблицы по страницам или указать страницы для печати.

Быстродействие

Вполне возможно, что у кого-то после прочтения этого поста возникнет закономерный вопрос — «Как быстро работает этот компонент по сравнению с родными гридами FMX?». Скажу как есть — я сравнивал этот грид только с TStringGrid из FMX и, естественно, TStringGrid при заполнении 6000 ячеек оказался шустрее. Однако и сам TMSFMXGrid выполнил эту же задачу вполне приемлемо — по-крайней мере, по моим субъективным ощущениям скорость работы компонента от TMS Software достаточно высокая.

Что касается итогового мнения по работе с TMS Grid, то лично мне этот компонент очень понравился по своим возможностям. Конечно, я сейчас не рассматривал в статье работу с базами данных (надеюсь, скоро мы узнаем об этом от Александра Божко), но в целом возможности компонента и простота их использования оставили самое положительное впечатление от использования TMS Grid.

Дополнительные материалы

  1. TMS Grid for FireMonkey Whitepaper and Special Offers
  2. Документация по TMSFMXGrid для разработчиков
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
27 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Алексей
Алексей
25/09/2012 22:34

Вопрос только один: сколько такая радость будет стоить сама по себе? И стоит ли оно того?

G-Sirr
G-Sirr
25/09/2012 22:40

Спасибо за обзор!
А если больше? Скажем, не 6 тыс. записей, а 400? Работают ли хоткеи «из коробки»? Например, Ctrl+A, Ctrl+PageDown и т.п. А как выглядит в MacOS? Ну, и по юзабилити — MacOS все же другой, была ли возможность потестировать?

max
max
26/09/2012 01:35

Целый ексель под руками.

zdm
zdm
26/09/2012 12:44

Спасибо Влад, как всегда от тебя исчерпывающая статья.
Позволю себе личное мнение… FireMonkey и даже с TMS пытаются только приблизиться к тому, что уже давно есть… до уровня DevExpres доживем? 600 тыс. записей — детский лепет, есть реально рабатающая СУБД на Delphi, для коннекта — UniDac, более 1 500 000 записей не убивают ни чего………

alexey38
alexey38
26/09/2012 15:06

2zdm: 600 тыс. записей — детский лепет, есть реально рабатающая СУБД на Delphi, для коннекта — UniDac, более 1 500 000 записей не убивают ни чего. Как я понял, представленный компонент осуществляет обработку без СУБД. И в такой постановке функционал действительно очень интересен. По факту очень много реальных задач, для которых использование СУБД для визуализации — это лишнее. Например, когда нужно визуализировать результаты матобработки или данные вытащены с веба. А родных средств для визуализации таких данных очень мало. Когда есть СУБД и данные лежат в БД, то обработка идет в СУБД, и визуализируется только выборка. Естественно для любой современной СУБД… Подробнее »

Slike
Slike
26/09/2012 18:23

Поправьте меня если я ошибаюсь. У этого грида поддерживается только одна платформа 32-bit Windows?
Как-то не очень кроссплатформенно получается…

Slike
Slike
26/09/2012 18:36

На оф.сайте да, но по факту, я скачал триальную верcию с http://www.tmssoftware.com/site/tmsfmxpack.asp и у компонентов TMSFMXGrid, TMSFMXEditBtn, TMSFMXEdit Supported Platforms: 32-bit Windows.

Slike
Slike
26/09/2012 20:43

Проверишь отпишись. Думаю интересно будет не только мне.

IL
IL
27/09/2012 11:01

Влад, посмотрите еще MonkeyStyler https://twitter.com/TheMonkeyStyler/status/251030616215285760

zdm
zdm
27/09/2012 16:33

да, что-то я вечно в сторону СУБД :) извиняюсь….

IL
IL
27/09/2012 22:04

Vlad, автор написал в твиттер, что разошлет всем MVP, и просил написать ему, если кто-то не получил. Буду рад вашему обзору обезьяно-стилизатора ;)

Георгий
Георгий
08/10/2012 22:22

Отличный обзор! Спасибо.

Alexander
Alexander
19/10/2012 01:03

Скачал триал и демо…
по гриду есть еще баги, самый неприличный в примере, где в ячейке другая сетка, не удалаяется при скрытии скролбар.
складывается впечатление, что в торопях под тройку переделывали…

Не много в сторону, но всеж… у компаса не нашел свойства отвечающего за поворот стрелки, пришлось шарить стиль — искать там рут стрелки и указывать угол поворота :)
Общее впечатление от компонент положительное, баги не страшны, да и оптимизация под большое количество записей не за горами.
Автору большое Спасибо за статью!!!

Денис Гладько
09/11/2012 04:13

Извините не поскажите что это за ошибка и как её решить, не совсем понял как подсоединить этот TMSFMXGridExcelIO.
Создаю Grid, кидаю TMSFMXGridExcelIO, подсоеденяю его, кидаю OpenDialog, а что дальше ?
выбивает при запуске:
[dcc32 Error] E1026 File not found: ‘FMX.EmptySheet.res’

помогите плиз((((

Alex
Alex
09/11/2012 13:40

то Денис Гладько:
Проверьте пути к файлам компонент в «Tools->Options…»
а также где реально файл находится.

IL
IL
10/11/2012 03:17

Vlad и остальные MVP, DevJet объявила, что дарит одну лицензию на все её продукты (в настоящий момент Documentation Insight Enterprise) лично вам навсегда!
https://forums.embarcadero.com/message.jspa?messageID=484095
Кстати, а не добавить ли в темы опросов: каким решением для документирования кода пользуются люди?

Nick
Nick
27/11/2012 15:28

Добрый день

Насколько я понял из семинара Embarcadero, в FM робота с данными базы ведется через LiveBinding. Т.е. этот грид просто свяжется с компонентом базы и будут отображать данные (например TCLientDataSet).

Или я неправ?

Artem
Artem
18/02/2013 13:32

Попробуйте перевернуть текст в ячейке на 270 градусов к примеру отформатировать его по вертикали, по горизонтали, а потом экспортировать в эксель. Получим два глюка: 1 — не выравнивается если текст под углом; 2 — при экспорте возникает ошибка именно из-за текста под углом.

Вадим
Вадим
02/10/2013 19:20

Подскажите как отображать все записи таблицы, делаю всё как указано в интернете, но у меня отображается только 200 записей в гриде, хотя в таблице их намного больше.

Анатолий
Анатолий
20/05/2015 21:39

Combobox в гриде. Если прокрутить скрол или раскрыть и закрыть node список в combobox комкается, выдается ошибка несовместимая с дальнейшей жизнью приложения…