PC SOFT

GRUPOS DE DISCUSSÃO PROFISSIONAL
WINDEVWEBDEV e WINDEV Mobile

Inicio → WINDEV 2025 → Comment assurer que le document s'est bien imprimé
Comment assurer que le document s'est bien imprimé
Iniciado por NotreFaq2109, fev., 05 2024 11:51 AM - 10 respostas
Publicado em fevereiro, 05 2024 - 11:51 AM
Bonjour

Je veux savoir si la facture a été correctement imprimée ou non , pour affecter la valeur 1 dans la rubrique EstImprimé (voir mon code)
iInitRequêteEtat(MonEtat,IDDoc)
iImprimeEtat(MonEta)

SI HLitRecherchePremier(DOCUMENTS,IDDoc,Col_IdDoc) =Vrai ALORS
DOCUMENTS.EstImprime=1
SI PAS HModifie(DOCUMENTS) ALORS
Info(HErreurInfo(hErrComplet))
FIN
FIN


Parfois cette rubrique prend la valeur 1 sans que l'imprimante n'imprime le document.

Comment puis-je m'assurer que le document s'imprime correctement ?
Je souhaite en cas d'une erreur d'impression survient (arrêt de l'imprimante, message d'encre, réseau, etc.) la rubrique EstImprime ne prend pas la valeur 1, c'est à dire que l'utilisateur doit relancer l'impression à partir de ce document non imprimé.

Merci de vos retours
Membro registado
1.046 mensagems
Publicado em fevereiro, 06 2024 - 1:14 AM
Bonsoir,
vous affectez 1 si "HLitRecherchePremier" est "vrai" mais ceci n'a aucun rapport avec le fait que le document ait été imprimé.

Allez voir la doc de :
iImprimeEtat (Fonction)
https://doc.pcsoft.fr/?3046032
Extrait :
Syntaxe
 = iImprimeEtat( [,  [... [, ]]])
 : Type du résultat retourné par l'état (optionnel)
Valeur renvoyée par l'état lors de son impression. Cette valeur est renvoyée :
soit par le mot-clé RENVOYER présent dans le code de fermeture de l'état.
soit par la propriété ValeurRevoyée utilisée avant la fermeture de l'état.

Cdlt
Publicado em fevereiro, 06 2024 - 6:22 AM
Merci Cédric_34

Dans la fermeture de MonEtat, je met ce code
RENVOYER IDDoc // je revoie la valeur de l'ID


Dans mon code je modifie et j'écris ça
iInitRequêteEtat(MonEtat,IDDoc)
nRésultat=iImprimeEtat(MonEta)

SI nRésultat>0 ALORS
FDocs.EstImprime=Vrai
SI PAS FDocs.Modifie() ALORS
Info(" Pas de modification "+HErreurInfo(hErrComplet))
FIN
FIN


Est-ce vraiment le bon contrôle ?
Membro registado
371 mensagems
Publicado em fevereiro, 06 2024 - 1:03 PM
Bonjour

iImpressiondemande et imprime te permettront de savoir si ça a été envoyé à l imprimante
Membro registado
151 mensagems
Publicado em fevereiro, 06 2024 - 1:11 PM
comme le dit GB tu peux au mieux savoir si l'imprimante ou le spool à reçu ta demande d'impression mais savoir que l'impression s'est effectué correctement, je ne penses pas vu que c'est le système qui à la main sur l'impression et non pas ton application.

Peux être en utilisant un spooler et en connaissant des fonctions d'interrogation du spooler mais là je ne connais pas
Publicado em fevereiro, 08 2024 - 2:38 PM
Bonjour

iImpressionDemandée()
Attention : Cette fonction ne permet pas de savoir si l'impression s'est bien passée. En cas de problème physique de l'imprimante, la fonction renverra toujours le même résultat.

Donc iImpressionDemandée ne donne pas le résultat souhaité


Jusqu'à présent je ne trouve plus comment savoir si l'impression s'est bien passée ou non ?
Membro registado
182 mensagems
Publicado em fevereiro, 08 2024 - 3:25 PM
Hello
C'est jouable, j'avais trouvé la solution sur le forum il y a un moment, dont voici le lien exact :
https://forum.pcsoft.fr/fr-FR/pcsoft.fr.windev/22000-wd90033t-recuperer-contenu-spool-impression-22015/read.awp

J'ai arrangé le code de la sorte :
- Déclaration d'une collection de procédures ("Check_API" dans mon cas
- J'ai mis ce qui suit dans la déclaration de la collection :

CONSTANTE
JOB_STATUS_READY = 0x00000000
JOB_STATUS_PAUSED = 0x00000001 // Job is paused.
JOB_STATUS_ERROR = 0x00000002 // An error is associated with the job.
JOB_STATUS_DELETING = 0x00000004 // Job is being deleted.
JOB_STATUS_SPOOLING = 0x00000008 // Job is spooling.
JOB_STATUS_PRINTING = 0x00000010 // Job is printing.
JOB_STATUS_OFFLINE = 0x00000020 // Printer is offline.
JOB_STATUS_PAPEROUT = 0x00000040 // Printer is out of paper.
JOB_STATUS_PRINTED = 0x00000080 // Job has printed.
JOB_STATUS_DELETED = 0x00000100 // Job has been deleted.
JOB_STATUS_BLOCKED_DEVQ = 0x00000200 // The driver cannot print the job.
JOB_STATUS_USER_INTERVENTION = 0x00000400 // Printer has an error that requires the user to do something.
JOB_STATUS_RESTART = 0x00000800 // Job has been restarted.
JOB_STATUS_COMPLETE = 0x00001000 // Windows XP: Job is sent to the printer, but the job may not be printed yet. See Remarks for more information.
FIN

_SYSTEM_TIME est une structure
wYear est un entier sans signe sur 2 octets
wMonth est un entier sans signe sur 2 octets // 1 = January
wDayOfWeek est un entier sans signe sur 2 octets // 0 = Sunday
wDay est un entier sans signe sur 2 octets
wHour est un entier sans signe sur 2 octets
wMinute est un entier sans signe sur 2 octets
wSecond est un entier sans signe sur 2 octets
wMilliseconds est un entier sans signe sur 2 octets
FIN

_JOB_INFO_1 est une structure
JobId est un entier // Job id
pPrinterName est un entier // Pointer Name of the printer for which the job is spooled
pMachineName est un entier // Pointer Name of the machine that created the print job
pUserName est un entier // Pointer Name of the user who owns the print job
pDocument est un entier système // Pointer Name of the print job
pDatatype est un entier // Pointer Type of data used to record the print job
pStatus est un entier // Pointer to a null-terminated string that specifies the status of the print job
Status est un entier // Specifies the job status
Priority est un entier // Specifies the job priority
Positi est un entier // Specifies the job's position in the print queue
TotalPages est un entier // Specifies how many pages the document contains
PagesPrinted est un entier // Specifies the number of pages that have printed
Submitted est une _SYSTEM_TIME // A SYSTEMTIME structure that specifies the time that this document was spooled
FIN

- Et enfin, une procédure globale intitulée "Report_Printed" :

Procedure Report_Printed(Report_File est une chaîne)

// init vars
API_Result est un entier système

hdPrint, pcReturned, pcbNeeded sont des entiers
prName est une chaîne ASCIIZ sur 512 = iInfoImprimante

i est un entier

Job est un _JOB_INFO_1
Jobs est un tableau dynamiquedynamique de 0 _JOB_INFO_1

// open printer handle
API_Result = API("winspool.drv", "OpenPrinterA" , &prName, &hdPrint, Null)
IF API_Result = 0 THEN
RENVOYER Faux
END

// check "EnumJobsA" a first time to get bytes total we need
API_Result = API("winspool.drv", "EnumJobsA", hdPrint, 0, 1000, 1, Null, 0, &pcbNeeded, &pcReturned)

// resize array
Dimension(Jobs, PartieEntière(pcbNeeded / Dimension(Job)) + 1)

// check a second time to get total jobs
API_Result = API("winspool.drv", "EnumJobsA", hdPrint, 0, 1000, 1, &Jobs, pcbNeeded, &pcbNeeded, &pcReturned)
SI API_Result = 0 ALORS
API("winspool.drv", "ClosePrinter", hdPrint)
RENVOYER Faux
FIN

// just do it!
SELON pcReturned
CAS 0
API("winspool.drv", "ClosePrinter", hdPrint)

AUTRE CAS
POUR i = 1 _À_ pcReturned
QUAND EXCEPTIONEXCEPTION DANS
// we consider this job has been printed if its status does not correpsond to these values
SI PAS Jobs[i]:Status DANS (JOB_STATUS_READY, JOB_STATUS_PAUSED, JOB_STATUS_ERROR, JOB_STATUS_DELETING, JOB_STATUS_SPOOLING, JOB_STATUS_PRINTING, JOB_STATUS_OFFLINE, JOB_STATUS_PAPEROUT, JOB_STATUS_DELETED, JOB_STATUS_BLOCKED_DEVQ, JOB_STATUS_USER_INTERVENTION) ALORS
SI ChaîneRécupère(Jobs[i]:pDocument, crAdresseASCIIZ) = Report_File ALORS
API("winspool.drv", "ClosePrinter" , hdPrint)

RENVOYER Vrai
FIN
FIN
FAIRE
SORTIR
FIN
FIN
FIN

RENVOYER Faux

Il faudra peut-être adapter quelques parties (le code est issu d'un projet en version 23).
Comme c'est un projet sur lequel je ne travaille plus, il y a sûrement aussi moyen d'améliorer certaines parties.

Pour vérifier ensuite, il suffit de mettre après l'impression :

iImprimeEtat(MonEtat, ...)

// check if document is, or has been, printed
SI Report_Printed("MonEtat") = Vrai ALORS
...
SINON
...
FIN


Dans ton cas, je ferais même comme ça :

iInitRequêteEtat(MonEtat, IDDoc)
iImprimeEtat(MonEtat)

SI Report_Printed("MonEtat") = Vrai ALORS
SqlUpdate est une Source dede Données
SqlUpdate.IDDoc = Col_IdDoc

SI HExécuteRequêteSQL(sdReq, "UPDATE DOCUMENTS SET EstImprime = 1 WHERE IDDoc = {IDDoc}") = Faux ALORS
TitreSuivant("Erreur")
Erreur(HErreurInfo(hErrComplet))
FIN
FIN
Mensagem modificada, fevereiro, 08 2024 - 3:40 PM
Membro registado
182 mensagems
Publicado em fevereiro, 08 2024 - 3:52 PM
Attention, je vois que le parseur double le terme "EXCEPTION" dans le code de la procédure "Report_Printed".
Membro registado
4.361 mensagems
Publicado em fevereiro, 08 2024 - 4:07 PM
Bonjour,
iStatutImpressionEnCours devrait résoudre une partie de ton problème

--
Il y a peut être plus simple, mais, ça tourne
Publicado em fevereiro, 09 2024 - 8:21 AM
Bonjour

Merci pour vos retours

@Adri1b : Je test ton code mais je trouve toujours que la variable pcReturned garde la valeur 0 qui permet de renvoyer la valeur FAUX c'est à dire que l'impression n'est pas bien passée

@Voroltinquo : J'ai testé la fonction on le met dans la fermeture de l'état à imprimer
Mais ca marche pas
soit statut=iStatusImpressionEtat()
SELON statut
CAS -1 : Trace("Aucune impression en cours")
CAS -2 : Trace("Impression abandonnée")
CAS 0 : Trace("Impression en cours")
CAS 1 : Trace("Etat vide : aucune données à imprimer")
FIN
Membro registado
182 mensagems
Publicado em fevereiro, 09 2024 - 11:16 AM
Je vais retester le code.
Il y a probablement eu des changements sur les API entretemps.