|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Объединение 2 таблиц с одинаковыми полями, но частично с разными данными
Всем привет!!!
Буду благодарен за Вашу помощь!!! Возникли проблемки в написание кода объединения 2 таблиц(tb1,tb2) с полями tb1(n,name,kol,ed_izm) и tb2(n,name,dw,kol,ed_izm). То есть суть такова, мне необходимо в общую таблицу tb1 внести данные, которые будут в tb2, но не просто объединить, а произвести действия с ними. К примеру: [IMG] [/IMG] Поясняю: пока не конец tb2 делаю Если1 в tb1.name равно tb2.name делаю если2 tb2.dw='прих' делаю tb1.kol:=tb1.kol+tb2.kol иначе2 если3 tb2.dw='расх' делаю tb1.kol:=tb1.kol-tb2.kol иначе1 tb1 добовляем строки из tb2 Работаю с помощью ADOQuere, таблицы в Access2003. То есть не получается написать правильно код! Возможно условие цикла не правильно задаю! Код:
procedure TForm1.Button4Click(Sender: TObject); var s:integer; begin if DM.ADOQuery2.Modified then begin DM.ADOQuery2.Post; DM.ADOQuery2.First; while not DM.ADOQuery2.Eof do begin s:= DM.ADOQuery2.FieldByName('kol').AsInteger; if Trim(AnsiLowerCase(DM.ADOQuery2.FieldByName('name').Text))= Trim(AnsiLowerCase(DM.ADOQuery1.FieldByName('name').Text)) then begin DM.ADOQuery1.Close; DM.ADOQuery1.SQL.Clear; DM.ADOQuery1.SQL.Add('UPDATE Dvig SET kol=kol+s'); DM.ADOQuery1.ExecSQL; end; DM.ADOQuery2.Next; end; end; Сам код на компиляцию ошибок не выдает, но при выполнении ругается на переменную S. Тем самым попробывал в запросе вместо S поставить цифру 5, данные изменяются причем все, а нужно чтобы изменились только совподающии данные с поля(name) из таблиц (tb1,tb2) . Поправьте код, или мою направленность, если такое возможно или подскажите как правильно обращаться к ячейке на коде программировании и выполнять с ней какие либо действия Последний раз редактировалось schuher, 27.01.2015 в 13:21. |
#2
|
||||
|
||||
Цитата:
Код:
DM.ADOQuery1.SQL.Add('UPDATE Dvig SET kol=kol + ' + IntToStr(s)); Всегда пишите код так, будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете. Последний раз редактировалось Kailon, 28.01.2015 в 16:36. |
#3
|
||||
|
||||
Если для каждого значения name из таблицы tb1 есть ОДНО такое-же значение в таблице tb2 то все можно сделать одним запросом:
Код:
UPDATE Tb1 INNER JOIN Tb2 ON Tb1.name = Tb2.name SET Tb1.kol = [tb1].[kol]+[Tb2].[kol]; Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. Последний раз редактировалось Страдалецъ, 28.01.2015 в 20:36. |
#4
|
|||
|
|||
Цитата:
Но к сожалению не каждому пользователю объяснишь, что когда РАСХОД, то значение надо ставить со знаком "-", от сюда следует что поле DW необходимо для задачи условия. Вот код который написал. Осуществляет заполнение расходно-приходной таблицы, с проверкой на пустой ввод: Код:
begin try if Edit1.Text = '' then begin ShowMessage('Введите данные'); Edit1.SetFocus; end else if DM.ADOQuery2.Locate('name', Edit1.Text, []) = True then begin ShowMessage('Введите данные'); Edit1.Clear; Edit1.SetFocus; end else if ComboBox1.Text = '' then begin ShowMessage('Введите данные'); ComboBox1.SetFocus; end else begin if Edit4.Text = '' then begin ShowMessage('Введите данные'); Edit4.SetFocus; end else if ComboBox2.Text = '' then begin ShowMessage('Введите данные'); ComboBox2.SetFocus; end else begin //ShowMessage('dfkz'); -это я так, проверял на работоспособность условий DM.ADOQuery2.Insert; DM.ADOQuery2.FieldByName('data').AsDateTime:=DateTimePicker1.DateTime; DM.ADOQuery2.FieldByName('name').AsString:=Edit1.Text; DM.ADOQuery2.FieldByName('dw').AsString:=ComboBox1.Text; DM.ADOQuery2.FieldByName('kol').AsFloat :=StrToInt(Edit4.Text); DM.ADOQuery2.FieldByName('ed_izm').AsString:=ComboBox2.Text; DM.ADOQuery2.Post; end; end; except on e:Exception do end; end; А вот и сам код для вставки в другую таблицу: Код:
var Proverka:boolean; s:extended; begin Proverka:=false; // if DM.ADOQuery2.Modified then begin - правда тут мне надо условие на изменения данных в таблицы поставить //DM.ADOQuery2.Post; - чтобы пользователь не ввел одни и те же данные 2 и более раз. // но думаю что в конце кода буду просто очищать таблицу полностью DM.ADOQuery2.First; //переход на первую запись в tb2 While not DM.ADOQuery2.Eof do begin DM.ADOQuery3.First; //переход на первую запись в tb1 While not DM.ADOQuery3.Eof do begin if DM.ADOQuery3.FieldByName('name').AsString=DM.ADoquery2.FieldByName('name').AsString then begin if DM.ADOQuery2.FieldByName('dw)').AsBoolean=true then begin // вот это условия не получилось объединить в одном IF, так как он //ругается на несовместимость типов string and boolean DM.ADOQuery3.Edit; //открываю для редактирования , если 2 условия выполняется DM.ADOQuery3.FieldByName('kol').AsFloat:=DM.ADOQuery3.FieldByName('kol').AsFloat+DM.ADOQuery2.FieldByName('kol').AsFloat; DM.ADOQuery3.Post; proverka:=true; end else begin DM.ADOQuery3.Edit; DM.ADOQuery3.FieldByName('kol').AsFloat:=DM.ADOQuery3.FieldByName('kol').AsFloat-DM.ADOQuery2.FieldByName('kol').AsFloat; DM.ADOQuery3.Post; proverka:=true; end; end; DM.ADOQuery3.next; // если условие выполнилось переходим на следующую запись в tb1 end; if proverka=false then // тут долго думал, так как без этого условия //не шла добавка записей из tb2.name , если данные разные //ну в общем не нужна, тут просто else поставлю, в голове каша с бд, со временем просматривая, что-то изменяю) begin DM.ADOQuery3.Insert; DM.ADOQuery3.FieldByName('data').AsDateTime:=DM.ADOQuery2.FieldByName('data').AsDateTime; DM.ADOQuery3.FieldByName('name').AsString:=DM.ADOQuery2.FieldByName('name').AsString; DM.ADOQuery3.FieldByName('dw').AsString:=DM.ADOQuery2.FieldByName('dw').AsString; DM.ADOQuery3.FieldByName('kol').AsFloat:=DM.ADOQuery2.FieldByName('Kol').AsFloat ; DM.ADOQuery3.FieldByName('ed_izm').AsString:=DM.ADOQuery2.FieldByName('ed_izm').AsString; DM.ADOQuery3.Post; DM.ADOQuery3.next; end; DM.ADOQuery2.next; // переход на следующую запись в tb2 end; Если есть какие-нибудь поправки и предложения по оптимизации кода, но пока SQL малость не понятен, изучаю, но если есть направленная литература буду благодарен. Последний раз редактировалось schuher, 30.01.2015 в 08:21. |
#5
|
|||
|
|||
Цитата:
Последний раз редактировалось schuher, 30.01.2015 в 07:19. |
#6
|
||||
|
||||
Цитата:
Вот тебе универсальный код. Проверит все компоненты Edit и ComboBox, вне зависимости от имени, где отличительное свойство Tag = 1. Код:
procedure Tfrm_Test.btn_CheckingClick(Sender: TObject); var I: Integer; begin for I := 0 to ComponentCount - 1 do if (Components[i] is TEdit) and ((Components[i] as TEdit).Tag = 1) and ((Components[i] as TEdit).Text = '') or (Components[i] is TComboBox) and ((Components[i] as TComboBox).Tag = 1) and ((Components[i] as TComboBox).Text = '') then begin MessageBox(Handle, 'Введите данные', 'Информация', mb_IconInformation); try (Components[i] as TEdit).SetFocus except (Components[i] as TComboBox).SetFocus; end; Exit; end; end; Всегда пишите код так, будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете. |