Migra de QuickReport a sgcReports

sgcReports es el motor de informes por bandas de sgcUI: TsgcReport guarda el diseño, TsgcReportEngine enlaza los datos, TsgcReportPreviewVCL muestra las páginas y la exportación a PDF escribe PDF/UA etiquetado. Este kit relaciona las bandas y los controles de QuickReport que usas con sus gemelos de sgcReports, muestra el código de una demo compilada y enumera con honestidad lo que no se corresponde.

Informes Delphi VCL creados con QuickReport

Un TQuickRep en un formulario, bandas, controles QR en las bandas y un botón de vista previa, impresión o PDF en la aplicación.

QuickReport vuelve a tener mantenimiento. En "QuickReport is back" (blog de Embarcadero, Ian Barker, 14 de noviembre de 2024) Embarcadero explica que el producto entró en crisis cuando falleció su desarrollador principal, que volvió gracias al socio de Embarcadero Barnsten, y que ahora admite todas las versiones de RAD Studio con Delphi y C++Builder desde Delphi 7. La página de QuickReport de Barnsten (consultada el 2026-10-20) enumera un filtro PDF con fuentes TrueType incrustadas, compatibilidad con PDF/A y filtros de exportación a HTML, XML/XSLT, XLS y XLSX, y pone a QuickReport Pro 5-developer un precio de 2.155,00 EUR sin IVA. Así que esta página no trata de un producto muerto ni de un botón de PDF que falta. Es para los equipos que quieren lo que esa lista de funciones no menciona.

Lo que añade sgcReports

Cada afirmación sobre sgcReports de abajo está en el código fuente distribuido. En el lado de QuickReport, "no figura" significa que la página del fabricante no lo menciona, no que no sea compatible.

PDF/UA accesible

TsgcReportPDFExport escribe PDF/UA etiquetado por defecto (PDFUA es True, PDFUAPart elige la parte 1 o 2), con orden de lectura, roles de encabezado a partir de TagRole del elemento, textos alternativos desde AltText, y el Language y el Title del documento. PDFA añade PDF/A-3b, PDF/A-3a o PDF/A-4 para archivo. Está en todas las ediciones, Community incluida. PDF/UA y el PDF etiquetado no figuran en la página de funciones de Barnsten. Los documentos accesibles importan más desde la Ley Europea de Accesibilidad, Directiva (UE) 2019/882, que abarca productos y servicios como los libros electrónicos, el comercio electrónico y los servicios bancarios.

Un diseñador para el usuario final, VCL y FireMonkey

Tus usuarios pueden cambiar un informe sin una nueva compilación: sgcShowReportDesigner(Engine) abre el diseñador VCL, o incrusta el panel TsgcVCLReportDesigner; sgcShowReportDesignerFMX(Engine) hace lo mismo en FireMonkey (Delphi XE6 y posteriores, escritorio). El diseñador VCL sigue los cambios de DPI del formulario (su inspector, sus iconos y su superficie de diseño se reescalan en ChangeScale). Solo en las ediciones Registered. La página de funciones de Barnsten no menciona un diseñador para el usuario final; históricamente era un producto de terceros aparte, QRDesign. Sobre High DPI, una respuesta en Delphi-PRAXiS del 4 de abril de 2022 decía que QuickReport 6 compila con Delphi 11.1 pero no admite High-DPI; consulta la versión actual con el fabricante.

Un motor para toda la suite

Las tablas cruzadas, los códigos de barras, los subinformes y el texto enriquecido son tipos de elemento del mismo motor de bandas. Con las unidades puente, un informe también imprime como elementos una gráfica de sgcCharts y una tabla dinámica de sgcPivotGrid, dibujadas como contenido vectorial en el PDF (ediciones Registered). Exportaciones: PDF, XLSX, CSV, HTML y PNG en todas las ediciones, DOCX en las ediciones Registered.

Definiciones JSON y una contraparte .NET

Un informe se guarda y se carga en JSON (TsgcReport.SaveToFile, LoadFromFile), de modo que los diseños pueden vivir en una base de datos o bajo control de versiones. La misma definición se carga en sgcReports para .NET (NuGet esegece.sgcReports, .NET Standard 2.0, .NET Framework 4.7.2 y .NET 6 y posteriores), así que un informe Delphi puede reutilizarlo un servicio .NET.

Los informes se reconstruyen, no se importan. sgcReports no puede abrir un .dfm de QuickReport: no existe un importador de QuickReport. Cada informe se recrea, en código como hace la demo de abajo, o en el diseñador de sgcReports (ediciones Registered). La correspondencia y los pasos de esta página convierten eso en un trabajo mecánico, banda a banda. sgcReports se licencia por desarrollador desde €199 con el código fuente completo y un año de actualizaciones, y además forma parte de sgcUI.

Clases de QuickReport y sus equivalentes en sgcReports

Cada nombre de sgcReports de abajo está en el código fuente distribuido, y los que usa la demo compilan en ella. Los nombres de QuickReport se indican como orientación; QuickReport no estaba instalado cuando se comprobó esta página.

QuickReport sgcReports Edición
TQuickRepTsgcReport (Pages, Styles, Units, Title) y TsgcReportEngine (Report, AddDataSource, Prepare, Variables, OnGetVariable)Todas
TQuickRep.DataSetTsgcReportDataSetSource (SourceName, DataSet) registrado con AddDataSource; el DataSourceName de la banda lo nombraTodas
TQuickRep.Page (papel, márgenes)TsgcReportPage.PaperSize (rpsA3, rpsA4, rpsA5, rpsLetter, rpsLegal, rpsCustom), Margins.Left, Top, Right, BottomTodas
TQuickRep.ReportTitleTsgcReport.Title, y TsgcReportPDFExport.Title para los metadatos del PDFTodas
TQRBand con BandType rbTitle, rbPageHeader, rbColumnHeaderTsgcReportBand con BandType rbtReportTitle, rbtPageHeader, rbtColumnHeaderTodas
rbDetailrbtMasterData con DataSourceName establecido en el origen maestroTodas
rbGroupHeader, rbGroupFooterrbtGroupHeader, rbtGroupFooterTodas
rbSummary, rbPageFooterrbtReportSummary, rbtPageFooterTodas
TQRChildBandrbtChild con TsgcReportBand.ChildBandNameTodas
TQRSubDetailUna banda rbtDetailData (DataSourceName = origen de detalle) y MasterSource, MasterFields, DetailFields en el TsgcReportDataSetSource de detalleTodas
TQRGroup.ExpressionrbtGroupHeader con GroupExpressionTodas
TQRGroup.ReprintOnNewPageTsgcReportBand.RepeatOnEveryPageTodas
TQRGroup.FooterBandLa siguiente banda rbtGroupFooter; el primer pie cierra el grupo más internoTodas
TQRBand.ForceNewPageTsgcReportBand.StartNewPageTodas
TQRLabel (Caption)Un elemento con Kind = rikText y Text.Text literalTodas
TQRDBText (DataField, Mask)rikText con Text.Text = '[Source.Field]'; Mask pasa a Text.DisplayFormatTodas
TQRExpr (Expression)rikText con '[expression]', por ejemplo '[Lines.Qty * Lines.Price]'; funciones como IIF, FormatFloat, FormatDateTime, Round, UpperTodas
TQRExpr con SUM, COUNT, AVERAGE, MIN, MAX[Sum(x)], [Count()], [Avg(x)], [Min(x)], [Max(x)]; se reinician por grupo en los pies de grupo, con ámbito de página en los pies de páginaTodas
TQRSysData qrsPageNumber[Page], y [TotalPages] para Página X de YTodas
TQRSysData qrsDate, qrsTime, qrsDetailNo[Date], [Time] con Text.DisplayFormat; [Line] o [RecNo]Todas
TQRShape (qrsRectangle, qrsCircle, qrsRoundRect)rikShape con Shape.ShapeKind rskRectangle, rskEllipse, rskRoundRect; Shape.PenColor, FillColor, PenWidthTodas
TQRShape qrsHorLinerikLine con Height = 0Todas
TQRImage, TQRDBImagerikImage con Image.FileName o Image.Picture, o Image.DataField; Stretch, KeepAspectRatioTodas
TQRRichText, TQRDBRichTextrikRichText con RichText.Markup: marcado de tipo HTML, no RTF, que puede contener [expressions]Todas
Enabled establecido en tiempo de ejecución, eventos BeforePrintVisibleExpression en bandas y elementos; TsgcReportEngine.OnBeforePrintBandTodas
Prepare, PreviewTsgcReportEngine.Prepare devuelve TsgcReportPreparedPages; TsgcReportPreviewVCL.Prepare las muestra en un control del formularioTodas
Print, PrinterSetupTsgcReportPreviewVCL.Print(aTitle), después de un TPrintDialog estándarTodas
ExportToFilter con un filtro PDFTsgcReportPDFExport.SaveToFile(aPages, aFileName) o SaveToStreamTodas
PDF/ATsgcReportPDFExport.PDFA = rpaA3b, rpaA3a o rpaA4Todas
No figuraPDF/UA: TsgcReportPDFExport.PDFUA (por defecto True), PDFUAPart, Language, Title; TagRole y AltText del elementoTodas
No figura (QRDesign era un complemento de terceros)Diseñador para el usuario final: sgcShowReportDesigner, TsgcVCLReportDesigner; sgcShowReportDesignerFMX en FireMonkeyRegistered

El código, de la demo compilada

Cada fragmento está copiado de la demo MigrateFromQuickReport, que compila con Delphi 7 y Delphi 13 (Win32 y Win64) y en la edición Community. Los comentarios nombran el código de QuickReport que sustituye.

TQuickRep pasa a ser un informe y un motor

Antes: un TQuickRep en el formulario, con el informe y sus datos en un solo componente. Después: el diseño, el motor y la vista previa son componentes separados.

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 y TQRSubDetail pasan a ser orígenes de datos

Antes: TQuickRep.DataSet para las facturas y un TQRSubDetail con su propio DataSet para las líneas. Después: un origen por dataset, con el detalle enlazado al maestro por campos. FormCreate registra ambos 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 método auxiliar que sustituye a TQRLabel, TQRDBText y TQRExpr

La demo añade cada texto con este pequeño método de su formulario, para que los fragmentos de abajo sean cortos.

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;

Configuración de página, la banda de título y TQRSysData

Antes: TQuickRep.Page, una banda de título y un TQRSysData con la fecha. Después: TagRole marca el título como encabezado en el árbol de etiquetas de 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, la banda de detalle y TQRSubDetail

Antes: un TQRGroup por cliente, una banda de detalle de controles TQRDBText, y un TQRSubDetail con un TQRExpr para el importe de la línea. Después:

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';

Agregados del pie de grupo

Antes: componentes TQRExpr con COUNT y SUM en la banda de pie de grupo. Después:

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 de resumen, TQRShape y TQRRichText

Antes: una banda de resumen con un TQRShape, totales generales y un TQRRichText. Después: el texto enriquecido es marcado de tipo 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>.';

Pie de página con Página X de 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');

Vista previa e impresión

Antes: QuickRep1.Preview, PrinterSetup y Print. Después:

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 pasa a ser TsgcReportPDFExport

Antes: ExportToFilter con un filtro PDF. Después: un interruptor escribe un PDF normal o un archivo PDF/UA etiquetado.

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;

Ocho pasos por informe

Los datasets se quedan como están. El informe se reconstruye banda a banda.

1

Sustituye el TQuickRep

Coloca un TsgcReport, un TsgcReportEngine (Report = el informe) y un TsgcReportPreviewVCL (Engine = el motor) en un formulario normal.

2

Registra los datos

Añade un TsgcReportDataSetSource por dataset (SourceName, DataSet) y llama a AddDataSource. Para cada TQRSubDetail establece MasterSource, MasterFields y DetailFields.

3

Configura la página

Añade un TsgcReportPage con el tamaño de papel y los márgenes de TQuickRep.Page, y establece TsgcReport.Units (ruPoints en la demo) para que las coordenadas sean predecibles.

4

Recrea las bandas

Un TsgcReportBand por cada TQRBand, en el orden del informe, con el tipo de banda rbt equivalente; DataSourceName en las bandas maestra y de detalle, GroupExpression en los encabezados de grupo.

5

Recrea los controles

TQRLabel, TQRDBText y TQRExpr pasan a ser elementos rikText que mezclan texto literal y [expressions]. Mask pasa a Text.DisplayFormat, y las fuentes pasan a estilos con nombre.

6

Traduce las expresiones

Los agregados pasan a [Sum(x)], [Count()], [Avg(x)], [Min(x)] y [Max(x)]; TQRSysData pasa a [Page], [TotalPages], [Date] y [Time].

7

Vista previa, impresión, exportación

Preview pasa a TsgcReportPreviewVCL.Prepare, Print pasa a Print, y el filtro PDF pasa a TsgcReportPDFExport.SaveToFile. Establece PDFUA, Title y Language para un PDF accesible.

8

Entrégalo a tus usuarios

Opcional, ediciones Registered: guarda el informe reconstruido como JSON con TsgcReport.SaveToFile y deja que los usuarios lo editen con sgcShowReportDesigner.

Lo que no se corresponde uno a uno

Léelo antes de planificar el cambio.

MigrateFromQuickReport

Un listado típico de facturas maestro detalle de QuickReport, agrupado por cliente: 18 facturas de 4 clientes y sus líneas, a partir de dos TClientDataSet rellenados en código.

Dónde está

El instalador de sgcUI la deja en Demos\Reports\Delphi\MigrateFromQuickReport: sgcReports_Demo_MigrateFromQuickReport.dpr, frmMain.pas, frmMain.dfm y un readme.html. También está en la edición Community.

Cómo ejecutarla

Abre el .dpr en cualquier Delphi de la 7 a la 13 con sgcReports y sgcPDF instalados, compila para Win32 o Win64 y ejecuta. El informe se prepara al iniciar, tres páginas con Página X de Y.

Qué probar

Print... muestra un diálogo de impresión e imprime. Save PDF escribe invoices.pdf y Save PDF/UA escribe el invoices_pdfua.pdf etiquetado junto al exe, listo para comprobarlo con un validador de PDF/UA.

Para ser justos con ambos motores: QuickReport vuelve a tener mantenimiento, admite Delphi 7 en adelante, y sus informes se diseñan en el diseñador de formularios de Delphi. Su página de funciones enumera filtros de exportación, como XML/XSLT, que sgcReports no tiene, y conservarlo significa que no hay que reconstruir ningún informe. sgcReports es el camino cuando necesitas una salida PDF/UA accesible, un diseñador para tus usuarios, informes compartidos con sgcCharts, sgcPivotGrid o un servicio .NET, y aceptas reconstruir cada informe una vez. Para la lista completa de funciones consulta la página del producto sgcReports.

La mejor opción: All-AccessTodos los productos de eSeGeCe, con Premium Support incluido, desde €1,059 al año.
Ver precios de All-Access

Reconstruye hoy tu primer informe

Descarga la prueba de sgcUI con sgcReports y la demo MigrateFromQuickReport, y migra tu primer informe.