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

Delphi Sources



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

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 27.09.2013, 12:14
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию Сумма по колонке (с добавлением)

Задачка такая:
пользователь должен добавлять в таблицу элементы: по принципу
заполняется поле А
заполняется поле Б
автоподсчёт поле С = А*Б;

Здесь первый вопрос. Если полю С выдать AutoCalc, и в onFieldCalc обрабатывать его подсчёт, то почему-то это значение не сохраняется в Таблицу. Что я делаю не так?

Далее с каждым новым элементом общая сумма по колонке С должна отображаться на форме.

Вторая часть реализована следующим образом:
Код:
var
  TotalPrice: real;
begin
  with fMain.Items do
  begin
    Post;
    TotalPrice := 0;
    First;
    while not Eof do
    begin
      TotalPrice := TotalPrice + FieldByName('Price').AsFloat;
      Next;
    end;

    maxPrice.Text := FormatFloat('0.00', TotalPrice);
    maxLoan.Text := FormatFloat('0.00', TotalPrice * 0.76);
  end;
Получается, что каждый раз программа пересчитывает предыдущие элементы. А если их будет 100, и добавляться 101 ... а если 1000.

Была мысли уйти от ADOTable и воспользоваться ADOQuery и запросом (SUM), но как-то весь проект в таблицах.) Это скорее эстетика. Может стоит отказаться от таблиц?

Последний раз редактировалось Uniq!, 27.09.2013 в 12:28.
Ответить с цитированием
  #2  
Старый 27.09.2013, 12:46
Аватар для Mrak
Mrak Mrak вне форума
Местный
 
Регистрация: 26.01.2013
Адрес: МО
Сообщения: 438
Версия Delphi: XE2
Репутация: 17
По умолчанию

Конечно отказывайся, пока не стало еще хуже
Если таблицы есть и их много и не охота переделывать, то сделай симбиоз с квериками

Бд - доска, таблицы - топор, кверики - электролобзик))
__________________
Я за здоровый экстрим!
Спасибо за "спасибо")
Ответить с цитированием
Этот пользователь сказал Спасибо Mrak за это полезное сообщение:
Uniq! (27.09.2013)
  #3  
Старый 27.09.2013, 13:12
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Раз тут начался поиск серебряной пули, считаю нужным отписаться для контекста.

На самом деле задача подсчета итогов прямо в процессе ввода нетривиальна для DB-компонентов и является частным проявлением проблемы размазывания логики между клиентом и сервером. Подсчет суммы агрегатной функцией sum на сервере -- это одно, а подсчет и функцией на сервере, и еще какими-то костылями на клиенте во время ввода -- это другое. Без костылей, к сожалению, не получается, поскольку большинство DB-компонентов не умеют делать это штатно. ADO в их числе, но в других компонентах я что-то тоже такого не припомню.

Поэтому, если задача именно в подсчете на лету, любое решение будет вынужденным костылем, называемым заграничным словом workaround, зато при работе с ним будет греть мысль, что это не просто мелкая проблема, а частное проявление чего-то большего, что до сих пор не решено в компьютерной науке.
Ответить с цитированием
Этот пользователь сказал Спасибо Freeman за это полезное сообщение:
Uniq! (27.09.2013)
  #4  
Старый 27.09.2013, 13:27
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Все несколько не так.
Если вы хотите только видеть результаты в таблице то вам нужно использовать calcfield. Но! Имейте ввиду что это по сути виртуальное поле и живет оно только на экране. Обратится извне к нему не выйдет ибо его в таблице физически не существует. Более приятный и удобный способ - это сделать запрос с вычислением. Вот тогда уже можно к такому полю обратится извне. Но и тут без подводных камней не обойдется если вам нужен подсчет при вводе.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
Этот пользователь сказал Спасибо Страдалецъ за это полезное сообщение:
Uniq! (27.09.2013)
  #5  
Старый 27.09.2013, 13:57
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию

Ребят, вот wiki:fkInternalCalc.
Я так понимаю, это мой ключ от замка к первой части задачи.

Только вот справиться с ним не могу.
1) Двойной клик на "открытом" TADOTable (т.е. DataSet заполнен)
2) Добавляю все колонки
3) Выставляю нужным колонкам в свойствах fkInternalCalc
4) Обрабатываю в OnCalcFields подсчёт этой колонки:
Код:
procedure TfMain.ItemsCalcFields(DataSet: TDataSet);
begin
  DataSet.FieldByName('MetallWeight').AsFloat := DataSet.FieldByName('Weight')
    .AsFloat - DataSet.FieldByName('InsertWeight').AsFloat;
  DataSet.FieldByName('Price').AsFloat := DataSet.FieldByName('MetallWeight')
    .AsFloat * DataSet.FieldByName('Pricep1g').AsFloat;
end;
Обычно, при вводе в связанные с DataSet'ом TDBEdit'ы, изменения сразу отображаются в DBGrid. А вот с fkInternalCalc ничего не происходит.

С TADOQuery не работал. Пока попробую вникнуть.

Последний раз редактировалось Uniq!, 27.09.2013 в 14:06.
Ответить с цитированием
Этот пользователь сказал Спасибо Uniq! за это полезное сообщение:
Freeman (27.09.2013)
  #6  
Старый 27.09.2013, 15:11
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Uniq!
А вот с fkInternalCalc ничего не происходит.
Во, век живи, век учись. Раньше думал, что fkInternalCalc -- для совместимости с древними версиями VCL, гвоздями прибитыми к BDE. Ан нет.

Как понимаю, этот вид поля предназначен для вычисляемых полей с кэшируемыми значениями, которые и хранятся в наборе данных. Не поленился и посмотрел в исходниках, как это реализовано. Похоже, что это базовая функциональность, реализованная в модуле DB и унаследованная всеми наследниками TDataSet. Стало быть, и в ADO должно быть.

Как можно догадаться, я сам fkInternalCalc ни разу не пользовал... Могу предположить, что значения этих полей нужно изменять вместе с изменением основных полей, раз они физически хранятся в наборе данных. Если сработает, мне придется посыпать голову пеплом взять назад свои слова об отсутствии в DB-компонентах возможности подсчета на лету.
Ответить с цитированием
Ответ


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

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