Utiliser un tableau dynamique ? [Résolu]

Signaler
Messages postés
61
Date d'inscription
mardi 4 mai 2004
Statut
Membre
Dernière intervention
1 août 2007
-
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
-
Voici mon souci : je dois envoyé à un périphérique en USB des commandes spécifiques (19 pour l'instant) et


recevoir leur réponse, sachant que je ne peux à priori pas envoyer toutes ces commandes à la fois, sinon je ne receverrai que la réponse de la 19ième commande !
J'aurai voulu donner un nom pour chaque commande envoyée, mais cela posera peut-être problème pour la création d'un tableau fixe ou dynamique. Comment faire au mieux selon vous car je ne voit pas très bien comment procéder ?
Merci



Sub CollectData()

Dim Buffer As String * 256

start = Chr(27) & Chr(1)

Model = start & "@EJL IQ NAME" & vbCrLf
USBID = start & "@EJL IQ USBID" & vbCrLf
SN = start & "@EJL IQ SERIALNUMBER" & vbCrLf
FW = start & "@EJL IQ FIRMREVISION" & vbCrLf
MCU = start & "@EJL IQ MCUREVISION" & vbCrLf
Memory = start & "@EJL IQ MEMORY" & vbCrLf
CTR = start & "@EJL IQ CTONERREMAIN" & vbCrLf
MTR = start & "@EJL IQ MTONERREMAIN" & vbCrLf
YTR = start & "@EJL IQ YTONERREMAIN" & vbCrLf
KTR = start & "@EJL IQ TONERREMAIN" & vbCrLf
CTC = start & "@EJL IQ CTONERCHANGE" & vbCrLf
MTC = start & "@EJL IQ MTONERCHANGE" & vbCrLf
YTC = start & "@EJL IQ YTONERCHANGE" & vbCrLf
KTC = start & "@EJL IQ TONERCHANGE" & vbCrLf
OPCR = start & "@EJL IQ OPCREMAIN" & vbCrLf
TP = start & "@EJL IQ TOTALPRINT" & vbCrLf
CTP = start & "@EJL IQ COLORTOTALPRINT" & vbCrLf
MTP = start & "@EJL IQ MONOTOTALPRINT" & vbCrLf
TotalStatus = start & "@EJL IQ TOTALSTATUS" & vbCrLf
        
data = Model + USBID + SN + FW + MCU + Memory + CTR + MTR + YTR + _
       KTR CTC + MTC + YTC + KTC + OPCR + TP + CTP + MTP + TotalStatus
        
datalen = Len(data)

For i = 1 To 10

    If (Send = 0) Then
        Send = WriteComm(hprinter, data, datalen)
    ElseIf (Send = 5) Then
        MsgBox "A port writting error has occured" & vbCrLf & Err.Description
    ElseIf (Send = 6) Then
        MsgBox "A writting error has occured" & vbCrLf & Err.Description
    End If

nb = Len(Buffer)
Receive = ReadComm(hprinter, Buffer, nb)

    If (Receive = 0) Then
        Buffer = Left(Buffer, nb) 'Troncage du buffer sur le nombre de caractères effectivement lus
    ElseIf (Receive = 7) Then
        MsgBox "A read error has occured" & vbCrLf & Err.Description
    End If
    
Next i

   
    Text1.Text = data & lineoftext & vbCrLf
    Text1.Enabled = True
    
    Text2.Text = ""
    Text2.Text = Buffer & lineoftext & vbCrLf
    Text2.Enabled = True
   
CloseComm (hprinter)

End Sub

10 réponses

Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
37
Niveau code ça pourrait donner quelque chose du genre :

JE me suis permis de modifier un peu ton traitement, je ne sais pas si ça correspondra exacteemnt à ton besoin

Sub CollectData()

Dim Buffer As String * 256
Dim TabCommande(1 To 19) As String

start = Chr(27) & Chr(1)

TabCommande(1) = start & "@EJL IQ NAME" & vbCrLf             'Model
TabCommande(2) = start & "@EJL IQ USBID" & vbCrLf            'USBID
TabCommande(3) = start & "@EJL IQ SERIALNUMBER" & vbCrLf     'SN
TabCommande(4) = start & "@EJL IQ FIRMREVISION" & vbCrLf     'FW
TabCommande(5) = start & "@EJL IQ MCUREVISION" & vbCrLf      'MCU
TabCommande(6) = start & "@EJL IQ MEMORY" & vbCrLf           'Memory
TabCommande(7) = start & "@EJL IQ CTONERREMAIN" & vbCrLf     'CTR
TabCommande(8) = start & "@EJL IQ MTONERREMAIN" & vbCrLf     'MTR
TabCommande(9) = start & "@EJL IQ YTONERREMAIN" & vbCrLf     'YTR
TabCommande(10) = start & "@EJL IQ TONERREMAIN" & vbCrLf     'KTR
TabCommande(11) = start & "@EJL IQ CTONERCHANGE" & vbCrLf    'CTC
TabCommande(12) = start & "@EJL IQ MTONERCHANGE" & vbCrLf    'MTC
TabCommande(13) = start & "@EJL IQ YTONERCHANGE" & vbCrLf    'YTC
TabCommande(14) = start & "@EJL IQ TONERCHANGE" & vbCrLf     'KTC
TabCommande(15) = start & "@EJL IQ OPCREMAIN" & vbCrLf       'OPCR
TabCommande(16) = start & "@EJL IQ TOTALPRINT" & vbCrLf      'TP
TabCommande(17) = start & "@EJL IQ COLORTOTALPRINT" & vbCrLf 'CTP
TabCommande(18) = start & "@EJL IQ MONOTOTALPRINT" & vbCrLf  'MTP
TabCommande(19) = start & "@EJL IQ TOTALSTATUS" & vbCrLf     'TotalStatus
       

For i = LBound(TabCommande) To UBound(TabCommande)
   
   Send = WriteComm(hprinter, TabCommande(i), Len(TabCommande(i)))
   If (Send = 5) Then
       MsgBox "A port writting error has occured" & vbCrLf & Err.Description
       Exit Sub
   ElseIf (Send = 6) Then
       MsgBox "A writting error has occured" & vbCrLf & Err.Description
       Exit Sub
   End If

   ' Un peu d'attente, on en profite pour rendre la main au système
   ' pour qu'il est, par exemple, le temps de traiter l'envoie et la reception
   DoEvents
   
   Receive = ReadComm(hprinter, Buffer, Len(Buffer))
'### il sera judicieux de regarder si ReadComm ne retourne pas l'info que rien n'est encore recu
'### Si c'est le cas, il faudrait alors remplacer les 2 lignes au dessus par une boucle style
'###    Do
'###        DoEvents
'###        Receive = ReadComm(hprinter, Buffer, Len(Buffer))
'###    Loop While Receive = [le retour de "aucune données reçues"]

   If (Receive = 0) Then
       Buffer = Left(Buffer, nb) 'Troncage du buffer sur le nombre de caractères effectivement lus
   ElseIf (Receive = 7) Then
       MsgBox "A read error has occured" & vbCrLf & Err.Description
   End If
   
   'En mettant la propriété Multiline de Text1 et de Text2 à True
   'tu pourra voir l'ensemble des commandes et des réponses
   Text1.Text = Text1.Text & TabCommande(i) & vbCrLf
   Text2.Text = Text2.Text & Trim(Buffer) & vbCrLf
Next i
 
CloseComm (hprinter)

End Sub
, ----
[code.aspx?ID=41455 By Renfield]

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
37
Je comprens pas tout là.

Dans le code que tu met, tu envois l'ensemble des 19 commandes à une seule fois, tu lis la réponse, et tu fait cela 10 fois.
Es-tu sur que ton code est correct ?
Quel est l'interet d'envoyer 10 fois de suite l'ensembles des commandes ?

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Messages postés
61
Date d'inscription
mardi 4 mai 2004
Statut
Membre
Dernière intervention
1 août 2007

J'ai mis 10 fois mais j'aurai pu mettre 2, ça suffit, c'est juste parce que je voulais mettre un délai de réception pour le ReadComm. Si je met la boucle juste pour le ReadComm, je ne reçoi rien, ou du moins je n'arrive pas à lire.
En fait, actuellement je n'arrive à lire que la dernière commade : TotalStatus = start & "@EJL IQ TOTALSTATUS" & vbCrLf.
Si je veux lire toutes les commandes envoyées, comment je pourrais faire ? Tableau ? Enoyé une commande et faire un call ReadComm entre chaque commande ?
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
37
le problème avec ce code c'est que tu envoie toutes les commandes en une seule fois, donc oui tu ne lira que la réponse à la dernière commande envoyée.
De plus en l'envoyant 10 fois de suite, tu sature ton imprimante. Il y a des chance qu'au bout d'un moment elle n'y comprenne plus rien et il doit lui falloir un certain temps pour retrouver ses petits.

Ensuite pour le tableau, si tu veux, tu peux stocker tes commandes dans un tableau si ça t'arrange. ça peut etre effectivement utile si tu veux faire une boucle pour l'envoie

Le principe de la communication c'est

Debut_Boucle
    Envoie de la commande x
    Un peu d'attente, le temps que l'imprimante réponde
    Lecture de la réponse
Fin_boucle

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Messages postés
61
Date d'inscription
mardi 4 mai 2004
Statut
Membre
Dernière intervention
1 août 2007

Merci beaucoup Casy, j'y vois un peu plus clair maintenant.
Ce qui est bizarre c'est que je n'obtient pas tout et dans dans le même orde !!!
Voici ce que j'obtiens :





@EJL ANSWER TONERREMAIN=84
@EJL ANSWER CTONERCHANGE=?
@EJL ANSWER MTONERCHANGE=?
@EJL ANSWER YTONERCHANGE=?
@EJL ANSWER TONERCHANGE=15
@EJL ANSWER OPCREMAIN=61

@EJL ANSWER TOTALPRINT=101747
@EJL ANSWER COLORTOTALPRINT=?
@EJL ANSWER MONOTOTALPRINT=?

@EJL STATUS CODE=62B003E800080001000054FFFFFFFFFF3DFFFFFF52190E01FFFF0000FFFF0000FFFF0000FFFF000000018D73FFFFFFFF00FFFF
@EJL ANSWER TOTALSTATUS=?
080001000054FFFFFFFFFF3DFFFFFF52190E01FFFF0000FFFF0000FFFF0000FFFF000000018D73FFFFFFFF00FFFF
@EJL STATUS CODE=62B003E800080001000054FFFFFFFFFF3DFFFFFF52190E01FFFF0000FFFF0000FFFF0000FFFF000000018D73FFFFFFFF00FFFF
@EJL ANSWER NAME="EPL-6200"
0001000054FFFFFFFFFF3DFFFFFF52190E01FFFF0000FFFF0000FFFF0000FFFF000000018D73FFFFFFFF00FFFF
@EJL ANSWER USBID=24P120311051123270
4FFFFFFFFFF3DFFFFFF52190E01FFFF0000FFFF0000FFFF0000FFFF000000018D73FFFFFFFF00FFFF
@EJL ANSWER SERIALNUMBER=?
51123270
4FFFFFFFFFF3DFFFFFF52190E01FFFF0000FFFF0000FFFF0000FFFF000000018D73FFFFFFFF00FFFF
@EJL ANSWER FIRMREVISION=19710
3270
4FFFFFFFFFF3DFFFFFF52190E01FFFF0000FFFF0000FFFF0000FFFF000000018D73FFFFFFFF00FFFF
@EJL ANSWER MCUREVISION=?
710
3270
4FFFFFFFFFF3DFFFFFF52190E01FFFF0000FFFF0000FFFF0000FFFF000000018D73FFFFFFFF00FFFF
@EJL ANSWER MEMORY=8388608
10
3270
4FFFFFFFFFF3DFFFFFF52190E01FFFF0000FFFF0000FFFF0000FFFF000000018D73FFFFFFFF00FFFF
@EJL ANSWER CTONERREMAIN=?
10
3270
4FFFFFFFFFF3DFFFFFF52190E01FFFF0000FFFF0000FFFF0000FFFF000000018D73FFFFFFFF00FFFF





Ce que j'aimerais afficher serais ceci :



@EJL ANSWER NAME="EPL-6200"
@EJL ANSWER USBID=24P120311051123270
@EJL ANSWER SERIALNUMBER=?
@EJL ANSWER FIRMREVISION=19710
@EJL ANSWER MCUREVISION=?
@EJL ANSWER MEMORY=8388608
@EJL ANSWER CTONERREMAIN=?
@EJL ANSWER CTONERCHANGE=?
@EJL ANSWER MTONERREMAIN=?
@EJL ANSWER MTONERCHANGE=?
@EJL ANSWER YTONERREMAIN=?
@EJL ANSWER YTONERCHANGE=?
@EJL ANSWER TONERREMAIN=84
@EJL ANSWER TONERCHANGE=15
@EJL ANSWER OPCREMAIN=61
@EJL ANSWER TOTALPRINT=101747
@EJL ANSWER COLORTOTALPRINT=?
@EJL ANSWER MONOTOTALPRINT=?
@EJL ANSWER TOTALSTATUS=?




De plus, est-il possible de modifier directement une variable chaîne de caractères en utilisant un code similaire à celui-ci (que j'utilise lorque j'ouvre un fichier texte) ?
Voici un code que j'utilise pour prendre uniquement les caractères qui se situent après le signe "=" et avant le retour chariot d'une chaîne telle que celle-ci : @EJL ANSWER NAME="AL-2600"

Open strfilePrn For Input As #1
    Do Until EOF(1)
        Line Input #1, lineoftext$
        If InStr(lineoftext$, "=") > 0 Then
        monmot = Trim(Mid(lineoftext$, InStr(lineoftext$, "=") + 1))
        Text1.Text = Text24.Text & monmot & vbCrLf
        End If
    Loop
Close #1   'Cela m'affichera donc juste "AL-2600"

C'est ce que j'aimerai faire sur les données recueillies pour les mettre dans un autre tableau par exemple, en attente de pouvoir les sauver dans un fichier CSV de ce type :



colonne 1:      colonne 2 :       colonne 3 :  ..........
ligne 1 :          Date                Time                Name
ligne 2 :      xx-xx-xxxx         xx:xx:xx       "AL-C2600"







Quand ce source sera au point, je le posterai sans doute car il est quand même intéressant pour un débutant comme moi je pense : utilisation de dll, utilisation de tableaux, manipulation de chaîne de caractère, création et enrigistrement de données das un fichier CSV...

PS : Comment utiliser la coloration syntaxique lorsque qu'on met un code dans le forum ?
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
37
Alors , je vais tenter de répondre dans l'ordre.

<ol><li>Pour le problème d'ordre, cela vient du fait que l'imprimante mette plus de temps à répondre à certaines comandes par rapport à d'autre. D'ou mon commentaire sous l'instruction ReadComm. Il faudrait voir l'instruction ReadComm renvoie un état qui dit que rien n'a encore été reçu. Si c'était le cas, il faudra faire une boucle sur cet état (celle que j'ai mis en com) tant que la réponse n'a pas été reçue et ne passer à la commande suivante que lorsque la réponse est reçue et traitée. Mais n'ayant pas possibilité de faire de test, je ne peux en dire plus.</li><li>Bien sur que tu peux traiter la chaine reçue pour ne garder que le texte souhaité. Les instruction inportantes  sont
        If InStr(chaine_à_traiter, "= ") > 0 Then
        résultat = Trim(Mid(
chaine_à_traiter
, InStr(
chaine_à_traiter
, "=") + 1))

Par rapport au premier code que je t'ai donné, la chaine à traiter serait Buffer, le résultat viendrait à la place de Trim(Buffer) dans la dernière instruction</li><li>Pour les fichiers CSV rien de plus simple, c'est un simple fichier texte ou une ligne = une ligne du tableau, les colonnes sont séparées par un caractère séparateur. A l'orrigine c'est un comma (d'ou le nom csv,  Comma Separate Value) ou en français un ; mais Excel accepte aussi la tabulation que l'on voit d'ailleurs de plus en plus souvent car même ouvert comme fichier texte, le fichier possède un début de mise en forme qui permet de le lire facilement, même si c'est d'etre parfait.</li><li>Pour la coloration syntaxique, il faut utiliser des petits logiciels externes, développer par certains membres du forum. Car rien n'est prevu au niveau de VB, mais en plus, il faut que la mise en page generée soit compatible avec ce forum. Si tu fait une recherche dans les sources tu en trouvera plusieurs, notamment une de Mortalino et PCPT, et une autre de Renfield. Celle que j'ai utiliser ici est celle de Renfield. Cet un plug-in qui se rajoute comme complément à VB6. Ensuite Il te suffit de sélectionné ton code dans VB6, de faire Copier. Quand tu le collera sur le forum, il sera coloré. Tu peux acceder directement à la page de la source en cliquant sur le petit lien "By Renfield" en bas à droite du code
</li></ol>

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Messages postés
61
Date d'inscription
mardi 4 mai 2004
Statut
Membre
Dernière intervention
1 août 2007

Merci Casy pour ton aide.
1. Je reçoi bien quelque chose dès le départ mais ce n'est pas la réponse à IQ NAME, mais c'est la réponse à TabCommande(10), ie TONERREMAIN, même en mettant :
Do
        DoEvents
        receive = ReadComm(hprinter, Buffer, Len(Buffer))
Loop While Buffer = " "

2. Je récupère ceci : MFG:EPSON;CMD:EJL,PJL,PCL,HPGL2-01,ESCPL2,ESCP9,PRPXL24-01,ESCPAGE-04,PCLXL,POSTSCRIPT;MDL:EPL-6200;CLS:PRINTER;DES:EPSON EPL-6200;
et j'aimerai prendre juste ce qu'il y a entre ":" et ";"
MFG=xxxx
CMD=xxxx
MDL=xxxx
DES=xxxx

J'ai commencer à écrire un bout de code mais pour l'instant ça ne colle pas :

p = InStr(PID, "CMD:")
v = Right(PID, Len(PID) - p + 1)
p = InStr(PID, ";")
Text27.Text = Text27.Text & Trim(Mid(v, p - 1)) & vbCrLf

3.  CommonDialog2.Filter = "Comma Separated Value (*.CSV)|*.CSV"
    CommonDialog2.ShowSave      'affiche la bte dial Enregistrer
    If CommonDialog2.FileName <> "" Then
      
        Open CommonDialog2.FileName For Output As #1
   Print #1, Date & ",";
   Print #1, Time & ",";

Comment faire pour ranger de cette façon ?
colonne 1:      colonne 2 :       colonne 3 :  ..........
ligne 1 :          Date                Time                Name
ligne 2 :      xx-xx-xxxx         xx:xx:xx       "AL-C2600"

Merci encore
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
37
Déjà un petit conseil en passant : Si tu as l'intention un jour de passer à .Net, je te conseille dès maintenant de prendre l'habitude de n'utiliser que la fonction Mid, de laisser tomber Left et Right. Left et right n'existe plus en .Net, seul Mid trouve son équivalent dans la méthode SubString. De plus ça te permettra de réflechir différenment à la découpe de tes chaines et eviter des erreurs notamment avec Right dont la manipulation n'est pas des plus naturelles. En fait Left et Right peuvent etre considérées comme des surcharges de Mid. On peut donc toujours se ramener à l'utilisation de Mid :
Left(chaine, longueur) ---> Mid(chaine, 1, longueur)
Right(chaine, longueur) ---> Mid(chaine, len(chaine)-longueur+1).ex dans ton cas : v Right(PID, Len(PID) - p + 1) --> v Mid(PID, p)

Concernant ton code, le voici donc corrigé :

pid = "MFG:EPSON;CMD:EJL,PJL,PCL,HPGL2-01,ESCPL2,ESCP9,PRPXL24-01,ESCPAGE-04,PCLXL,POSTSCRIPT;MDL:EPL-6200;CLS:PRINTER;DES:EPSON EPL-6200;"

p = InStr(pid, "CMD:")
v = Mid(pid, p + Len("CMD:"))
p = InStr(v, ";")
Text27.Text = Text27.Text & Trim(Mid(v, 1, p - 1)) & vbCrLf
, ----
[code.aspx?ID=41455 Code de colorisation By Renfield], <
Et en tennant compte de la spécificité de ta chaine et du résultat que tu veux en obtenir, je te propose une astuce pour décoder la totalité de la chaine en une seule passe :

pid = "MFG:EPSON;CMD:EJL,PJL,PCL,HPGL2-01,ESCPL2,ESCP9,PRPXL24-01,ESCPAGE-04,PCLXL,POSTSCRIPT;MDL:EPL-6200;CLS:PRINTER;DES:EPSON EPL-6200;"

pid = Replace(pid, ":", "=")
pid = Replace(pid, ";", vbCrLf)
Text27.Text = pid
, ----
[code.aspx?ID=41455 Code de colorisation By Renfield], <

Concernant l'écriture dans le fichier, tu peux faire ainsi, ça sera directement reconnu par Excel :

CommonDialog2.Filter = "Comma Separated Value (*.CSV)|*.CSV"
CommonDialog2.ShowSave      'affiche la bte dial Enregistrer
If CommonDialog2.FileName <> "" Then
   Open CommonDialog2.FileName For Output As #1
   Print #1, Date & ";" & Time & ";" & "Texte à mettre"
   Close
End If , ----
[code.aspx?ID=41455 Code de colorisation By Renfield], <
---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Messages postés
61
Date d'inscription
mardi 4 mai 2004
Statut
Membre
Dernière intervention
1 août 2007

'### il sera judicieux de regarder si ReadComm ne retourne pas l'info que rien n'est encore recu




'### Si c'est le cas, il faudrait alors remplacer les 2 lignes au dessus par une boucle style




'###    Do




'###        DoEvents




'###        Receive = ReadComm(hprinter, Buffer, Len(Buffer))




'###    Loop While Receive = [le retour de "aucune données reçues"]



Au contraire cela reçoi trop vite j'ai l'impression et c'est toujours TONERREMAIN qui est mis en premier et non NAME qui est la première commande...!!! Peut-être faut-il initialiser le tableau.

Concernant le CSV, merci ce n'était ni vbTab, ni ",", c'était ";"
Et ça mets toujours par défaut sur la première ligne, et si je veux mettre sur la deuxième ligne ou plus, quels sont les séparateurs ou commandes à utiliser ?
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
37
Oui effectivement pour la boucle, dans ce cas il faudrait alors lire en boucle jusque avoir effectivement lu la bonne réponse. Par exemple la réponse contenant ANSWER NAME pour la commande NAME.

Pour le fichier, le problème vient de la facon de l'utiliser. Avec une ouverture en mode OUTPUT, ton fichier est systématiquement effecer et recréer à chaque ouverture.
Deux solutions :
- Soit garder ce mode d'ouverture, dans ce cas il faut ouvrir le fichier avant la boucle, dans la boucle, ecrire les 19 lignes, et ne le fermer que une fois toutes les lignes écrites, par exemple en sortant de la procedure.

- Soit changer le mode d'ouverture en mode APPEND, dans ce cas le fichier sera ouvert de sorte que toute nouvelle ecriture soit systématiquement ajouter à la fin du fichier.

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #