*Helly* |
Отправлено: 30.12.2003, 13:40 |
|
Не зарегистрирован
|
Добрый день!
Такой вопрос.
Есть DataSet, открытый только для чтения. Для добавления и изменения записей используется хранимая процедура. При выполнении Refresh() после вставки записи новая запись в DataSet не отражается. Можно ли как нибудь заставить работать Refresh() без перечитывания всего набора данных? |
|
Nick |
Отправлено: 31.12.2003, 09:45 |
|
Машинист паровоза
Группа: Участник
Сообщений: 247
|
Поставь poRefreshAfterPost = false
Но если процедура изменяет какието поля в зависимости от изменений других полей
Допустим
В базе хранится Количество и Сумма, Цена расчитывается в запросе.
При изменении Суммы если ты сама не пересчитываешь уже в гриде цены, она визуально для пользователя неизменится, так как в случае
poRefreshAfterPost = false не выполнится Refresh для измененной записи.
Есть еще возможность оставить poRefreshAfterPost = false.
Но тебе надо определять значение ключевого поля.
Или поставить Генератор на ключевое поле или в событии AfterInsert вызывать процедуру возвращаюшую Новое ID ключевого поля и самой присвавать.
Вот пример RefreshSQL из моего проекта.
SELECT
NAKLDATA_ID, DATA_ID, DOCUMENTS_ID,
DET_ID, NAME, AMOUNT, CENA, SUMMA,
OLDCENA, NEWCENA, PERCENT, RESERVE,
PART, PARTNAME, NAL, NOTE, NDS, NLSP,
AKCIZ, NDSSUMMA, NLSPSUMMA, AKCIZSUMMA
FROM
DOCS_DATA_2
(
:IPDOCS_ID
)
WHERE
(
DATA_ID = :OLD_DATA_ID )
DATA_ID = :OLD_DATA_ID — указывает что RefreshSQL выполняется для измененной (добавленной) записи по ключевому полю DATA_ID |
|
** pasha |
Отправлено: 31.12.2003, 13:16 |
|
Не зарегистрирован
|
QUOTE | Можно ли как нибудь заставить работать Refresh() без перечитывания всего набора данных? |
Скорее всего нельзя.
(ведь я так понимаю, свойства SQLs: Update/Insert/Delete пусты,
да к тому-же и не через них происходит изменения таблицы)
Наверное придется использовать pFIBDataSet->CloseOpen(false);
|
|
*Helly* |
Отправлено: 05.01.2004, 11:59 |
|
Не зарегистрирован
|
Я попробовала каждый раз заново перестраивать запрос в RefreshSQL,
подставляя вместо значений OLD_XXX значения из новой записи. В этом случае TDataSet считывает из базы новую запись, но в гриде она
перезаписывается на место той записи, которая была активной перед вставкой новой. |
|
Nick |
Отправлено: 05.01.2004, 13:06 |
|
Машинист паровоза
Группа: Участник
Сообщений: 247
|
Не надо перестраивать запрос.
Его я привел для того что бы показать
Запрос Refresh работает по ключевому полю.
Если ключевое поле новой записи программе неизветно то и
Refresh не покажет эту запись. |
|
*Helly* |
Отправлено: 05.01.2004, 13:13 |
|
Не зарегистрирован
|
Так в том то весь и прикол, что если я перестраиваю RefreshSQL,
то новая запись появляется в гриде, но только вместо той, на которой стоял курсор. |
|
*Helly* |
Отправлено: 05.01.2004, 17:03 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 12
|
Вроде бы получилось обновлять грид, путем работы с кешем набора данных:
делаю добавление пустой записи в кэш таблицы
int intArr[2] = {0,1};
const int* Ar = intArr;
Variant vFields;
vFields << NULL << NULL;
dsView->CacheAppend(Ar,sizeof(intArr),&vFields,sizeof(vFields));
тогда при выполнении Refresh() (с подстановкой конкретных значений вместо OLD_XXX) новая запись отображается на месте пустой
Один только вопрос, как реально проверить, что рефрешится только одна запись, а не весь набор данных?
|
|
Nick |
Отправлено: 06.01.2004, 09:11 |
|
Машинист паровоза
Группа: Участник
Сообщений: 247
|
Слов нет.
Пришли кусок проекта, подправлю где надо.
Soltami@yandex.ru |
|
Bubble |
Отправлено: 23.01.2004, 00:36 |
|
Не зарегистрирован
|
А чем плох-то CloseOpen(false)?
Зачем с рефрешем мучиться. Или я не понимаю чего-то? |
|
Nick |
Отправлено: 23.01.2004, 08:52 |
|
Машинист паровоза
Группа: Участник
Сообщений: 247
|
Зачем пересчитывать Шоколад в одном ящике.
Лучше открыть весь камаз пересчитать все ящики и закрыть (зкрыть сначала-забылся). |
|
** pasha |
Отправлено: 25.01.2004, 21:32 |
|
Не зарегистрирован
|
Остаюсь при своем мнении: CloseOpen(false)
Это работает корректно.
А вот в вашем варианте возможны различные глюки.
|
|
Nick |
Отправлено: 26.01.2004, 08:45 |
|
Машинист паровоза
Группа: Участник
Сообщений: 247
|
Кто же делает CloseOpen после добавления всего одной записи.
Тем более курсор упадет на первую запись а не на новую.
|
|
** Deem |
Отправлено: 17.02.2004, 17:13 |
|
Не зарегистрирован
|
Вобще, вопрос это больной. Только Закрытие/открытие увидит новую запись (я уже собрался писать свой DBGrid, задолбало). Можно запомнить ключевое поле записи, на которой стоит курсор, закрыть/открыть запрос и выйти на запомненную запись. Правда, в гриде записи могут переместиться, и выбранная запись часто оказывается в самом низу (что на нервы действует).
В FB+ при добавлении записи можно генерировать ключ на клиенте, а не в триггере. Тогда клиент знает ключ новой записи и выходит на нее.
Если новая запись добавляется ХрПр, то она может возвращать клиенту ключевое поле новой записи, и тогда после CloseOpen можно перепрыгрнуть курсором на новую запись. |
|
olegenty |
Отправлено: 18.02.2004, 09:57 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
Вот готовое решение. В него надо вникнуть, но оно работает, а опубликовано, кстати, давно.
http://ibase.ru/devinfo/ClientRefresh.htm
по всем вопросам об Interbase/Firebird/Yaffil рекомендую http://ibase.ru. проблемы у всех одни, а решены многие из них уже давно.
|
|