Migrare da QuickReport a sgcReports

sgcReports è il motore di report a bande di sgcUI: TsgcReport contiene il layout, TsgcReportEngine collega i dati, TsgcReportPreviewVCL mostra le pagine e l'esportazione PDF scrive PDF/UA con tag. Questo kit associa le bande e i controlli di QuickReport che usi ai loro equivalenti in sgcReports, mostra il codice di una demo compilata ed elenca con onestà ciò che non si associa.

Report Delphi VCL creati con QuickReport

Un TQuickRep su un form, bande, controlli QR sulle bande e un pulsante di anteprima, stampa o PDF nell'applicazione.

QuickReport è di nuovo in manutenzione. In "QuickReport is back" (blog di Embarcadero, Ian Barker, 14 novembre 2024) Embarcadero spiega che il prodotto ha attraversato una crisi quando è venuto a mancare il suo sviluppatore principale, che è stato riportato in vita con il partner di Embarcadero Barnsten e che ora supporta ogni versione di RAD Studio con Delphi e C++Builder a partire da Delphi 7. La pagina QuickReport di Barnsten (letta il 2026-10-20) elenca un filtro PDF con font TrueType incorporati, il supporto PDF/A e filtri di esportazione HTML, XML/XSLT, XLS e XLSX, e indica QuickReport Pro 5-developer a 2.155,00 EUR IVA esclusa. Questa pagina quindi non parla di un prodotto morto o di un pulsante PDF mancante. È per i team che vogliono ciò che quell'elenco di funzioni non nomina.

Cosa aggiunge sgcReports

Ogni affermazione su sgcReports riportata di seguito è presente nel codice sorgente distribuito. Per QuickReport si scrive "non elencato" dove la pagina del produttore tace, non "non supportato".

PDF/UA accessibile

TsgcReportPDFExport scrive per impostazione predefinita PDF/UA con tag (PDFUA è True, PDFUAPart sceglie la parte 1 o 2), con ordine di lettura, ruoli di intestazione dal TagRole dell'elemento, testi alternativi da AltText e Language e Title del documento. PDFA aggiunge PDF/A-3b, PDF/A-3a o PDF/A-4 per gli archivi. È presente in ogni edizione, Community inclusa. PDF/UA e PDF con tag non sono elencati nella pagina delle funzioni di Barnsten. I documenti accessibili contano di più dopo l'European Accessibility Act, la Direttiva (UE) 2019/882, che riguarda prodotti e servizi come e-book, e-commerce e servizi bancari.

Un designer per l'utente finale, VCL e FireMonkey

I tuoi utenti possono modificare un report senza una nuova build: sgcShowReportDesigner(Engine) apre il designer VCL, oppure incorpora il pannello TsgcVCLReportDesigner; sgcShowReportDesignerFMX(Engine) fa lo stesso in FireMonkey (Delphi XE6 e successivi, desktop). Il designer VCL segue le modifiche di DPI del form (ispettore, icone e superficie di disegno si ridimensionano in ChangeScale). Solo edizioni Registered. La pagina delle funzioni di Barnsten non elenca un designer per l'utente finale; storicamente era un prodotto di terze parti separato, QRDesign. Sull'High DPI, una risposta su Delphi-PRAXiS del 4 aprile 2022 diceva che QuickReport 6 si compila con Delphi 11.1 ma non supporta l'High-DPI; verifica la versione attuale con il produttore.

Un solo motore per la suite

Tabelle incrociate, codici a barre, sottoreport e testo ricco sono tipi di elemento dello stesso motore a bande. Con le unit ponte, un report stampa anche un grafico sgcCharts e una tabella pivot sgcPivotGrid come elementi, disegnati come contenuto vettoriale nel PDF (edizioni Registered). Esportazioni: PDF, XLSX, CSV, HTML e PNG in ogni edizione, DOCX nelle edizioni Registered.

Definizioni JSON e un equivalente .NET

Un report si salva e si carica in JSON (TsgcReport.SaveToFile, LoadFromFile), quindi i layout possono stare in un database o nel controllo di versione. La stessa definizione si carica in sgcReports per .NET (NuGet esegece.sgcReports, .NET Standard 2.0, .NET Framework 4.7.2 e .NET 6 e successivi), quindi un report Delphi può essere riutilizzato da un servizio .NET.

I report vengono ricostruiti, non importati. sgcReports non può aprire un .dfm di QuickReport: non esiste un importatore di QuickReport. Ogni report viene ricreato, nel codice come fa la demo qui sotto, oppure nel designer di sgcReports (edizioni Registered). La mappatura e i passaggi di questa pagina rendono il lavoro meccanico, banda per banda. sgcReports è concesso in licenza per sviluppatore a partire da €199, con il codice sorgente completo e un anno di aggiornamenti, ed è incluso anche in sgcUI.

Classi di QuickReport, equivalenti in sgcReports

Ogni nome di sgcReports riportato di seguito è presente nel codice sorgente distribuito, e quelli usati dalla demo vengono compilati. I nomi di QuickReport sono riportati per orientamento; QuickReport non era installato quando questa pagina è stata verificata.

QuickReport sgcReports Edizione
TQuickRepTsgcReport (Pages, Styles, Units, Title) e TsgcReportEngine (Report, AddDataSource, Prepare, Variables, OnGetVariable)Tutte
TQuickRep.DataSetTsgcReportDataSetSource (SourceName, DataSet) registrato con AddDataSource; il DataSourceName della banda lo indicaTutte
TQuickRep.Page (carta, margini)TsgcReportPage.PaperSize (rpsA3, rpsA4, rpsA5, rpsLetter, rpsLegal, rpsCustom), Margins.Left, Top, Right, BottomTutte
TQuickRep.ReportTitleTsgcReport.Title e TsgcReportPDFExport.Title per i metadati del PDFTutte
TQRBand con BandType rbTitle, rbPageHeader, rbColumnHeaderTsgcReportBand con BandType rbtReportTitle, rbtPageHeader, rbtColumnHeaderTutte
rbDetailrbtMasterData con DataSourceName impostato sulla sorgente masterTutte
rbGroupHeader, rbGroupFooterrbtGroupHeader, rbtGroupFooterTutte
rbSummary, rbPageFooterrbtReportSummary, rbtPageFooterTutte
TQRChildBandrbtChild con TsgcReportBand.ChildBandNameTutte
TQRSubDetailUna banda rbtDetailData (DataSourceName = sorgente detail) e MasterSource, MasterFields, DetailFields sul TsgcReportDataSetSource detailTutte
TQRGroup.ExpressionrbtGroupHeader con GroupExpressionTutte
TQRGroup.ReprintOnNewPageTsgcReportBand.RepeatOnEveryPageTutte
TQRGroup.FooterBandLa successiva banda rbtGroupFooter; il primo piè di pagina chiude il gruppo più internoTutte
TQRBand.ForceNewPageTsgcReportBand.StartNewPageTutte
TQRLabel (Caption)Un elemento con Kind = rikText e Text.Text letteraleTutte
TQRDBText (DataField, Mask)rikText con Text.Text = '[Source.Field]'; Mask diventa Text.DisplayFormatTutte
TQRExpr (Expression)rikText con '[expression]', per esempio '[Lines.Qty * Lines.Price]'; funzioni come IIF, FormatFloat, FormatDateTime, Round, UpperTutte
TQRExpr con SUM, COUNT, AVERAGE, MIN, MAX[Sum(x)], [Count()], [Avg(x)], [Min(x)], [Max(x)]; azzeramento per gruppo nei piè di pagina dei gruppi, ambito pagina nei piè di paginaTutte
TQRSysData qrsPageNumber[Page] e [TotalPages] per Pagina X di YTutte
TQRSysData qrsDate, qrsTime, qrsDetailNo[Date], [Time] con Text.DisplayFormat; [Line] o [RecNo]Tutte
TQRShape (qrsRectangle, qrsCircle, qrsRoundRect)rikShape con Shape.ShapeKind rskRectangle, rskEllipse, rskRoundRect; Shape.PenColor, FillColor, PenWidthTutte
TQRShape qrsHorLinerikLine con Height = 0Tutte
TQRImage, TQRDBImagerikImage con Image.FileName o Image.Picture, oppure Image.DataField; Stretch, KeepAspectRatioTutte
TQRRichText, TQRDBRichTextrikRichText con RichText.Markup: markup simile a HTML, non RTF, che può contenere [expressions]Tutte
Enabled impostato in fase di esecuzione, eventi BeforePrintVisibleExpression su bande ed elementi; TsgcReportEngine.OnBeforePrintBandTutte
Prepare, PreviewTsgcReportEngine.Prepare restituisce TsgcReportPreparedPages; TsgcReportPreviewVCL.Prepare le mostra in un controllo sul formTutte
Print, PrinterSetupTsgcReportPreviewVCL.Print(aTitle), dopo un TPrintDialog standardTutte
ExportToFilter con un filtro PDFTsgcReportPDFExport.SaveToFile(aPages, aFileName) o SaveToStreamTutte
PDF/ATsgcReportPDFExport.PDFA = rpaA3b, rpaA3a o rpaA4Tutte
Non elencatoPDF/UA: TsgcReportPDFExport.PDFUA (predefinito True), PDFUAPart, Language, Title; TagRole e AltText dell'elementoTutte
Non elencato (QRDesign era un componente aggiuntivo di terze parti)Designer per l'utente finale: sgcShowReportDesigner, TsgcVCLReportDesigner; sgcShowReportDesignerFMX in FireMonkeyRegistered

Il codice, dalla demo compilata

Ogni estratto è copiato dalla demo MigrateFromQuickReport, che viene compilata con Delphi 7 e Delphi 13 (Win32 e Win64) e nell'edizione Community. I commenti indicano il codice di QuickReport che sostituisce.

TQuickRep diventa un report e un motore

Prima: un TQuickRep sul form, con il report e i suoi dati in un unico componente. Dopo: il layout, il motore e l'anteprima sono componenti separati.

frmMain.dfm
object sgcPreview: TsgcReportPreviewVCL
  Left = 0
  Top = 44
  Width = 900
  Height = 676
  Align = alClient
  TabOrder = 1
  Engine = sgcEngine
end
object sgcReport: TsgcReport
  Left = 40
  Top = 80
end
object sgcEngine: TsgcReportEngine
  Report = sgcReport
  Left = 120
  Top = 80
end

TQuickRep.DataSet e TQRSubDetail diventano sorgenti dati

Prima: TQuickRep.DataSet per le fatture e un TQRSubDetail con un proprio DataSet per le righe. Dopo: una sorgente per dataset, con il detail collegato al master tramite campi. FormCreate registra entrambe con sgcEngine.AddDataSource.

frmMain.dfm
object srcInvoices: TsgcReportDataSetSource
  SourceName = 'Invoices'
  DataSet = cdsInvoices
  Left = 40
  Top = 208
end
object srcLines: TsgcReportDataSetSource
  SourceName = 'Lines'
  MasterSource = srcInvoices
  MasterFields = 'Number'
  DetailFields = 'Invoice'
  DataSet = cdsLines
  Left = 120
  Top = 208
end

Un helper che sostituisce TQRLabel, TQRDBText e TQRExpr

La demo aggiunge ogni testo con questo piccolo metodo del suo form, così gli estratti seguenti restano brevi.

frmMain.pas
function TformMain.AddText(aBand: TsgcReportBand; const aText: string;
  aLeft, aTop, aWidth: Double; const aStyle: string): TsgcReportItem;
var
  oStyle: TsgcReportStyle;
begin
  // one item replaces TQRLabel (literal text), TQRDBText ([Source.Field])
  // and TQRExpr ([expression]); literal text and [expressions] can be mixed
  Result := aBand.Items.Add;
  Result.Kind := rikText;
  Result.Name := aBand.Name + IntToStr(aBand.Items.Count);
  Result.Text.Text := aText;
  Result.Left := aLeft;
  Result.Top := aTop;
  Result.Width := aWidth;
  Result.Height := 14;
  Result.StyleName := aStyle;
  oStyle := sgcReport.Styles.FindStyle(aStyle);
  if Assigned(oStyle) and (oStyle.Font.Size * 1.25 > Result.Height) then
    Result.Height := oStyle.Font.Size * 1.25;
end;

Impostazione della pagina, banda del titolo e TQRSysData

Prima: TQuickRep.Page, una banda del titolo e un TQRSysData con la data. Dopo: TagRole contrassegna il titolo come intestazione nell'albero dei tag PDF/UA.

frmMain.pas
// QuickReport: TQuickRep.Page (PaperSize, LeftMargin, TopMargin, ...)
oPage := sgcReport.Pages.Add;
oPage.Name := 'Invoices';
oPage.PaperSize := rpsA4;
oPage.Margins.Left := 40;
oPage.Margins.Top := 40;
oPage.Margins.Right := 40;
oPage.Margins.Bottom := 40;

// TQRBand BandType = rbTitle: printed once, on the first page
oBand := AddBand(oPage, rbtReportTitle, 'Title', 40);
AddText(oBand, 'Invoices by customer', 0, 0, 350, 'Title').TagRole :=
  rtrHeading1;
AddText(oBand, 'Printed on', 315, 6, 120, 'Right');
// TQRSysData Data = qrsDate
oItem := AddText(oBand, '[Date]', 440, 6, 75, 'Right');
oItem.Text.DisplayFormat := 'yyyy-mm-dd';

TQRGroup, banda di dettaglio e TQRSubDetail

Prima: un TQRGroup sul cliente, una banda di dettaglio di controlli TQRDBText e un TQRSubDetail con un TQRExpr per l'importo della riga. Dopo:

frmMain.pas
// TQRGroup Expression = 'Invoices.Customer', ReprintOnNewPage = True.
// The column titles are TQRLabel components in QuickReport
oBand := AddBand(oPage, rbtGroupHeader, 'CustomerHeader', 42);
oBand.GroupExpression := 'Invoices.Customer';
oBand.RepeatOnEveryPage := True;
AddText(oBand, '[Invoices.Customer]', 0, 4, 515, 'Group').TagRole :=
  rtrHeading2;
AddText(oBand, 'Invoice / product', 0, 24, 200, 'Bold');
AddText(oBand, 'Date / qty', 210, 24, 120, 'Bold');
AddText(oBand, 'Price', 345, 24, 70, 'BoldRight');
AddText(oBand, 'Amount', 425, 24, 90, 'BoldRight');
AddLine(oBand, 40);

// TQRBand BandType = rbDetail: one band per record of TQuickRep.DataSet.
// Each [Source.Field] text item replaces a TQRDBText with DataField set
oBand := AddBand(oPage, rbtMasterData, 'Invoice', 18);
oBand.DataSourceName := 'Invoices';
AddText(oBand, '[Invoices.Number]', 0, 3, 200, 'Bold');
oItem := AddText(oBand, '[Invoices.InvoiceDate]', 210, 3, 120, 'Bold');
oItem.Text.DisplayFormat := 'yyyy-mm-dd';
oItem := AddText(oBand, '[Invoices.Amount]', 425, 3, 90, 'BoldRight');
// TQRDBText.Mask
oItem.Text.DisplayFormat := '#,##0.00';

// TQRSubDetail DataSet = Lines, linked to the invoice: the link is
// MasterSource / MasterFields / DetailFields of srcLines (see the form)
oBand := AddBand(oPage, rbtDetailData, 'Line', 14);
oBand.DataSourceName := 'Lines';
AddText(oBand, '[Lines.Product]', 15, 1, 195);
AddText(oBand, '[Lines.Qty]', 210, 1, 40, 'Right');
oItem := AddText(oBand, '[Lines.Price]', 345, 1, 70, 'Right');
oItem.Text.DisplayFormat := '#,##0.00';
// TQRExpr Expression = 'Lines.Qty * Lines.Price'
oItem := AddText(oBand, '[Lines.Qty * Lines.Price]', 425, 1, 90, 'Right');
oItem.Text.DisplayFormat := '#,##0.00';

Aggregati nel piè di pagina del gruppo

Prima: componenti TQRExpr con COUNT e SUM nella banda del piè di pagina del gruppo. Dopo:

frmMain.pas
// TQRBand BandType = rbGroupFooter (TQRGroup.FooterBand). Aggregates are
// reset for every group, like TQRExpr with ResetAfterPrint = True
oBand := AddBand(oPage, rbtGroupFooter, 'CustomerFooter', 30);
AddLine(oBand, 2);
// TQRExpr Expression = 'COUNT' and 'SUM(Lines.Qty)'
AddText(oBand, '[Count()] invoices, [Sum(Lines.Qty)] items', 0, 8,
  250, 'Bold');
AddText(oBand, 'Customer total', 260, 8, 155, 'BoldRight');
// TQRExpr Expression = 'SUM(Invoices.Amount)'
oItem := AddText(oBand, '[Sum(Invoices.Amount)]', 425, 8, 90, 'BoldRight');
oItem.Text.DisplayFormat := '#,##0.00';

La banda di riepilogo, TQRShape e TQRRichText

Prima: una banda di riepilogo con un TQRShape, totali generali e un TQRRichText. Dopo: il testo ricco è un markup simile a HTML.

frmMain.pas
// TQRBand BandType = rbSummary: printed once, after the last record
oBand := AddBand(oPage, rbtReportSummary, 'Summary', 90);
oBand.KeepTogether := True;
// TQRShape Shape = qrsRectangle, Brush.Color and Pen.Color
oItem := oBand.Items.Add;
oItem.Kind := rikShape;
oItem.Name := 'SummaryBox';
oItem.Top := 10;
oItem.Width := 515;
oItem.Height := 30;
oItem.Shape.ShapeKind := rskRectangle;
oItem.Shape.PenColor := $00A0A0A0;
oItem.Shape.FillColor := $00EEF3FA;
// TQRExpr Expression = 'COUNT' and 'SUM(Invoices.Amount)' in the summary
AddText(oBand, 'Grand total, [Count()] invoices', 10, 17, 300, 'Group');
oItem := AddText(oBand, '[Sum(Invoices.Amount)]', 315, 17, 190,
  'GroupRight');
oItem.Text.DisplayFormat := '#,##0.00';
// TQRRichText: the text is HTML-like markup instead of RTF
oItem := oBand.Items.Add;
oItem.Kind := rikRichText;
oItem.Name := 'SummaryNote';
oItem.Top := 50;
oItem.Width := 515;
oItem.Height := 36;
oItem.StyleName := 'Base';
oItem.RichText.Markup := '<b>Migrated from QuickReport.</b> Each band of ' +
  'this report replaces a <i>TQRBand</i>, each text item a <i>TQRLabel</i>, '
  + '<i>TQRDBText</i> or <i>TQRExpr</i>.';

Piè di pagina con Pagina X di Y

frmMain.pas
// TQRBand BandType = rbPageFooter
oBand := AddBand(oPage, rbtPageFooter, 'PageFooter', 20);
AddLine(oBand, 2);
// TQRLabel with a literal caption
AddText(oBand, 'Invoices by customer', 0, 6, 300);
// TQRSysData Data = qrsPageNumber; [TotalPages] is resolved after the
// last page is laid out
AddText(oBand, 'Page [Page] of [TotalPages]', 315, 6, 200, 'Right');

Anteprima e stampa

Prima: QuickRep1.Preview, PrinterSetup e Print. Dopo:

frmMain.pas
procedure TformMain.btnPreviewClick(Sender: TObject);
begin
  // QuickReport: QuickRep1.Preview (or Prepare + a TQRPreview). sgcReports:
  // the preview control on the form runs the engine and shows the pages
  sgcPreview.Prepare;
  lblStatus.Caption := Format('%d pages prepared', [sgcPreview.PageCount]);
end;

procedure TformMain.btnPrintClick(Sender: TObject);
begin
  // QuickReport: QuickRep1.PrinterSetup + QuickRep1.Print. The print dialog
  // selects the printer, Print sends the prepared pages to it
  if dlgPrint.Execute then
    sgcPreview.Print(sgcReport.Title);
end;

ExportToFilter diventa TsgcReportPDFExport

Prima: ExportToFilter con un filtro PDF. Dopo: un solo interruttore scrive un PDF semplice o un file PDF/UA con tag.

frmMain.pas
procedure TformMain.SavePDF(aPDFUA: Boolean; const aFileName: string);
var
  oPages: TsgcReportPreparedPages;
  vFileName: string;
begin
  // QuickReport: QuickRep1.ExportToFilter(TQRPDFDocumentFilter.Create(...))
  vFileName := ExtractFilePath(ParamStr(0)) + aFileName;
  // PDF/UA: a tagged PDF (headings, reading order, alternate texts); Title
  // and Language are set on pdfExport in the form
  pdfExport.PDFUA := aPDFUA;
  oPages := sgcEngine.Prepare;
  try
    pdfExport.SaveToFile(oPages, vFileName);
  finally
    oPages.Free;
  end;
  lblStatus.Caption := Format('Saved %s (%d warnings)',
    [vFileName, pdfExport.Warnings.Count]);
end;

Otto passaggi per ogni report

I dataset restano come sono. Il report viene ricostruito banda per banda.

1

Sostituisci il TQuickRep

Inserisci un TsgcReport, un TsgcReportEngine (Report = il report) e un TsgcReportPreviewVCL (Engine = il motore) su un normale form.

2

Registra i dati

Aggiungi un TsgcReportDataSetSource per dataset (SourceName, DataSet) e chiama AddDataSource. Per ogni TQRSubDetail imposta MasterSource, MasterFields e DetailFields.

3

Imposta la pagina

Aggiungi un TsgcReportPage con il formato carta e i margini di TQuickRep.Page, e imposta TsgcReport.Units (ruPoints nella demo) in modo che le coordinate siano prevedibili.

4

Ricrea le bande

Un TsgcReportBand per ogni TQRBand, nell'ordine del report, con il tipo di banda rbt corrispondente; DataSourceName sulle bande master e detail, GroupExpression sulle intestazioni di gruppo.

5

Ricrea i controlli

TQRLabel, TQRDBText e TQRExpr diventano elementi rikText che mescolano testo letterale ed [expressions]. Mask diventa Text.DisplayFormat, i font diventano stili con nome.

6

Traduci le espressioni

Gli aggregati diventano [Sum(x)], [Count()], [Avg(x)], [Min(x)] e [Max(x)]; TQRSysData diventa [Page], [TotalPages], [Date] e [Time].

7

Anteprima, stampa, esportazione

Preview diventa TsgcReportPreviewVCL.Prepare, Print diventa Print e il filtro PDF diventa TsgcReportPDFExport.SaveToFile. Imposta PDFUA, Title e Language per un PDF accessibile.

8

Consegnalo ai tuoi utenti

Facoltativo, edizioni Registered: salva il report ricostruito in JSON con TsgcReport.SaveToFile e lascia che gli utenti lo modifichino con sgcShowReportDesigner.

Cosa non si associa uno a uno

Leggi questa sezione prima di pianificare il passaggio.

MigrateFromQuickReport

Un tipico elenco fatture master detail di QuickReport, raggruppato per cliente: 18 fatture di 4 clienti e le loro righe, da due TClientDataSet riempiti nel codice.

Dove si trova

L'installer di sgcUI la copia in Demos\Reports\Delphi\MigrateFromQuickReport: sgcReports_Demo_MigrateFromQuickReport.dpr, frmMain.pas, frmMain.dfm e un readme.html. È presente anche nell'edizione Community.

Come eseguirla

Apri il .dpr in qualsiasi Delphi dal 7 al 13 con sgcReports e sgcPDF installati, compila per Win32 o Win64 ed esegui. Il report viene preparato all'avvio, tre pagine con Pagina X di Y.

Cosa provare

Print... mostra una finestra di stampa e stampa. Save PDF scrive invoices.pdf e Save PDF/UA scrive il file con tag invoices_pdfua.pdf accanto all'exe, pronto per essere controllato con un validatore PDF/UA.

Per essere onesti con entrambi i motori: QuickReport è di nuovo in manutenzione, supporta Delphi dalla versione 7 e i suoi report si progettano nel designer dei form di Delphi. La sua pagina delle funzioni elenca filtri di esportazione, come XML/XSLT, che sgcReports non ha, e mantenerlo significa che nessun report deve essere ricostruito. sgcReports è la strada giusta quando ti serve un output PDF/UA accessibile, un designer per i tuoi utenti, report condivisi con sgcCharts, sgcPivotGrid o un servizio .NET, e accetti di ricostruire ogni report una sola volta. Per l'elenco completo delle funzioni vedi la pagina del prodotto sgcReports.

La scelta più conveniente: All-AccessTutti i prodotti eSeGeCe, con Supporto Premium incluso, a partire da €1,059/anno.
Vedi i prezzi All-Access

Ricostruisci oggi il tuo primo report

Scarica la versione di prova di sgcUI con sgcReports e la demo MigrateFromQuickReport, e porta il tuo primo report.