2

Printer.Printers文字列リストにアクセスすると、選択したプリンターにQuickReportレポートを送信すると、「リストインデックスが範囲外です」などのエラーが発生します。

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

エラーが発生する直前にプリンターのリスト(Printer.Printers)が変更されたことを示すログを追加しました。ネットワークプリンタがオフになっている場合、ネットワークがダウンしている場合、およびその他の理由で、プリンタのリストが変更される可能性があると思います。

この状況に対処する方法は?Delphiでは、選択されたプリンタはPrinter.PrinterIndexによって指定されますが、プリンタのリストが変更されると、このインデックスは無効になります。

私は、すべての印刷の前にプリンタの選択ダイアログを表示する、つまり、Printer.PrinterIndexが1つの印刷ジョブから次の印刷ジョブまで正しいことに依存しないという1つの解決策しか考えられません。しかし、それはユーザーにとって非常に迷惑になる可能性があります。

理想的には、選択したプリンターをGUIDまたは名前で保存する必要があります。それはそれをより信頼できるものにするでしょう。

このフォーラムとエンバカデロフォーラムを検索しましたが、この種の問題についての言及は見つかりませんでした。それで、私が見落としていた単純な何かがここにあるのでしょうか?

Delphi2007とQuickReport5を使用しています。

4

1 に答える 1

1

OnBeforePrint必要に応じてプリンター名を保存し、イベント ハンドラーまたはレポートのコンストラクターに割り当てることができます。ハードコーディングしたくない場合は、レジストリまたは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;
于 2012-07-31T12:24:38.077 に答える