Форум: "Базы";
Текущий архив: 2004.01.16;
Скачать: [xml.tar.bz2];
ВнизСнятие аттрибута ReadOnly с полей в TClientDataSet Найти похожие ветки
← →
Rem (2003-12-18 17:11) [0]Проблема вот в чем:
- данные через TADOQuery запрашиваются из БД; запрос связанный - из нескольких таблиц;
- через TDataSetProvider (локальный) данные передаются в TClientDataSet
ClientDataSet.SetProvider(Provider);
ClientDataSet.Open;
- и в результате у TClientDataSet некоторые поля имеют аттрибут ReadOnly, так как обратная их запись невозможна (они вытянуты первичным запросом из других таблиц)
Установка ReadOnly := false для ClientDataSet и полей не помогает, так как это свойство установлено у курсора более низкого уровня. Интерфейс доступа к данным IDSBase напрочь отказывается это делать.
И при попытке изменить эти поля выскакиевает Exception "Can"t modify read-only field".
Для чего это надо? Загруженные единожды данные хранятся в памяти компбьютера и периодически обновляются: периодически считывается изменившаяся(иеся) строка(и) из БД - и переписывается(ются) в ClientDataSet для отображения пользователю.
Может, кто в курсе, что делать? Заранее благодарен!
← →
Rem (2003-12-18 17:55) [1]И?...
← →
Polevi (2003-12-18 17:58) [2]не очень хороший вариант, но на крайний случай можешь пошаманить с ClientDataset.XmlData - убрать оттуда тег ридонли и присвоить другому ClientDataset.XmlData
← →
Mik Prokoshin (2003-12-19 06:43) [3]Сними ReadOnly у полей нижележащей таблицы. Но получишь потом проблемы при записи таблиц в БД.
← →
Rem (2003-12-19 14:11) [4]2 Mik Prokoshin
Они не снимаются, в том то и дело. Как ADO, так и ClientDataSet работают с данными через COM, а интерфесы наборов данных не позволяют снимать этот аттрибут, ругаются.
Но я все же решил эту проблему. ClientDataSet использует два интерфеса: DSBase - для хранения данных, и DSCursor - для доступа к данным. И как раз DSCursor не позволяет записывать данные в свои ReadOnly поля. А DSBase это все равно. Поэтому можно получить прямой доступ к данным через интерфейс DSBase:
var
Packet: TDataPacket;
UpdateDS.DSBase.StreamDS(Packet);
if BaseDS.Locate("Код", a_sID, []) then
begin
BaseDS.DSCursor.GetRecordNumber(iRecNum);
BaseDS.DSBase.RefreshRecords(Packet, iRecNum, 0, nil);
end
else
BaseDS.DSBase.AppendData(Packet, true);
Правда, после обновления/записи данных надо вручную обновить курсор. Но это уже просто:
BaseDS.UpdateCursorPos;
BaseDS.Resync([]);
Так что вот как-то так... Спасибо всем!... :)
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.01.16;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.204 c