Используя ClientDataSet в Delphi, можете ли вы отображать данные и дельта-записи в DBGrid? - PullRequest
2 голосов
/ 01 ноября 2010

Я делаю приложение в базе данных Delphi 6 + MySQL, используя стандартные компоненты, учитывающие данные, и dbExpress.Приложение позволяет пользователям просматривать записи в сетке и редактировать данные (вставлять и / или удалять записи) на стороне клиента.Эти изменения данных затем записываются в базу данных только после нажатия кнопки «Отправить».Все это прекрасно работает и имеет следующую настройку:

Controls : 1. DBGrid1 связан с DataSource1 для визуального отображения данных.2. DataSource1 связан с ClientDataSet1, чтобы предложить данные для отображения DBGrid.3. ClientDataSet1 связан с DataSetProvider1 для предоставления данных на стороне клиента для редактирования.4. DataSetProvider1 связан с SQLDataSet1, который выбирает записи из одной таблицы БД.5. SQLDataSet1 связан с SQLConnection для обеспечения подключения к базе данных MySQL.

Действия : 1. Пользователь вставляет запись: я использую ClientDataSet1.InsertRecord;2. Пользователь удаляет запись: я использую ClientDataSet.Delete;3. Пользователь отправляет данные: я использую ClientDataSet1.ApplyUpdates (-1);

Все это прекрасно работает с точки зрения обработки данных и публикации данных (с учетом небольшого взлома DataSetProvider1BeforeUpdateRecord для удаления записей).

СЕЙЧАС ДЛЯ МОЕЙ ПРОБЛЕМЫ: Когда пользователь впервые загружает форму, DBGrid1 отображает все исходные записи, удаляет все удаленные записи.Но когда пользователь вставляет новую запись в ClientDataSet1, пустая запись отображается в DBGrid1.Фактические данные не теряются и не устанавливаются в NULLS. Как и в случае ClientDataSet1.ApplyUpdates, эта запись правильно записывается в БД.

Я знаю, что TClientDataSet имеет свойство data для исходных данных и свойство Delta для отредактированных данных.Могут ли эти два свойства с данными отображаться в одной DBGrid одновременно и, тем не менее, позволять пользователю редактировать данные?

Я посмотрел более 30 ресурсов и демонстрационных приложений и все избежали этой проблемы.Можно ли это сделать?

Ответы [ 3 ]

3 голосов
/ 08 декабря 2010

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

Чистый результат:

  1. Эти элементы управления в целом немного ошибочны.
  2. В конкретной ссылке на мой вопрос можно с уверенностью сказать, что элементы управления не могут делать то, что я описываю как стандарт.

Это основано на более чем 30 демонстрационных приложениях, статьях и руководствах, которые я рассмотрел, которые либо не описывают отображение обоих исходных данных с данными Delta в одной сетке данных. Конечно, вы можете взломать этот результат (что я и сделал), используя Listbox или StringGrid, но это также указывает на то, что элемент управления не может или не может использоваться при предоставлении этой функциональности (маловероятно, что это возможно).

Эта функциональность, на мой взгляд, является очевидным упущением, поскольку пользователь хочет видеть потенциальный результат своих действий, удобно в единой сетке данных, И разработчик хочет предоставить это простым и безболезненным способом, то есть с использованием сетки данных отображать данные!

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

Если вы создали демонстрационное приложение и не смогли заставить его работать, проголосуйте за мой ответ. Спасибо

0 голосов
/ 20 октября 2011

TClientDataset будет обрабатывать правильное состояние записи.Изменения записываются в журнал, но если вы не попросите его подробно показать какой-либо другой статус (см. Свойство StatusFilter), он покажет фактическое состояние записи.

Возможно, InsertRecord обходит некоторый механизм уведомлений, поэтому отображение поляне обновляетсяЧто, если вы выполните просто вставку и установите значения полей?

0 голосов
/ 20 октября 2011

Элемент управления TDBGrid, поставляемый с Delphi, не имеет встроенных функций для отображения как старых, так и новых значений для полей.Вы можете, конечно, унаследовать от Grid или создать свою собственную и добавить функциональность, или купить сторонний компонент, который выполняет то, что вы хотите.Вы не ограничены стандартными элементами управления, хотя они предоставляют наиболее часто требуемые функции.

Вы также можете выполнить то, что хотите, используя вычисляемые поля.Например, если у вас есть поле String Name, добавьте новое вычисленное поле String к набору данных с именем OldName такой же длины, что и Name.

Затем в своем событии OnCalcFields для набора данных простовведите код, подобный следующему:

if DataSet.State = dsEdit then
begin
  DataSet.FieldByName('OldName').Value := DataSet.FieldByName('Name').OldValue;
end
else
begin
  DataSet.FieldByName('OldName').Value := Null;
end;
...