DELPHI: Master-Detail с использованием ClientDataSet и CalcFields
У меня есть основной / подробный ClientDataSet следующим образом (они создаются/заполняются во время выполнения и заполняются данными, возвращенными из вызова API, без подключения к базе данных):
Services:
ID
Name
BasePrice
etc.
AddOns:
Selected
ID
ServiceID
Name
Quantity
UnitCost
TotalCost
etc.
Я отображаю сервисы как выпадающее поле, которое затем заполняет сетку доступными надстройками для этого сервиса. Поле "TotalCost" - это вычисляемое поле, отображаемое в таблице в отдельном столбце. Поле "выбрано" используется для отслеживания флажка, показанного в таблице, чтобы указать, что клиент хочет этого. особое дополнение.
Все это работает, как и ожидалось. Теперь мне нужно рассчитать общую стоимость услуги плюс любые дополнения. Стоимость услуги, которую я могу получить, используя:
ClientDataSetServices.FieldByName('BasePrice').Value
Однако я не могу получить TotalCost из каждого выбранного дополнения. Я думал, что мог бы использовать агрегатное поле, но в моих поисках я обнаружил, что это не выполнимо с помощью настройки master / detail. Я также попытался просто перебрать детали ClientsDataSet как образом:
(within the CalcFields method of the details ClientDataSet)
// Add parts to parts cost
grdMain.DataSource.DataSet.First;
while not grdMain.DataSource.DataSet.Eof do begin
if (grdMain.DataSource.DataSet.FieldByName('Selected').Value) then begin
FPartsCost := FPartsCost +
grdMain.DataSource.DataSet.FieldByName('TotalPrice').Value;
end;
grdMain.DataSource.DataSet.Next;
end;
Но это приводит к бесконечному циклу. Когда я отлаживаю эту часть кода, я нахожу, что ...набор данных.Во-первых, это вызов CalcFields (или что-то еще, что в свою очередь вызывает CalcFields).
Как я могу перебирать набор данных выбранных надстроек для динамического расчета общих затрат (при изменении выбора или количества)?
--EDIT--
Я попытался настроить агрегат в таблице деталей следующим образом:
- добавлено TAggregate 'AggregatePrice'
- задайте поля следующим образом:
Active-True
Имя-AggregatePrice'
Выражение-сумма (TotalPrice)
Уровень группирования-1
IndexName-ServiceId
Видимое-Истинное
Когда я запускаю это, я получаю сообщение об ошибке "поле ' TotalPrice' не является правильным типом вычисляемого поля для использования в агрегате, используйте internalcalc "
2 ответов:
После редактирования ответ кажется очевидным: используйте поле InternalCalc вместо простого CalcField!
Расчет все еще выполняется внутри поля Oncalc, но вы должны проверить TDataset.Состояние для dsInternalCalc.
Это необходимо, поскольку агрегаты вычисляются после dsInternalCalc, но до состояния dsCalcFields.
В качестве дополнительной заметки, поле InternalCalc может быть использовано для индекса, но простое CalcField не может.
Один из способов заключается в использовании клонированного курсора для детализации-копии набора данных, которая синхронизируется с содержимым источника, но может перемещаться независимо.
Напр.
CopyCDS.CloneCursor(OriginalCDS,False); // check params in help to see options CopyCDS.First; while not CopyCDS.EOF do begin // do stuff to calculate what you need CopyCDS.Next; end;Имейте в виду, что клонированный курсор не будет иметь вычисляемых полей или каких-либо событий, связанных с оригиналом, поэтому вам нужно будет настроить их снова, если это необходимо.
Comments