Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.05.2009, 01:59   #1
Vitalik55
Пользователь
 
Регистрация: 03.12.2008
Сообщений: 16
Злость Цикл в ADOTable

Создал цикл который должен считать задолжность людей за месяцы,
складывать их и показывать на другой таблице их сумму для каждого человека.
Мозг уже кипит))
Вот код помогите найти ошибку.

Код:
var c:real; n:string;
begin
c:=0;
ADOTable1.First;
while not(AdoTable1.Eof) do
  begin
  n:=adotable1.FieldByName('Контрагент').AsString;
    while not(AdoTable1.Eof) do
    begin
      if n=adotable1.FieldByName('Контрагент').AsString then
      begin
      c:=c+adotable1.FieldByName('Долг').AsFloat;
        if n=form3.ADOTable1.FieldByName('Контрагент').AsString then
        begin
        form3.ADOTable1.FieldByName('Долг').AsFloat:=c;
        end;
      end;
    adotable1.Next;
    end;
adotable1.Next;
end;
end;
Vitalik55 вне форума Ответить с цитированием
Старый 21.05.2009, 06:53   #2
edgy
Форумчанин
 
Регистрация: 15.06.2008
Сообщений: 271
По умолчанию

Не проще ли написать запрос, чем гонять датасет по циклу?

Что-нибудь вроде этого (упрощенно):
Код:
select sum ( dolg ) as dolg_kontragent,
         kontragent
  from your_table
group by kontragent
edgy вне форума Ответить с цитированием
Старый 21.05.2009, 10:56   #3
Vitalik55
Пользователь
 
Регистрация: 03.12.2008
Сообщений: 16
По умолчанию

Просто с запросами ещё неработал и вся прога уже написанна с адотабле кроме этого момента с циклом.
Vitalik55 вне форума Ответить с цитированием
Старый 21.05.2009, 11:52   #4
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

Vitalik55, стоит подумать над предложением, edgy
представь, что у тебя в этой табличке уже не 100 строчек как у тебя на тесте, а под 100 000 в бою! во-первых, сама табличка лопнет столько данных принимать и отображать, а уж редактировать так ваще устрелится, а уж по циклам гонять и еще "веселее" будет.

но если ты так прям горишь желанием поработать с таблами, то, наверное, у тебя много лишних данных считается и итоги набегают, и данные наверняка присваются не те
ты же считаешь долг по данным табл. adotable1 для контрагента из табл. form3.ADOTable1
Код:
var 
  c:real; 
  n:string;
begin
c:=0;
n=form3.ADOTable1.FieldByName('Контрагент').AsString;
if ADOTable1.Locate('Контрагент', n, [{здесь можно указать опции локейта по желанию}]) then 
begin
  while not(AdoTable1.Eof) do 
  if n=adotable1.FieldByName('Контрагент').AsString then begin
    c:=c+adotable1.FieldByName('Долг').AsFloat;
    if not(AdoTable1.Eof) then
      AdoTable1.Next;
  end
  else begin
    form3.ADOTable1.FieldByName('Долг').AsFloat:=c;
    exit;
  end;
end;

Последний раз редактировалось soleil@mmc; 21.05.2009 в 12:04.
soleil@mmc вне форума Ответить с цитированием
Старый 21.05.2009, 21:17   #5
Vitalik55
Пользователь
 
Регистрация: 03.12.2008
Сообщений: 16
По умолчанию

Прога чета ругается на EXIT и вопрос зачем он нужен.
А если его убрать то ругается на while
ADOTable1: Dataset not in edit or insert mode
Vitalik55 вне форума Ответить с цитированием
Старый 21.05.2009, 22:24   #6
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

Цитата:
Сообщение от Vitalik55 Посмотреть сообщение
Прога чета ругается на EXIT и вопрос зачем он нужен.
это я обозначил момент выхода из процедуры, который возможно и нужно переписать, выбрав нормальное условие (есть над чем тебе поработать)

Цитата:
Сообщение от Vitalik55 Посмотреть сообщение
ADOTable1: Dataset not in edit or insert mode
а здесь неясно про какой датасет речь - про первый или про второй
если про второй, то так допиши
Код:
form3.ADOTable1.Edit;
form3.ADOTable1.FieldByName('Долг').AsFloat:=c;
form3.ADOTable1.Post;
soleil@mmc вне форума Ответить с цитированием
Старый 22.05.2009, 00:25   #7
Vitalik55
Пользователь
 
Регистрация: 03.12.2008
Сообщений: 16
По умолчанию

Немного поковырял код получилось это
Код:
c:=0;
while not(form3.AdoTable1.Eof) do
begin
n:=form3.ADOTable1.FieldByName('Контрагенты').AsString;
  while not(form1.AdoTable1.Eof) do
  if n=form1.adotable1.FieldByName('Контрагенты').AsString then begin
    c:=c+form1.adotable1.FieldByName('Задолжность').AsFloat;
    form3.ADOTable1.Edit;
    form3.ADOTable1.FieldByName('Задолжность').AsFloat:=c;
    form3.ADOTable1.Post;
    form1.AdoTable1.Next;
    end else
    form1.AdoTable1.Next;
    end;
    c:=0;
    form3.ADOTable1.Next;

    end;
Но считает правильно и записывает в таблицу только 1 запись а дальше не идёт.
Vitalik55 вне форума Ответить с цитированием
Старый 22.05.2009, 01:17   #8
koma_grusha
Редкий обитатель
Форумчанин
 
Аватар для koma_grusha
 
Регистрация: 08.04.2009
Сообщений: 170
По умолчанию

в суть глубоко не лазила, просто подправлю твой же код
Код:
form3.AdoTable1.First;
while not(form3.AdoTable1.Eof) do
begin
    c:=0;
    n:=form3.ADOTable1.FieldByName('Контрагенты').AsString;
    form1.AdoTable1.First;
    while not(form1.AdoTable1.Eof) do
    begin
        if n=form1.adotable1.FieldByName('Контрагенты').AsString then
            c:=c+form1.adotable1.FieldByName('Задолжность').AsFloat;
        form1.AdoTable1.Next;
    end;
    form3.ADOTable1.Edit;
    form3.ADOTable1.FieldByName('Задолжность').AsFloat:=c;
    form3.ADOTable1.Post;
    form3.AdoTable1.Next;
end;
Мозг, хорошо устроенный, стоит больше, чем мозг, хорошо наполненный (Мишель Монтень)
koma_grusha вне форума Ответить с цитированием
Старый 22.05.2009, 11:39   #9
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

скл-запросом точно "дешевле" будет это проделать
form3.AdoTable1.RecordCount * form1.adotable1.RecordCount переборов по табл. form1.adotable1 - это просто до фига

надеюсь, ты не забудешь отключить контролы перед таким перебором

твой вариант (с обработкой всех строк в таблице) можно ускорить если немного выправить мой вариант и реализовать его в виде функи
по крайней мере, не нужно будет листать почти всю таблицу, чтобы встать на нужную запись (Locate рулит)

Последний раз редактировалось soleil@mmc; 22.05.2009 в 11:41.
soleil@mmc вне форума Ответить с цитированием
Старый 22.05.2009, 11:46   #10
koma_grusha
Редкий обитатель
Форумчанин
 
Аватар для koma_grusha
 
Регистрация: 08.04.2009
Сообщений: 170
По умолчанию

действительно, почему бы автору не послушать советы от edgy и soleil@mmc, заодно научишься работать с запросами (чем сэкономишь уйму времени и сил), а если у тебя все на ADOTable, так ты запрос назови также, ведь почти все функции у них схожи, а основная разница, грубо говоря, в том что у запроса вместо свойства TableName, есть свойство SQL, где пишешь собственно запрос, например
Код:
SELECT * FROM Table
Мозг, хорошо устроенный, стоит больше, чем мозг, хорошо наполненный (Мишель Монтень)

Последний раз редактировалось koma_grusha; 22.05.2009 в 12:23.
koma_grusha вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
AdoTable Artruman БД в Delphi 4 03.04.2009 02:07
AdoTable Mishina БД в Delphi 2 15.06.2008 06:35
Как копировать данные из ADOTable в ADOTable? mauar БД в Delphi 1 10.05.2008 16:05
Цикл с предусловием. ( цикл while) Цикл с постусловием. (цикл repeat ... until) Mr.User Помощь студентам 9 23.11.2007 01:34