| 
| 
 | Вопрос # 1 806/ вопрос открыт / | 
 |  Здравствуйте, уважаемые эксперты!Подскажите , как можно сделать так чтобы при изменении в gride записи она автомотически изменялась во всех таблицах где она встречается .... я предпринимала некоторые попытки но  выскакивает сообщение: resultat : Dataset not in edit or insert mode --- > это при попытке № раз (код №1)
 Либо вообще ничего не происходит (Код №2)
 Приложение:Переключить в обычный режим  i:integer;begin for i:=1 to DM.resultat.RecordCount dobeginif  dm.resultat.FieldByName('ID_D').AsInteger=DM.dogovor.FieldByName('ID_D').AsInteger   then if  dm.resultat.FieldByName('ID_C').AsInteger=DM.klient.FieldByName('ID_C').AsInteger   then      end;  If DM.klient.FieldByName('id_c')=dm.resultat.FieldByName('id_c') then  
|  |   Вопрос задала: Танюшка (статус: Посетитель)Вопрос отправлен: 7 августа 2008, 10:56
 Состояние вопроса: открыт, ответов: 3.
 |  Ответ #1. Отвечает эксперт: Помфюк Владимир Степанович Здравствуйте, Танюшка!перед изменением таблицы надо бы её перевести в режим редактирования:
 dm.resultat.edit;
 Ответ #2. Отвечает эксперт: ANBsoft Здравствуйте, Танюшка!А по окончании редактирования записи нужно выполнить
 dm.resultat.post;
 это для сохранения сделанных изменей.
 Каким гридом пользуемся?
 При использовании TDBGrid все действия происходят автоматически.
 Чтобы его подключить к запросу, ставим на форма TDataSource, в поле DataSet указываем свой запрос.
 После этого ставим TDBGrid и в поле DataSource указываем описанный TDataSource.
 Это намного удобнее чем делать через обычные гриды.
 
|  | Ответ отправил: ANBsoft (статус: Студент)Время отправки: 7 августа 2008, 11:13
 Оценка за ответ: 5
 |  Ответ #3. Отвечает эксперт: Шичко Игорь Здравствуйте, Танюшка!А Вы не пробовали при анализе таблиц dogovor и klient воспользоваться SQL-запросами.
 Мне кажется это будет немного попроще:
 i, temp:integer;
 begin
 DM.resultat.First; //переходим на первую запись
 for i:=1 to DM.resultat.RecordCount do
 begin
 temp:= dm.resultat.FieldByName('ID_D').AsInteger;
 SQLdogovor.SQL.Text:= "Select ID_D, Fields[1] from dogovor where ID_D = temp;
 SQLdogovor.Open; SQLdogovor.First;                                      // считываем запись из dogovor по ID_D
 SQLclient.SQL.Text:= "Select ID_D, Fields[1] from client where ID_D = temp;
 SQLclient.Open; SQLclient.First;                                             // считываем запись из client по ID_D
 
 dm.resultat.edit; // редактирование
 dm.resultat.FieldByName('Наименование').AsString:=SQLdogovor.Fields.Fields[1].AsString;
 dm.resultat.FieldByName('ФИО').AsString:=SQLclient.Fields.Fields[1].AsString;
 dm.resultat.post;
 
 SQLdogovor.Close;
 SQLclient.Close;
 
 DM.resultat.Next;
 end;
 end;
 
 SQLclient и SQLdogovor - TADOQuery
 
|  | Ответ отправил: Шичко Игорь (статус: 9-ый класс)Время отправки: 7 августа 2008, 12:05
 
 |  
 Мини-форум вопросаВсего сообщений: 23; последнее сообщение — 7 августа 2008, 20:05; участников в обсуждении: 5. Страницы: [1] [2] [Следующая »]  
|   | Танюшка (статус: Посетитель), 7 августа 2008, 11:23 [#2]:я извиняюсь за повторение просто не знала что при обновлении мой вопрос отсылается дважды . теперь пишет ошибку: "Не удается найти строку для обнавления, некоторые значения могли быть изменены со времени ее последнего чтения ."
 Что еще нужно добавить?
 |  
|   | ANBsoft (статус: Студент), 7 августа 2008, 11:30 [#3]:И если нужно переносить данные из одного запроса в другой, то лучше это делать по событию AfterPost измененного запроса. |  
|   | Танюшка (статус: Посетитель), 7 августа 2008, 11:46 [#4]:Так тож не получается оно в базе изменения только в опред таблицах делает а там где нужно то есть в результирующей старые записи не меняет а это оч нужно сделать ... |  
|   | ANBsoft (статус: Студент), 7 августа 2008, 11:46 [#5]:Кроме того, Ваш код во многих случаях вообще не будет работать (так как RecordCount возвращает количество уже полученных записей, а не полное их количество). Я бы рекомендовал на событие AfterPost Ваших запросов Dogovor и Klient поставить такой код:
 if  dm.resultat.Locate('ID_D',DM.dogovor.FieldByName('ID_D').AsInteger,[]) then begin
 dm.resultat.Edit;
 dm.resultat.FieldByName('Наименование').AsString:=DM.dogovor.Fields.Fields[1].AsString;
 dm.resultat.Post;
 end
 else ShowMessage('Запись не найдена');
 и
 if  dm.resultat.Locate('ID_C',DM.klient.FieldByName('ID_C').AsInteger,[]) then begin
 dm.resultat.Edit;
 dm.resultat.FieldByName('ФИО').AsString:=DM.klient.Fields.Fields[1].AsString;
 dm.resultat.Post;
 end
 else ShowMessage('Запись не найдена');
 Так будет намного лучше.
 |  
|   | Танюшка (статус: Посетитель), 7 августа 2008, 11:53 [#6]:Сейчас попробую ... |  
|   | Танюшка (статус: Посетитель), 7 августа 2008, 11:54 [#7]:Спасибо вам огромное!!!!!!!!!!!!!!!!!Бубырь Александр Николаевич !!!!!!!!!!! Вышло просто так как было нужно
  )))))))))))) |  
|   | ANBsoft (статус: Студент), 7 августа 2008, 12:03 [#8]:Значит можно и оценку поставить  . |  
|   | Танюшка (статус: Посетитель), 7 августа 2008, 12:42 [#9]:Извините за навязчивость, но тут такое дело, почему-то меняется только одна запись , а все остальные остаются без изменения......... может тут еще цикл какой-нить добавить... |  
|   | Помфюк Владимир Степанович (статус: Абитуриент), 7 августа 2008, 12:52 [#10]:Проще всего воспользоватся видоизменённом советом Игоря Шичко: использовать SQL-запросы update: SQLresultat.SQL.Text:= 'update resultat set Наименование='''+DM.dogovor.Fields.Fields[1].AsString+''' where ID_D ='+DM.dogovor.FieldByName('ID_D').AsString;
 тогда точно обновлятся все записи c совпадающими ID_D
 |  
|   | ANBsoft (статус: Студент), 7 августа 2008, 13:03 [#11]:если записей много, можно переделать так: dm.resultat.First;
 if  dm.resultat.FieldByName('ID_D').AsInteger=DM.dogovor.FieldByNamedm.resultat.Edit;
 dm.resultat.FieldByName('Наименование').AsString:=DM.dogovor.Fields.Fields[1].AsString;
 dm.resultat.Post;
 end;
 ('ID_D').AsInteger   then begin
 while dm.resultat.LocateNext('ID_D',DM.dogovor.FieldByName('ID_D').AsInteger,[]) do begin
 dm.resultat.Edit;
 dm.resultat.FieldByName('Наименование').AsString:=DM.dogovor.Fields.Fields[1].AsString;
 dm.resultat.Post;
 end;
 Хотя лучше будет описанный выше массовый апдейт.
 |  
|   | ANBsoft (статус: Студент), 7 августа 2008, 13:06 [#12]:Пардон, как-то коряво отослало, еще раз: если записей много, можно переделать так:
 dm.resultat.First;
 if dm.resultat.FieldByName('ID_D').AsInteger=DM.dogovor.FieldByName('ID_D').AsInteger then begin
 dm.resultat.Edit;
 dm.resultat.FieldByName('Наименование').AsString:=DM.dogovor.Fields.Fields[1].AsString;
 dm.resultat.Post;
 end;
 while dm.resultat.LocateNext('ID_D',DM.dogovor.FieldByName('ID_D').AsInteger,[]) do begin
 dm.resultat.Edit;
 dm.resultat.FieldByName('Наименование').AsString:=DM.dogovor.Fields.Fields[1].AsString;
 dm.resultat.Post;
 end;
 Хотя лучше будет описанный выше массовый апдейт.
 |  
|   | Шичко Игорь (статус: 9-ый класс), 7 августа 2008, 13:35 [#13]:Одна запись поэтому и корректируется, потому что нужно использовать структуру First
 for...
 begin
 ...
 Next
 end;
 Как я ранее уже написал, согласен также с
 Помфюк Владимир Степанович
 |  
|   | ANBsoft (статус: Студент), 7 августа 2008, 13:57 [#14]:В общем, выбор зависит от конкретных задач, описанные мной алгоритмы позволяют программно контролировать все вносимые изменения, массовые апдейты несомненно проще и быстрее, но в некоторых случаях потребуют усложнения бизнес-правил самой базы данных, а это сложнее отлаживается и не все базы позволяют это делать (например если при изменении каждой записи в resultat нужно изменять в соответствии с ней еще какие-то зависимые таблицы или делать пересчеты). Описанные варианты позволяют выбирать в зависимости от конкретных задач, далее каждый выбирает сам.
 |  
|   | Шичко Игорь (статус: 9-ый класс), 7 августа 2008, 14:23 [#15]:to Бубырь Александр Николаевич Совершенно согласен, кроме этого влияние имеет какой размер базы планируется использовать
 |  
|   | Вадим К (статус: Академик), 7 августа 2008, 14:45 [#16]:to  Шичко Игорь ваша конструкция с for плоха. плоха по той причине, что для некоторых баз получения общего кол-ва записей - долгая операция.
 Но это пол проблемы. если не сделать транзакцию, то может оказаться, что на момент прохода по записям, кол-во может отличаться. (это возможно при совместной работе нескольких пользователей).
 правильная конструкция выглядит где то так.
 
 MyTable.first;
while not MyTable.eof do begin
  //код обработки записи
  //....
  MyTable.next
end;Для некоторых типов баз такой "проход" гораздо эффективнее. Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Танюшка (статус: Посетитель), 7 августа 2008, 15:28 [#17]:а что это за LocateNext? |  
|   | Шичко Игорь (статус: 9-ый класс), 7 августа 2008, 15:31 [#18]:to Вадим К Вадим, согласен, но не совсем.
 Подсчет количества записей насколько я понимаю происходит при открытии набора. Поэтому коль уж мы по нему идем, то подразумевается, что известно количество.
 MyTable.first не сможет выполниться без открытия таблицы.
 Хотя в целом мой алгоритм расчитан в большем мере на работу с наборами, созданными на основе SQL-запросов.
 |  
|   | Вадим К (статус: Академик), 7 августа 2008, 15:45 [#19]:есть два способа работы с базами. в первом закачиваются все данные. в таком случае количество записей известно и по ним можно безобидно пройтись.
 
 Но при больших объёмах, закачивать невыгодно. Поэтому запрос кол-ва записей превращается в лишний SQL запрос.
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | ANBsoft (статус: Студент), 7 августа 2008, 17:06 [#20]:TIBCustomDataSet.LocateNext Searches the dataset for the record after a specified record and makes that record the current record.
 function LocateNext(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean;
 Description
 Call LocateNext to search a dataset for a record after the current cursor position
 Аналогично Locate, но ищет следующую запись начиная с текущей, удовлетворяющую условию.
 Правда не во всех компонентах есть, я пользуюсь TIBQuery, потому и написал по привычке.
 |  Страницы: [1] [2] [Следующая »]  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |