Если вы хотите создать отчет Мастер/Деталь в Fast Reports для Delphi XE2, но столкнулись с проблемами перехода ко второй записи в втором датасете, этот гайд поможет вам решить эту проблему.
Проблема
Пользователь вводит две даты и два времени, и на основании этих значений загружаются данные из двух Oracle датасетов. При нажатии кнопки "Печать" значения вводятся в первый датасет, который затем возвращает первое значение и отправляет его вместе с введенными пользователем значениями во второй датасет для печати деталей, относящихся к полученному значению. Однако, второй датасет возвращает только записи для первого значения и дублирует их для каждой записи в первом датасете.
Причина проблемы
Проблема заключается в том, что второй датасет не переходит к следующей записи после завершения цикла печати деталей. Это происходит из-за того, что в коде не выполняется команда Next для второго датасета после цикла печати деталей.
Решение проблемы
Чтобы решить эту проблему, необходимо установить связь между первым и вторым датасетами и использовать параметры для передачи значений между ними. Вот шаги, которые помогут вам это сделать:
Добавьте компонент DataSource на форму и подключите его к первому датасету (opr_operator_ods) с помощью свойства DataSet.
В событии OnDataChange компонента DataSource, закройте второй датасет (opr_operatorcount_ods), установите параметры, открыв второй датасет и передав значение оператора из первого датасета во второй датасет.
В функции печати подготавьте и распечатайте отчет, используя подготовленный мастер-датасет.
Вот пример кода, который решает эту проблему:
procedure Print;
begin
// Подготовьте мастер-датасет (установите параметры, закройте и откройте его)
opr_operator_ods.Close;
opr_operator_ods.SetVariable('DATEFROM', opr_datefrom_dtp.Date);
opr_operator_ods.SetVariable('DATETO', opr_dateto_dtp.Date);
opr_operator_ods.SetVariable('TIMEFROM', opr_timefrom_dtp.Text);
opr_operator_ods.SetVariable('TIMETO', opr_timeto_dtp.Text);
opr_operator_ods.Open;
// ... другие параметры ...
// Подготовьте и распечатайте отчет
frxReport1.PrepareReport;
frxReport1.ShowPreparedReport;
end;
procedure TForm1.DataSource1DataChange(Sender: TObject);
begin
// Закройте второй датасет
opr_operatorcount_ods.Close;
// Установите параметры и откройте второй датасет
opr_operatorcount_ods.SetVariable('DATEFROM', opr_datefrom_dtp.Date);
opr_operatorcount_ods.SetVariable('DATETO', opr_dateto_dtp.Date);
opr_operatorcount_ods.SetVariable('TIMEFROM', opr_timefrom_dtp.Text);
opr_operatorcount_ods.SetVariable('TIMETO', opr_timeto_dtp.Text);
opr_operatorcount_ods.SetVariable('OPERATOR', opr_operator_ods.FieldByName('opr_code').AsString);
opr_operatorcount_ods.Open;
end;
Альтернативное решение
Если вы хотите сохранить текущий подход без использования параметров, вы можете вручную управлять перемещением по записям в обоих датасетах. Для этого вам нужно будет добавить команды Next для обоих датасетов после цикла печати деталей. Вот пример кода, который демонстрирует это решение:
procedure Print;
begin
opr_operator_ods.Close;
opr_operator_ods.SetVariable('DATEFROM', opr_datefrom_dtp.Date);
opr_operator_ods.SetVariable('DATETO', opr_dateto_dtp.Date);
opr_operator_ods.SetVariable('TIMEFROM', opr_timefrom_dtp.Text);
opr_operator_ods.SetVariable('TIMETO', opr_timeto_dtp.Text);
opr_operator_ods.Open;
if opr_operator_ods.RecordCount > 0 then
begin
while not opr_operator_ods.Eof do
begin
opr_operatorcount_ods.Close;
opr_operatorcount_ods.SetVariable('DATEFROM', opr_datefrom_dtp.Date);
opr_operatorcount_ods.SetVariable('DATETO', opr_dateto_dtp.Date);
opr_operatorcount_ods.SetVariable('TIMEFROM', opr_timefrom_dtp.Text);
opr_operatorcount_ods.SetVariable('TIMETO', opr_timeto_dtp.Text);
opr_operatorcount_ods.SetVariable('OPERATOR', opr_operator_ods.FieldByName('opr_code').AsString);
opr_operatorcount_ods.Open;
while not opr_operatorcount_ods.Eof do
begin
frxReport1.PrepareReport(false);
opr_operatorcount_ods.Next;
end;
frxReport1.PrepareReport(true);
opr_operator_ods.Next;
end;
end;
DecodeDate(opr_datefrom_dtp.Date, tyear, tmonth, tday);
StartDate := '''' + IntToStr(tday) + '/' + IntToStr(tmonth) + '/' + IntToStr(tyear) + '''';
DecodeDate(opr_dateto_dtp.Date, tyear, tmonth, tday);
EndDate := '''' + IntToStr(tday) + '/' + IntToStr(tmonth) + '/' + IntToStr(tyear) + '''';
frxReport1.Variables['StartDate'] := StartDate;
frxReport1.Variables['EndDate'] := EndDate;
frxReport1.ShowPreparedReport;
end;
Обе эти подходы должны решить проблему перехода ко второй записи во втором датасете в вашем отчете Мастер/Деталь в Fast Reports для Delphi XE2. Вы можете выбрать тот, который лучше всего подходит для вашего проекта.
Мастер/Деталь отчет в Fast Reports для Delphi XE2: Решение проблемы перехода ко второй записи во втором датасете.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.