2012-07-31 153 views
2

當訪問Printer.Printers字符串列表時,如果發送QuickReport報告到選定的打印機時,出現「列表索引超出範圍」等錯誤。打印QR報告時列表索引超出範圍錯誤

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給出,但如果打印機列表發生更改,則此索引不再有效。

我只能想到一種解決方案,即在每次打印之前顯示select-printer對話框,換句話說,不要依賴Printer.PrinterIndex從一個打印作業到下一個打印作業。但是這對用戶來說可能很煩人。

理想情況下,選定的打印機應該作爲GUID或按名稱存儲。這會使它更可靠。

我搜索了這個論壇以及Embarcadero論壇,但沒有發現任何提及這類問題。所以也許這裏有一些我忽略的簡單東西?

我用Delphi 2007和QuickReport 5

回答

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; 
+0

如果該打印機已被刪除會發生什麼?我猜'Printers.IndexOf(FPrinterName)'返回-1?那會導致正在使用的默認打印機? – 2012-07-31 12:40:30

+3

是的。如果打印機在調用「IndexOf」之前被刪除,則調用返回-1,這意味着「使用默認打印機」(因爲Delphi 1引入了「TPrinter」)。如果在設置打印機索引和實際打印報告之間的短時間內刪除打印機,則可以將分配移動到更接近實際打印過程的某個位置(如「QuickRep1BeforePrint」),或者斷開保存人員的腿刪除您的打印機。 :-) – 2012-07-31 12:43:31