Newsgroup: it.comp.lang.visual-basic
Titolo: (Semi OT?) Problema di gestione spooling stampante.


Non vorrei essere prolisso ma cerco di darvi tutte le indicazioni.
Il problema (che probabilmente non c'entra niente con quanto detto sopra) 
e' che mi perdo le stampe!. Ovvero sulla classica getto tutto funzia 
mentre sulla laser no. In pratica succede che alcune stampe vengono 
bellamente ignorate, tipo il PrintReport di cui sopra sta in un ciclo 
relativo al numero delle copie e sulla laser viene stampata solo la 
prima, mentre altre stampe prendono sequenze diverse dal flusso del 
programma (esce magari prima il riepilogo fatture e poi la fattura anche 
se il programma le ha inviate nella giusta sequenza).
Dimenticavo di dire che in Debug tutto funziona correttamente!.
Ho provato tutte le combinazioni dei parametri dello spooler ed i driver 
+ recenti delle stampanti.
Non vorrei essere costretto a temporizzare le stampe per dare tempo allo 
spooler di 'digerire'!.
Accetto qualsiasi suggerimento.
Grazie e saluti
Paolo

 fattura anche se il programma le ha inviate nella giusta sequenza).
Il DataReport è asincrono.
Quindi, prima di ristampare un report devi accertarti che la stampa
precedente sia già stata inviata allo spooler.
DataReport offre una serie di eventi per intercettare le variazioni di stato
del processo asincrono.
Quindi, non puoi controllare più di tanto la tempistica con cui le stampe
del datareport vanno allo spooler, per cui quelle fatte col printer possono
incastrarsi qua e là.
A meno che, appunto, tu non gestisca gli eventi asincroni del datareport.
E, questo, fino a quello che tu puoi gestire.
Oltre a questo, considera che nella gestione dello spooler di windows non è
garantita la sequenzialità.
Ossia, se ad esempio una stampa per qualche motivo non parte, o nel mondo NT
anche in base a impostazioni personalizzate, o, in alcuni spooler molto
recenti che cercano di ottimizzare gli sfridi, se l'ordine viene volutamente
modificato dallo spooler, tu non puoi farci niente.
Ad esempio, qui abbiamo una HP8000 (mi sembra...), che di default sospende
ogni stampa per x secondi, e se nel frattempo arrivano altre stampe, e
queste richiedono tipi di carta più piccoli di quello installato, le ruota e
le sistema in modo da stampare contemporaneamente su un unico foglio anche
più pagine (che poi andranno rifilate).
Ciao
Alberto
-- 
Rigore è quando arbitro fischia

 A meno che, appunto, tu non gestisca gli eventi asincroni del datareport.
Ok, allora guardero' la gestione delle proprieta' relative sul DataReport  
( e sull'oggetto Print) per determinare quando lo spooler sia in grado di 
accodare ancora.
Pero' mi pare quantomeno strano che le stampe vengano proprio 'perse' in 
quanto a parte degli EndDoc non mi pare di effettuare nessuna operazione 
per svuotare lo spool e questo non dovrebbre mai farlo da solo; dovrebbe 
semmai comunicare lo stato di spool pieno.
Ciao.
Paolo

 dovrebbe semmai comunicare lo stato di spool pieno.
Il discorso è a monte dello spooler.
Guarda che anche in altri applicativi (prendi ad esempio Word), se tu
invochi una stampa mentre lui sta ancora 'spoolando', la nuova richiesta può
essere ignorata.


 
Comunque adesso provando gli eventi:
DataReport_ProcessingTimeout
DataReport_AsyncProgress
Ciao 
Paolo. 

 DataReport_AsyncProgress
Quest'ultimo è quello che conta.
Del resto, anche per chiudere l'applicativo devi verificare che la stampa
asincrona sia terminata, altrimenti l'Unload del datareport fallisce e ti
resta appeso un processo.


 
Per chi interessa credo di aver risolto con il seguente codice:
<CODICE>
sCurrentPage = 0	'variabili pubbliche
sTotalPages = 1
 
RptFattura.PrintReport False, rptRangeFromTo, 1, 1  'stampa solo la pag.1
 
'****
'test di stampa completata.
vStart = Now() 'ciclo per il timeout
Do While gCurrentPage < gTotalPages
    If DateDiff("s", vStart, Now()) > 120 Then
        Exit Do
    End If
 
    DoEvents
Loop
'***
 
Unload RptFattura
'-------
Private Sub DataReport_AsyncProgress(ByVal JobType As 
MSDataReportLib.AsyncTypeConstants, ByVal Cookie As Long, ByVal 
PageCompleted As Long, ByVal TotalPages As Long)
On Error Resume Next
If JobType = rptAsyncPrint Then
    gCurrentPage = PageCompleted
    gTotalPages = TotalPages
End If
End Sub
</CODICE>
In questo modo mi vanno nel corretto ordine anche le stampe intercalate 
fatte con la print.
In pratica attende che la variabile che contiene il numero della pagina 
corrente sia = a quella che indica le pagine totali.
Non si puo' dire che sia la soluzione + elegante (anzi mi pare proprio 
strano che non esista una proprieta' apposita per fare cio') pero' domani 
consegno ;).
Ciao
Paolo.