Как сделать distinct count в FastReport без group by в SQL
При работе с отчетами в FastReport иногда возникает потребность получить количество уникальных значений в каком-либо поле без использования группировки в SQL-запросе. В данной статье мы рассмотрим, как это можно сделать, используя пример с полем "Name" в отчете.
Проблема
У нас есть отчет с полями "Name" и "sex", и мы хотим получить количество уникальных имен в поле "Name", не используя группировку в SQL-запросе. Например:
Name sex
João m
João m
Maria f
При обычном подсчете количество строк будет 3, но мы хотим получить количество уникальных имен, то есть 2.
Решение
Для решения этой задачи можно воспользоваться скриптом в FastReport. Ниже приведен пример скрипта, который решает данную проблему:
var
LastName: string;
DistinctCount: integer;
procedure OnGroupHeader1.OnBeforePrint;
begin
if (LastName <> FieldByName('Name').AsString) then
begin
Inc(DistinctCount);
LastName := FieldByName('Name').AsString;
end;
end;
function GetDistinctCount: string;
begin
Result := IntToStr(DistinctCount);
end;
В этом скрипте мы используем переменные LastName и DistinctCount. Переменная LastName хранит последнее уникальное имя, а DistinctCount - количество уникальных имен.
В событии OnBeforePrint группы GroupHeader1 мы сравниваем текущее имя с последним уникальным именем. Если они не равны, то мы увеличиваем счетчик уникальных имен и обновляем последнее уникальное имя.
Функция GetDistinctCount возвращает количество уникальных имен в виде строки.
Пример кода в Delphi
Ниже приведен пример кода на Object Pascal (Delphi), который демонстрирует использование данного скрипта в отчете:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, FRxReport;
type
TForm1 = class(TForm)
frxReport1: TFRxReport;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
// Заполняем отчет данными
with frxReport1.DataSet do
begin
Close;
SQL.Clear;
SQL.Add('SELECT Name, sex FROM YourTable');
Open;
end;
// Добавляем скрипт в отчет
with frxReport1.ReportDesigner do
begin
// Создаем скрипт
with CreateComponent(TfrxScript) do
begin
Name := 'Script1';
ScriptText :=
'var' + #10 +
' LastName: string;' + #10 +
' DistinctCount: integer;' + #10 + #10 +
'procedure OnGroupHeader1.OnBeforePrint;' + #10 +
'begin' + #10 +
' if (LastName <> FieldByName(''Name'').AsString) then' + #10 +
' begin' + #10 +
' Inc(DistinctCount);' + #10 +
' LastName := FieldByName(''Name'').AsString;' + #10 +
' end;' + #10 +
'end;' + #10 + #10 +
'function GetDistinctCount: string;' + #10 +
'begin' + #10 +
' Result := IntToStr(DistinctCount);' + #10 +
'end;';
// Добавляем скрипт в отчет
ReportDesigner1.Components.Add(Component);
end;
// Привязываем скрипт к группе в отчете
with ReportDesigner1.FindObject('GroupHeader1') do
begin
// Добавляем поле для отображения количества уникальных имен
with CreateComponent(TfrxLabel) do
begin
Name := 'Label1';
Text := 'Количество уникальных имен:';
Parent := Self;
end;
// Добавляем поле для отображения результата скрипта
with CreateComponent(TfrxLabel) do
begin
Name := 'Label2';
Text := '=Script1.GetDistinctCount';
Parent := Self;
end;
// Привязываем скрипт к событию OnBeforePrint группы
OnBeforePrint := Script1.OnBeforePrint;
end;
end;
end;
end.
В данном примере мы заполняем отчет данными из таблицы "YourTable", создаем скрипт с описанным выше кодом, привязываем скрипт к группе в отчете и добавляем поля для отображения количества уникальных имен и результата скрипта. При печати отчета скрипт будет выполняться перед печатью каждой группы, и в поле "Label2" будет отображаться количество уникальных имен в поле "Name".
Контекст: Как сделать distinct count в FastReport без group by в SQL?
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.