Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Базы данных
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 27.01.2015, 10:38
schuher schuher вне форума
Прохожий
 
Регистрация: 27.01.2015
Сообщения: 3
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Объединение 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  
Старый 28.01.2015, 16:29
Аватар для Kailon
Kailon Kailon вне форума
Активный
 
Регистрация: 06.06.2010
Сообщения: 339
Версия Delphi: 10.4
Репутация: 429
Сообщение

Цитата:
Сообщение от schuher
...но при выполнении ругается на переменную S
Код:
DM.ADOQuery1.SQL.Add('UPDATE Dvig SET kol=kol+s');
А может быть так надо?
Код:
DM.ADOQuery1.SQL.Add('UPDATE Dvig SET kol=kol + ' + IntToStr(s));
Тогда ругаться не будет, но такой запрос изменит всю таблицу. Нужно задавать условия через WHERE.
__________________
Всегда пишите код так, будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете.

Последний раз редактировалось Kailon, 28.01.2015 в 16:36.
Ответить с цитированием
  #3  
Старый 28.01.2015, 20:25
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Если для каждого значения name из таблицы tb1 есть ОДНО такое-же значение в таблице tb2 то все можно сделать одним запросом:
Код:
UPDATE Tb1 INNER JOIN Tb2 ON Tb1.name = Tb2.name SET Tb1.kol = [tb1].[kol]+[Tb2].[kol];
И поле Dw вообще уберите, оно вам только мешает. Записывайте сразу отрицательное значение для расхода и положительное для прихода.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.

Последний раз редактировалось Страдалецъ, 28.01.2015 в 20:36.
Ответить с цитированием
  #4  
Старый 30.01.2015, 06:58
schuher schuher вне форума
Прохожий
 
Регистрация: 27.01.2015
Сообщения: 3
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
И поле Dw вообще уберите, оно вам только мешает. Записывайте сразу отрицательное значение для расхода и положительное для прихода.
Благодарю за ответы, сейчас добью через код Делфи и буду пытаться делать через запрос, точнее не пытаться а хотелось бы все в нем сделать, но решении задачи с помощью одного метода на середине не брошу)))
Но к сожалению не каждому пользователю объяснишь, что когда РАСХОД, то значение надо ставить со знаком "-", от сюда следует что поле 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;
Теперь осталось сделать условие на проверку tb2.kol=>tb1.kol, так как отпуск со склада не может быть произведен если на складе нет столько материала!!! И еще одну проверку tb1.name=tb2.name and tb1.ed_izm=tb2.ed_izm - ну это для того чтобы к примеру, у одного поставщика наименование материала отпускается, как в виде БАНОК, а у другого тот же материала в виде ШТ. Но с условием на поле DW долго не думал, так как оно логического поля, а вот тут опять цикл придется ставить.
Если есть какие-нибудь поправки и предложения по оптимизации кода, но пока SQL малость не понятен, изучаю, но если есть направленная литература буду благодарен.

Последний раз редактировалось schuher, 30.01.2015 в 08:21.
Ответить с цитированием
  #5  
Старый 30.01.2015, 07:00
schuher schuher вне форума
Прохожий
 
Регистрация: 27.01.2015
Сообщения: 3
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Kailon
А может быть так надо?
Код:
DM.ADOQuery1.SQL.Add('UPDATE Dvig SET kol=kol + ' + IntToStr(s));
Тогда ругаться не будет, но такой запрос изменит всю таблицу. Нужно задавать условия через WHERE.
Благодарю за поправку, разобрался))) А вот через запрос с условиями, которые указал в предыдущем сообщении по подробнее хотел примерчик, если не сложно

Последний раз редактировалось schuher, 30.01.2015 в 07:19.
Ответить с цитированием
  #6  
Старый 02.02.2015, 00:32
Аватар для Kailon
Kailon Kailon вне форума
Активный
 
Регистрация: 06.06.2010
Сообщения: 339
Версия Delphi: 10.4
Репутация: 429
Сообщение

Цитата:
Сообщение от schuher
... с проверкой на пустой ввод:
Код:
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'); -это я так, проверял на работоспособность условий
Я представляю если еще потребуется добавить несколько полей. Это же твоя проверка сколько ступеней будет иметь?
Вот тебе универсальный код. Проверит все компоненты 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;
__________________
Всегда пишите код так, будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 17:13.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter