Error de índice de lista fuera de los límites al imprimir el informe QR

Recibo errores como "Lista de índice fuera de los límites" cuando envío un informe QuickReport a la impresora seleccionada cuando se accede a la lista de cadenas Printer.Printers.

exception class   : EStringListError
exception message : List index out of bounds (6).

main thread ($1594c):
00479559 skdata.exe   Classes   5060 TStringList.GetObject
004a258b skdata.exe   Printers   581 TPrinter.GetPrinter
007ca744 skdata.exe   QRPrntr   3208 TPrinterSettings.ApplySettings
007cb5bb skdata.exe   QRPrntr   3995 TQRPrinter.BeginDoc
007be227 skdata.exe   QuickRpt  4645 TCustomQuickRep.CreateReport
007be909 skdata.exe   QuickRpt  4853 TCustomQuickRep.Print
00859bc7 skdata.exe   PostLst    142 TPostSpecListReport.Print

Agregué un registro que muestra que la lista de impresoras (Printer.Printers) cambió justo antes de que ocurriera el error. Supongo que la lista de impresoras puede cambiar si una impresora de red está apagada, si la red no funciona y también por otras razones.

¿Cómo manejar esta situación? En Delphi, la impresora seleccionada viene dada por Printer.PrinterIndex, pero si se cambia la lista de impresoras, este índice ya no es válido.

Solo puedo pensar en una solución que es presentar el cuadro de diálogo de selección de impresora antes de cada impresión, en otras palabras, no confiar en que Printer.PrinterIndex sea correcto de un trabajo de impresión al siguiente. Pero eso podría ser bastante molesto para el usuario.

Lo ideal es que la impresora seleccionada se almacene como un GUID o por nombre. Eso lo haría más confiable.

He buscado en este foro, así como en el foro de Embarcadero, pero no he encontrado ninguna mención a este tipo de problema. Entonces, ¿tal vez hay algo simple aquí que he pasado por alto?

Yo uso Delphi 2007 y QuickReport 5.

preguntado el 31 de julio de 12 a las 13:07

1 Respuestas

Puede almacenar el nombre de la impresora, si lo desea, y asignarlo en el OnBeforePrint controlador de eventos o en el constructor del informe. Si no desea codificarlo, guárdelo en el registro o en un archivo ini.

type
  TMyForm = class(TForm)
  ....
  private
    FPrinterName: string;
  published
    ....
  end;

implementation

uses
  Printers;

procedure TMyForm.FormCreate(Sender: TObject);
begin
  // Set, or read from registry or ini file
  FPrinterName := 'My LaserJet Printer';
end;

procedure TMyForm.PrintReportButtonClick(Sender: Object);
begin
  // Create report and set up. Select stored printer, or set to default
  // printer if none is stored
  QuickRep1.PrinterSettings.PrinterIndex := Printers.IndexOf(FPrinterName);
  QuickRep1.Print;
  // Clean up - free report, etc.
end;

Respondido 31 Jul 12, 13:07

¿Qué pasaría si esa impresora hubiera sido eliminada? Supongo Printers.IndexOf(FPrinterName) devolver -1? ¿Y eso conduciría a que se utilice la impresora predeterminada? - David Heffernan

Sí. Si la impresora se eliminó antes de la llamada a IndexOf, la llamada devuelve -1, lo que significa "usar la impresora predeterminada" (desde que Delphi 1 introdujo TPrinter). Si la impresora se elimina durante el breve período de tiempo entre la configuración del índice de la impresora y la impresión real del informe, puede mover la asignación a un lugar más cercano al proceso de impresión real (como QuickRep1BeforePrint), o romperle las piernas a la persona que sigue borrando tu impresora. :-)- Ken White

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.