Dbgrid как в 1с

Обновлено: 07.07.2024

Елена Филиппова
дата публикации 12-04-2000 00:00

Представленный материал - это пример проекта, который реализует некоторые возможности по "раскраске" компонента TDBGrid.
Проект составлен исключительно из учебных целей для публикации на сервере "Королевство Дельфи" и самостоятельной ценности не несет.

Аналогичный пример выложен на сайте www.citforum.ru/programming/ , по содержанию предлагаемый проект не повторяет его и если сложить все эти публикации, то вопрос "как раскрасить Grid" можно считать исчерпанным.

  • Общие вопросы проекта.
  • Раскрашиваем строку.
  • Картинка и CheckBox в поле TDBGrid.
  • Подмена текста или "Какой длины рыба?".
  • Полосатое окно.
  • Как отметить несколько строк или "Не MultiSelect'ом единым. "
  • Разные мелочи

ОБЩИЕ ВОПРОСЫ ПРОЕКТА.

Создание примера "Разноцветный Grid" продиктовано тем, что вопрос о том, как "раскрасить" строки grid'а в зависимости от каких-либо условий, является очень популярным на Круглом столе. И судя по тому, что ответ "обрабатывайте событие OnDrawColumnCell" многих не вдохновляет, тема остается открытой.
Хочется внести ясность в этот, довольно занятный, вопрос. Может после этой статьи кому-то станет легче ориентироваться в такого рода проблемах.

  1. Полосатое окно
  2. Выделение цветом
  3. Комментировать длину

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

РАСКРАШИВАЕМ СТРОКУ.

Практически все действия, которые мы должны произвести, вмешиваются в процедуру прорисовки DBGrid'ом самого себя. Сделать это можно, обрабатывая событие TDBGrid.OnDrawColumnCell .
Возникает это событие тогда, когда ячейка TDBGrid нуждается в перерисовке. Подробнее об этом вы можете прочесть в help'е. Кстати, именно там, первой строкой написано, что обрабатывая это событие, вы можете обеспечить собственную прорисовку ячейки.

  • сам DBGrid (это не что иное, как Sender ),
  • текущая колонка - та, ячейка из которой сейчас перерисовывается ( DataCol и Column ),
  • прямоугольник Rect , который содержит эту ячейку
  • и ее состояние State ( выделена, в фокусе и т.д.)

Маленькое лирическое отступление:

По правилам хорошего тона программирования не следует обращаться к объекту по его имени, если он доступен по ссылке.
То есть: обращаться к канве грида как DBGrid1.Canvas внутри обработчика его же события некорректно. Это не ошибка, но это не совсем правильно.
Оценить разницу вы сможете в том случае, если у вас несколько Grid'ов с одним обработчиком или вам вдруг понадобилось переименовать его.
Обратитесь к канве как TDBGrid(Sender).Canvas и это всегда будет канва того компонента, который сейчас перерисовывается, как бы он не назывался.

Код работает, строки перерисовываются, разве можно добавить что-то еще?
Можно. Как говорилось в одной известной рекламе, есть способ лучше!

Предложенный код подходит только для тех случаев, если у вас нет специального форматирования выводимого текста в полях таблицы, если у вас нет выравнивания по правому краю или центру и т.д.
Потому что методом TextOut(Rect.Left+2,Rect.Top+2,Column.Field.Text); вы рисуете в определенных координатах текст, который содержится в текущей строке текущего поля и больше ничего. Все внутреннее форматирование будет потеряно. Для его восстановления вам будет необходимо проверять, какое установлено выравниваение и т.д., самим пересчитывать координаты вывода текста в прямоугольнике. В общем, это не сложная задача, но только зачем делать то, что прекрасно умеет делать сам DBGrid ?
Дадим ему Ценные Указания и пусть рисует, а уж это он умеет делать хорошо!
Поначалу даем DBGrid'у Ценные Указания, то есть назначаем его канве нужные свойства. Проверка IF gdSelected IN State необходима, чтобы отследить выделение позиции курсора, иначе выделенная сейчас строка будет перекрашена нами. Это не только неверно, но и некрасиво. Попробуйте убрать эту проверку и сами в этом убедитесь.
И, наконец, последний штрих - вызов метода TDBGrid.DefaultDrawColumnCell , который заставляет DBGrid отрисовать указанную ячейку со всеми настройками DBGrid'а , но только с нашими цветами на канве!
И все! И никаких проблем с выравниванием текста в строках, все что нужно рисовать, компонент рисует сам, а мы только "подсказали" ему цвет.

Если нужно перекрасить не всю строку, а только отдельную ячейку, то в проверку вашего условия необходимо включить проверку текущего поля таблицы, имя которого лежит в Column.FieldName .
Результаты работы аналогичного кода можно увидеть на рис.1 и рис.2 (раскрашена вся строка). На рис.3 раскрашена конкретная ячейка и шрифт меняет стиль (добавляется Bold ).

КАРТИНКА И CHECKBOX В ПОЛЕ TDBGRID.

Результаты работы этого кода смотрите на Рис. 1. Строки grid'а содержат в первой колонке CheckBox'ы и выделенные строки отмечены крыжиками. Работает такая конструкция достаточно естественно.

Поместить в поле DBGrid'а картинку тоже не составляет особого труда.
Картинку удобнее хранить в ImageList. Особенно если их несколько для разных случаев.
И вновь наше любимое событие. На рис.2 показано, как картинки выводятся для каждой строки определенных полей и по некоторому условию.

"Почему здесь используется метод рисования ImageList, а не метод канвы DBGrid'а ?" , спросите вы. Причин несколько, во-первых не надо "вытаскивать" из списка ImageList сам рисунок, чтобы подставить его как параметр в метод TCanvas.Draw , во-вторых, такой способ работает достаточно быстро и сохраняет свойство прозрачности картинки.
Если кому-то не нравится, можете попробовать оба эти способа и выбрать тот, который покажется более естественным.

Когда вы рисуете картинку таким способом в ячейке DBGrid'а, которая содержит длинный текст, то он будет "просвечиваться" по краям ячейки. Что, в общем-то, совершенно естественно, так как мы просто рисуем поверх поля. Чтобы устранить эту неприятность можно перед вызовом ImageList.Draw залить ячейку цветом фона.
Например так: Но это не единственный способ! Те, кто не любит экзотику, следующий абзац могут не читать. :о)

Есть такой класс TField , у него есть интересное событие TField.OnGetText . Происходит это событие тогда, когда требуется обновить содержимое текущей ячейки на экране. Ясно, что это событие возникает гораздо реже, чем перерисовка ячейки DBGrid. Сомневающимся предлагаю поэкспериментировать.
В обработчике этого события нам доступны само поле Sender , текст Text , который будет выводиться в этом поле и признак DisplayText .
Читая help, видим, что переопределив этот обработчик мы полностью контролируем что именно будет выводиться в поле и запрещаем автоматический вывод его значения из таблицы. Таким образом, просто переопределив пустой обработчик этого события, мы запрещаем выводить текст в поле, в котором собираемся рисовать картинку ! Вот и все. Канву можно не беспокоить.

Если вы хотите одновременно раскрашивать строки и помещать в них другие объекты, помните, что важно не перепутать порядок следования вызовов DrawFrameControl , ImageList.Draw и DefaultDrawColumnCell . Иначе получится несколько не то.
Каким именно должен быть этот порядок, решите сами :о).

ПОДМЕНА ТЕКСТА ИЛИ "КАКОЙ ДЛИНЫ РЫБА?".

Довольно часто возникает задача подменить значнение в поле DBGrid'а другим текстом. Например в таблице хранится числовое значение, которое пользователю мало о чем говорит и нужно заменить его чем-то более естественным.
По аналогии со всеми выше приведенными примерами хочется вернуться к событию TDBGrid.OnDrawColumnCell . Кажется чего проще, нарисуем на канве нужный нам текст и все готово!
Действительно, такой вариант среди советов по этой теме самый стандартный, но . не самый лучший.

На рис.3 в поле "Длина (см)" вместо числового значения (см. рис.1 и рис.2) приведен текстовый вариант осмысления длины рыбы. :о)

Итак, нам нужно вместо числа сантиметров написать, длинная эта рыба или короткая. Вспомним только что упомянутое событие TField.OnGetText - это как раз то, что нам нужно! Просто и, главное, быстро! Не нужно перерисовывать канву ячейки при каждом передвижении курсора по DBGrid'у. На мой взгляд так намного изящнее :о)
Вот, собственно, и все на тему подметы текста.

ПОЛОСАТОЕ ОКНО.

Нужно раскрасить DBGrid вне зависимости от данных в строках, а просто через одну, как часто делается в отчетах для повышения читаемости большого количества строк. Эта задача очень легко решается для локальных бах данных но , к сожалению, для SQL-СУБД такое же решение применить невозможно.
Важно понять, что сам компонент TDBGrid не хранит данных и ничего не знает о текущих строках своего DataSource, он их только отображает на форме.
Воспользуемся свойством RecordNo для класса TDataSet, оно отдает номер текущей записи в наборе данных (работает только для локальных СУБД, в остальных случаях равно -1 ).
Алгоритм раскраски очень прост: каждую нечетную строку перекрашиваем в нужный нам цвет, а четную строку оставляем такой, какая она есть. Для этого мы, как уже делали неоднократно, переопределяем событие TDBGrid.OnDrawColumnCell .

Результат работы этого кода виден на Рис.1

Итак, все строки аккуратно раскрашены через одну - задача решена.
Как уже отмечалось, такой вариант годится исключительно для локальных таблиц, для которых легко получить номер текущей строки в наборе данных.
Для SQL-баз можно, например, добавить вычисляемое поле, которое и будет содержать значение номера строки по порядку ( что никакого отношения к физическому номеру строки не будет иметь). То есть необходимо привязываться к данным, так как сам DBGrid ничего не знает о текущем состоянии своих строк.
Для малого количества записей такой способ годится, для больших наборов данных еще и перебирать их все с тем, чтобы добавить фиктивный номер, не очень удачное решение. Но другого способа нет, если я ошибаюсь, поправьте меня - с удовольствием приму исправления.

КАК ОТМЕТИТЬ НЕСКОЛЬКО СТРОК ИЛИ "НЕ MultiSelect'ОМ ЕДИНЫМ. "

Пользователь желает выделить несколько записей в таблице, чтобы потом производить с ними какие-либо действия. Совершенно неважно, что он потом с ними будет делать, печатать или удалять, важно то, что нам их надо как-то запомнить и доходчиво отобразить.
Один из вариантов решения этой задачи - создаем список ListSelect : TList; В этот список будем заносить идентификатор отмеченной записи. Ясно, что это должно быть какое-то уникальное значение, в нашем случае используем поле Species No , содержащее специфический номер записи.
Так как сам факт выделения записи имеет смысл только в текущем сеансе работы с программой, то в нашей таблице нет специального поля, в котором можно было бы хранить результат этого выделения. В проекте создается вычисляемое поле с названием Check , в нем мы ничего не будем хранить, оно необходимо не для этого, а для отрисовки в нем контрола TCheckBox.

Добавлять записи в список "выбранных" будем по клику мышки на CheckBox'е в текущей строке, что на самом деле соответствует клику на компоненте DBGrid в нашем поле Check . При клике на строке, котрой еще нет в списке, она туда помещается, если строка там уже есть, они удаляется из списка. Имитация стандартного поведения переключателя True/False.
Переопределяем событие TDBGrid.OnCellClick : Теперь у нас есть информация о том, какие записи выделены. Осталось только это отобразить. В каждой строке вместо поля Check нужно нарисовать стандартный CheckBox и поставить в нем крыжик, если эта запись входит в список ListSelect. Для этого немного модифицируем уже известный нам код: Довольно просто не правда ли? Теперь по этому списку можно спокойно обрабатывать выделенные записи, в отличие от использовании свойства TDBGrid.MultiSelect, выделенные строки не перестанут быть таковыми при следующем случайном клике мышкой.

Результаты выделения строк показы на рис.1 (с помощью CheckBox) и на рис.2 (строки выделены цветом и специальной картинкой)

РАЗНЫЕ МЕЛОЧИ.

Код, приводимый в тексте несколько отличается от того, что есть в самом проекте, который вы скачаете. Дело в том, что проект реализует сразу все указанные возможности, а в статье мне хотелось не смешивать слишком много в одном месте, дабы не запутать тех, кто только начинает сам разбираться. Поэтому в проекте проводятся более сложные проверки при обработке события перерисовки чейки.

Примечания к коду проекта:
Функция ShowStatusBar выводит в статусной строке количество выделенных строк.
Тип TColumnAction помогает аккуратно разобраться между типами колонок, для которых применяются разные методы отрисовки.
Функция GetColumnAction нужна для получения типа колонки по ее названию.
Компоненты CheckLarge , cbTypeSelect и cbLine нужны для переключения между режимами работы проекта.
Если не ограничивать эти режимы, то при одновременном использовании всех этих способов "выделить" что-то в DBGrid'е будет выглядеть просто ужасно.
Кстати, рис.4 можно считать иллюстрацией того, как не надо делать. Но это уже скорее вопрос проектирования пользовательского интерфейса и к нашей теме не имеет прямого отношения.

В архиве содержатся файлы проекта и exe-файл. Проект ориентирован на стандартную демонстрационную базу данных Paradox, поставляемую с Delphi, которая находится в каталоге $(DELPHI)\Borland Shared\Data.
Проект настроен на алиас DBDEMOS , работа идет с таблицей biolife.db
Откомпилирован в Delphi 5

Тайную мысль преследовала я этой статьей, славные жители Королевства. Очень надеюсь, что спрашивать меня об этом больше не будут.

  • Файлы проекта + exe (337 K) обновление от 11/3/2005 7:37:00 AM
  • Файлы проекта (14 K) обновление от 11/3/2005 7:38:00 AM

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Компонент Delphi DBGrid – это визуальный компонент среды Delphi, предназначен для визуализации наборов данных. Этот компонент находиться на странице компонентов DataControls палитры компонентов. Класс TDBCustomGrid и класс TCustomGrid – это родительские классы компонента DBGrid. Компонент делиться на столбцы (поля ввода данных) и строки (записи).

Свойства DBGrid

Свойства Описание
DataSource В этом свойстве указывают имя компонента DataSource для связи БД с компонентом DBGrid
Columns Хранит в себе коллекцию состоящих из столбцов таблицы. Позволяет для каждого столбца применить индивидуальные свойства, например цвет.
Options Определяет параметры отображения таблицы:


Работа со столбцами

Над значениями столбцов можно проводить различные операции: скрывать или показывать поля, менять положение, добавлять новые столбцы. Редактор столбцов предназначен для изменения набора полей. Вызывается редактор двойным щелчком мыши(рис 1). Он имеет четыре свойства (Add New, Delete Selected, Add All Fields, Restore Defaults). Соответственно: добавить новый столбец, удалить выделенный, добавить все столбцы из полей ввода данных, восстановление значения для выделенного столбца (по умолчанию). Свойства для каждого из выбранных столбцов появляются в Object Inspector. Со столбцами можно проводить такие операции:

  • редактирование;
  • удаление;
  • смена местами двух столбцов;
  • изменять заголовок столбцов (свойство Title).

Изменения набора полей Delphi DBGrid

Свойства Colums

  • cbsAuto — кнопка появляется, если связанное с ним поле является полем синхронного просмотра;
  • cbsEllipsis —кнопка редактирования ячейки появляется всегда;
  • cbsNone — Кнопа при редактировании ячеек не появляется

При необходимости создания дополнительного пустого столбца в редакторе столбцов таблицы DBGrid необходимо воспользоваться свойством FieldName (поле базы данных оставить пустым). В пустые столбцы можно перемещать уже обработанные данные из других столбцов.

Работа со строками

Как при работе со столбцами, так и при работе со строками можно изменять цвет ячеек – это очень удобно при работе с большим количеством данных, ведь всегда можно выделить отдельные столбцы или строки различными цветами для обозначения той или иной категории. Свойство DefaultDrawing – значение, которое влияет на способ прорисовки данных в компоненте DBGrid (по умолчанию свойство равно True, в этом случае данные прорисовываются автоматически). Если значение DefaultDrawing равно False, прорисовку нужно делать самостоятельно при помощи OnDrawColumnCell. Другой вариант, пользователь прописал алгоритм прорисовки, но значение свойства остается равно True, тогда DBGrid заполнится сначала автоматически, а лишь потом будет выполнен алгоритм пользователя (то есть прорисовка выполняется дважды, это сказывается на быстродействии программы, но теперь пользователю не придется заполнять все пустые ячейки вручную).

Если до компонента DBGrid вам приходилось работать с компонентом Delphi StringGrid, то вам уже будет намного легче, ведь принцип работы этих двух компонент очень похож, только к дополнению свойств StringGrid, DBGrid имеет свои собственные свойства. Ячейки – это основные структурные единицы таблицы. Свойство State – состояние таблицы (gdSelected – выделена, gdSelected – имеет фокус ввода, gdFixed – ячейка-заглавие столбца).

Не могу вытащить данные на TDBGrid при нажатии кнопки:

при нажатии кнопки на TDBGrid должно вывести

select *
from tab1 t

__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь

По двойному нажатию на строку в dbgrid открыть форму и заполнить поля dbedit данными из это строки
Доброго времени суток! Помогите пожалуйста! Нужно по двойному нажатию на строку dbgrid открывать.

ObservableCollection заполнить данными из базы
Добрый день. Возник такой вопрос, вот создаю я ObservableCollection для отображения данных в.

Ero, вам нужно 3 компонента - TDataSource, которые укажите в TDBGrid, сам TDBGrid и, конечно же, TQuery, который указаываете в в свойстве DataSet TDataSource. при открытии запроса, данные будут отображаться в гриде. Ero, вам нужно 3 компонента - TDataSource, которые укажите в TDBGrid, сам TDBGrid и, конечно же, TQuery, который указаываете в в свойстве DataSet TDataSource. при открытии запроса, данные будут отображаться в гриде. Добрый день. Никакой разницы какая база (локальная или удалённая) нет. Какие компоненты используете? Соединение настроили? Если да, то всё как сказал Lord_Voodoo, если нет, то сначала установите соединение с базой. Добрый день. Никакой разницы какая база (локальная или удалённая) нет. Какие компоненты используете? Соединение настроили? Если да, то всё как сказал Lord_Voodoo, если нет, то сначала установите соединение с базой. да, вроде так все сделал.
но не могу вывести данные ?
нажатием кнопки !
помогите пожалуйста !
Спс.

Что это. Где это.
Полагаю в поле SQL какой то Query? Я же спрашивал КАКИЕ компоненты для связи с базой? Если Вы будете выдавать куцые фразы и не отвечать на наводящие вопросы, мы не сможем Вам помочь.

Что это. Где это.
Полагаю в поле SQL какой то Query? Я же спрашивал КАКИЕ компоненты для связи с базой? Если Вы будете выдавать куцые фразы и не отвечать на наводящие вопросы, мы не сможем Вам помочь.


Что Вы сделали? С какой базой? Покажите код.

В компоненте DataSource1 в поле DataSet усановите Query1. В Query1 в поле SQL в открывающемся окне введите ваш запрос select * from tab1 t, и еще вы не установили соединение с базой данных. Ero, по картинкам видно, что вы не указали DataSet у DataSource1. ну и конечно же надо открыть запрос, чтобы данные отобразились, как показано в посте №9 В компоненте DataSource1 в поле DataSet усановите Query1. В Query1 в поле SQL в открывающемся окне введите ваш запрос select * from tab1 t, и еще вы не установили соединение с базой данных.

но как она будет работать при нажатии кнопки ?

DataSet не могу установить query1

для соединения что используем ? oraclesession пойдет ?

Используйте ADOConnection, ADOQuery и DataSource. В ADOConnection устанавливает связь, для этого нужно создать строку подключение, затем в ADO query Connecton установите ADOConnection1 и в DataSource - DataSet в ADOQuery1 и в DBGrid - DataSource - установите DataSource1. А вообще вы вопрос не правильно поставили, вам надо сначала научится к базе данных подключится. Используйте ADOConnection, ADOQuery и DataSource. В ADOConnection устанавливает связь, для этого нужно создать строку подключение, затем в ADO query Connecton установите ADOConnection1 и в DataSource - DataSet в ADOQuery1 и в DBGrid - DataSource - установите DataSource1. А вообще вы вопрос не правильно поставили, вам надо сначала научится к базе данных подключится. Спасибо за детальное объяснение, я еще хотел запрос написать, что б при нажатии в дбгриде отражался . Спасибо за детальное объяснение, я еще хотел запрос написать, что б при нажатии в дбгриде отражался .

Ero, вы юы сначало литературу почитали по работе с БД. потренеровались бы сначала на примере, потом что то свое осваивали. с таким уровнем знаний у вас врятли что то получится . ИМХО

Ero, вы юы сначало литературу почитали по работе с БД. потренеровались бы сначала на примере, потом что то свое осваивали. с таким уровнем знаний у вас врятли что то получится . ИМХО +1 Согласен, Ero вам и вправду нужно для начала почитать про СУБД, а вот при нажатии на DBGrid или при открытии формы или нажатии на другую кнопку - это тоже нужно почитать но уже про Delphi .

обновить БД, данными из DBGrid
наткнулся на проблему обновления БД после изменения данных в dbgrid на форме. То есть на форме в.

Разница между данными DBGrid
Здравствуйте. Создаю оболочку для БД(создана в ms access 2007) в базе таблицы связаны между собой.

Заполнение Word документа данными из строки DBGrid
Не знаю возможно ли это, но было бы очень здорово, если бы я смог это реализовать. В общем есть.


Заполнить данными StringGrid
Перерыл весь форум, так и не нашел. Нужно заполнить стринггрид как таблицу т. е. - кликнул мышкой.

Читайте также: