Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 3 oct. 2006 à 17:47
sans vouloir relancer la polémique...
voici un code fonctionnel (on m'a demandé ce code, je voulais filer une version claire...)
Private Sub Form_Load()
Dim i As Long
Dim xsParts() As String
xsParts = ParseCommandLine("")
For i = LBound(xsParts) To UBound(xsParts)
Debug.Print i, xsParts(i)
Next i
Unload Me
End Sub
Private Function ParseCommandLine(Optional ByVal vsCommandLine) As String()
Dim i As Long
Dim bInQuotes As Boolean
Dim nChar As Integer
'# Si aucune chaine avec les arguments de ligne de commande n'a été fournie...
If IsMissing(vsCommandLine) Then
'# On utilise celle recue par l'executable, obtenu grâce a la fonction Command$()
vsCommandLine = Trim$(Command$())
Else
'# sinon, on utilise celle effectivement fournie par l'utilisateur.
vsCommandLine = Trim$(vsCommandLine)
End If
If LenB(vsCommandLine) Then
'# On regarde la chaine, caractère par caractère
For i = 1 To Len(vsCommandLine)
'# On évite d'extraire deux fois le même caractère
nChar = AscW(Mid$(vsCommandLine, i, 1))
'# Si le caractère considéré est une guillemet, on incrémente le compteur
If nChar = 34 Then
bInQuotes = Not bInQuotes
'# si c'est un espace...
ElseIf nChar = 32 Then
'# ...et que nous sommes en dehors d'un 'tronçon' avec des guillemets,
'# on remplace l'espace par un carctère \0
If Not bInQuotes Then
Mid$(vsCommandLine, i, 1) = vbNullChar
End If
End If
Next i
'# tout tronçon de chaîne ouvert par des " doit être fermé
'# On teste donc si le nombre de guillemets est pair ou impair
If bInQuotes Then
Err.Raise vbString, , "Construction de la chaîne de paramètres incorrecte"
Else
'# On supprime les guillemets de la chaine finale
vsCommandLine = Replace(vsCommandLine, ChrW$(34), vbNullString)
'# On découpe la ligne de commande à chaque \0 rencontré
ParseCommandLine = Split(vsCommandLine, vbNullChar)
End If
Else
ReDim ParseCommandLine(0) As String
End If
End Function
cs_clafouti
Messages postés78Date d'inscriptionsamedi 16 mars 2002StatutMembreDernière intervention 7 septembre 2006 7 sept. 2006 à 08:48
Si il y a aucune quotes, à la fin de la boucle de vérification, bQuotes est true, et donc pas de messages d'erreur.
J'ai testé la fonction avec plusieurs cas de figure, cela marche parfaitement.
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 7 sept. 2006 à 02:54
tu proposes d'initialiser à true. mais s'il n'y a aucune quote????
++
cs_clafouti
Messages postés78Date d'inscriptionsamedi 16 mars 2002StatutMembreDernière intervention 7 septembre 2006 6 sept. 2006 à 18:31
La seule chose qui importe est de savoir si on a un nombre pair (correct) ou impair (incorrect) de quotes. A la fin de la boucle, si bQuotes est false, c'est qu'il y a un nombre impair de quotes ==> message d'erreur.
Quand à la simplicité du code, elle me parrait évidente : qu'est-ce qui est plus lisible : "if cBool(nQuotes and 1) Then..." ou "if not bQuotes Then..." ?
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 6 sept. 2006 à 13:28
clafouti -> et sorti de ta boucle tu vois comment qu'il y en avait ou pas (des ")? ....
et si cette proposition était valable (mais c'est pas le cas), je ne vois pas en quoi soudainement le code devient "plus simple" ;)
si?
cs_clafouti
Messages postés78Date d'inscriptionsamedi 16 mars 2002StatutMembreDernière intervention 7 septembre 2006 6 sept. 2006 à 13:23
Eh les gars, c'est bien joli toutes vos explications, mais il y a plus simple !!!
Déclarer bQuotes as boolean, et initialiser à true.
Ensuite dans la boucle de "comptage" des quotes, il suffit de faire bQuotes = not bQuotes.
Pour tester si c'est pair ou pas : if bQuotes then....
bouv
Messages postés1410Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 5 sept. 2006 à 20:56
Oula... ne vous enervez pas, je ne fais qu'emettre un point de vu.
Je ne connais que VB6 comme langage et tout ce que j'ai appris c'est sur ce site, je n'ai jamais pris aucun cours. Donc il me manque évidemment quelques bases importantes.
Comme dit plus haut : "je suis volontier preneur d'explication".
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 5 sept. 2006 à 20:41
' si c'est une " de fermeture, on insère un espace s'il n'y en a pas
If (i > 1) And (i < Len(strCommandLine)) Then
If Not CBool(nQuotes And 1) Then
If Mid$(strCommandLine, i + 1, 1) <> " " Then
strCommandLine = Left$(strCommandLine, i) & " " & Right$(strCommandLine, Len(strCommandLine) - i)
End If
End If
End If
marrant, sans CBool çà fausse tout ^^
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 5 sept. 2006 à 20:31
woups, je corrige çà
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 5 sept. 2006 à 20:26
en dessous de l'incrémentation de nQuotes :
If (i > 1) And (i < Len(strCommandLine)) Then
If nQuotes And 1 Then
If Mid$(strCommandLine, i + 1, 1) <> " " Then
strCommandLine = Left$(strCommandLine, i) & " " & Right$(strCommandLine, Len(strCommandLine) - i)
End If
End If
End If
cs_LogOff
Messages postés69Date d'inscriptiondimanche 6 octobre 2002StatutMembreDernière intervention14 juillet 2009 5 sept. 2006 à 19:31
Pour l'histoire du '/ping', il est clair que si la syntaxe de la ligne de commande est incorrecte (ie. si pas de séparateur 'espace ' entre les arguments), la fonction ne retourne pas le résultat attendu.
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 5 sept. 2006 à 18:16
Bouv, tu peux pas remettre en cause 30 ans d'informatique basés sur
"est-ce différent de 0 ?"
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 5 sept. 2006 à 18:14
bouv > c'était le 1/4 h plaisanterie ou quoi ?
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 5 sept. 2006 à 18:06
condition : est-ce que 5<>0 oui
nop?
bouv
Messages postés1410Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 5 sept. 2006 à 18:01
"toujours comparer à 0 ou non 0"
C'est bien là que je ne trouve pas cela "normal".
False = 0
True = -1
Or, If bVar Then ..., ne devrait entrer dans la première partie du If que si bVar True donc -1.
Seulement si on fait, If 5 Then ... cela fonctionne également !
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 5 sept. 2006 à 17:55
qu'il convertisse ou non, sa structure interne est (en hexa):
400C0000 00000000
le bit droit est 0 donc résult 0 tout a fait normalement.
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 5 sept. 2006 à 17:44
x And 1 ne pourra renvoyer que 0 ou 1
pas mal interprété, non ....
(3.5 And 1) => 0
VB arrondit apparemment il doit y avoir un Cast vers un Long, en interne
cs_asimengo
Messages postés280Date d'inscriptionjeudi 24 mars 2005StatutMembreDernière intervention18 mars 2009 5 sept. 2006 à 17:30
Mon exemple était juste pour que la précision soit faite. Tout le monde passe par ici et ne comprend pas toujours très bien. La précision a été faite par Renfield et Brunews, ce test de parité (x and 1) n'est efficace que si x est un entier. Si résultat = 0 alors x est pair sinon (si différent de 0, peu importe la valeur) alors x est impair
Néanmoins:
Renfield dit : lors d'opérations bit a bit, VB supprime la partie décimale...
(3.5 and 1) = 0, ne semble pas vérifier, ai-je mal interpreter ce qu'a dit Renfield?
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 5 sept. 2006 à 17:12
Comme quoi VBA 2002 a été correctement réécrit...
Lecture des manuels Intel (ce qu'un VBiste fait régulièrement...) indique clairement:
NOT => Flags affected: NONE
Quand je vous dis qu'il y a de la logique partout, he he.
cs_Patrice99
Messages postés1221Date d'inscriptionjeudi 23 août 2001StatutMembreDernière intervention 9 septembre 2018 5 sept. 2006 à 17:00
BruNews > c'est bien ce qu'on dit, toujours comparer à 0 ou non 0.
Certes, mais si bVar est un booléen, c'est quand même triste que Not bVar ne soit pas toujours correctement évalué !
Heureusement en DotNet avec compilation Strict, il est strictement impossible de se faire piéger ainsi comme en VB6, ou plus gravement comme en VBA
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 5 sept. 2006 à 16:17
BruNews est tout se qu'il y a de plus au fait de se qui se passe en coulisses.
VB/VBA/VBS ne dérogent (heureusement) pas à la règle, et un IF ne teste qu'une seule et unique chose :
que l'expression présente entre If et Then soit ou non différent de 0.
son évaluation, c'est encore autre chose...
mavar And 1 va effectuer une operation bit a bit, et générer une valeur numérique
(qui sera testée selon son égalité ou non avec 0)
rien d'autre a ajouter là dessus
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 5 sept. 2006 à 16:10
Patrice > c'est bien ce qu'on dit, toujours comparer à 0 ou non 0.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 5 sept. 2006 à 16:08
mavar And 1
donne un résultat sur registre EFlags (pas sur mavar puiqsque non affecté) seulement, le test est toujours sur 0 ou NON 0 dans tous les cas.
Il pourrait en aller autrement avec des 'objets' VB ou VBA mais sur des types primaires, If se comporte ici comme dans tout langage.
cs_Patrice99
Messages postés1221Date d'inscriptionjeudi 23 août 2001StatutMembreDernière intervention 9 septembre 2018 5 sept. 2006 à 16:03
Parfois non : Attention, en VBA, le test If Not True Then ne fonctionne pas à 100%, il y a des cas où ça ne marche pas (par exemple si on lance une application Access 2000 avec Access 2002, remplacer If Not bVar par If False = bVar par mesure de prudence)
bouv
Messages postés1410Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 5 sept. 2006 à 15:56
Pour :
If mavar Then
' execute ok
End If
Je suis ok, mais pour :
If mavar And 1 Then OkExecute
Cela me parait moins evident.
Après je peux me tromper, si je mets ça dans le même sac que le reste (de certaines "non rigueurs" de VB) indûment. Dans ce cas je suis volontier preneur d'explication.
++
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 5 sept. 2006 à 15:31
ah non, là je suis pas du tout d'accord sur le sujet du 'If', aucune faute de prog à écrire:
If mavar Then
' execute ok
End If
'If' teste le NON 0 pour exécuter la condition comme dans tout langage normal, un cast superflu n'est en aucun cas de la rigueur programmatique, seulement perte de cycles car remplissage des bits à 1 (or eax, -1) totalement inutile.
If mavar And 1 Then OkExecute
sera traduit en:
test eax, 1
je LabelNON
il serait dommage d'en rajouter, non ?
cs_Patrice99
Messages postés1221Date d'inscriptionjeudi 23 août 2001StatutMembreDernière intervention 9 septembre 2018 5 sept. 2006 à 15:29
Ma fonction ne marche pas avec "cmd.exe exe.exe"/ping
Elle renvoie "cmd.exe exe.exe" et ping
Mais elle fonctionne avec "cmd.exe exe.exe" /ping
PCPT > Codyx.Org est aussi là pour çà ;)
Oui mais j'ai trop l'habitude d'utiliser Google pour trouver ce que je cherche, car je n'aime pas attendre, et j'aime sa pertinence. Je me sert de Google pour retrouver la plupart des fonctions que j'utilise, car j'ai mis les sources de mes programmes sur le web grace à VBToHtml.
bouv
Messages postés1410Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 5 sept. 2006 à 15:04
Je rejoins la conversation de BruNews et Renfield sur l'histoire du CBool.
Il est vrai que VB ne requiert pas le CBool dans le cas présent. Et je ne le met moi même jamais (ou presque).
Il s'agit à mon sens d'une des nombreuses 'fautes de programmation' que VB nous laisse faire. Certains diront souplesse, je préfère parler de fautes ou de code peu rigoureux que VB nous laisse programmer.
Ex : Utilisation de variables implicites, type casting...
Autre exemple :
Dim dVar As Double
Dim iVar as Integer
dVar = 3.2
iVar = dVar
Ceci ne posera pas non plus de problème !
++
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 5 sept. 2006 à 12:18
Patrice99 -> Codyx.Org est aussi là pour çà ;)
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 5 sept. 2006 à 11:59
bien vu.
c'est à cause de l'espace attendu avant le /ping...
ratala
Messages postés248Date d'inscriptionjeudi 3 février 2005StatutMembreDernière intervention22 juin 2008 5 sept. 2006 à 11:32
Ne marche pas avec un
"cmd.exe exe.exe"/ping
le fichier cmd.exe exe.exe est evidament un seul fichier
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 5 sept. 2006 à 11:12
J'ai pris pour habitude d'utiliser CBool lors d'opérations bit à bit.
Bien qu'il ne soit pas requis dans de nombreux cas, il arrive que son absence soit génante :
a = 5
'# On teste si a est impair
If a And 1 Then
'# On arrive ici, c'est OK
End If
a = 5
'# On teste si a est pair
If Not (a And 1) Then
'# On arrive ici, ca n'est pas voulu
'# l'explication est simple :
'# a And 1 => 1
'# Not 1 => -2 et comme -2 est different de 0...
End If
a = 5
'# On teste si a est impair
If Not CBool(a And 1) Then
'# On n'arrive plus ici, c'est OK
End If
Pourtant, et bien que certains seront satisfaits de CBool, une petite discussion avec notre ami BruNews m'aura éclairé sur le fait qu'un cast est un cast et qu'il consomme des cycles...il n'est pas plus complexe de faire un test d'égalité avec 0 :
a = 5
'# On teste si a est pair
If (a And 1)=0 Then
'# On n'arrive pas ici, pas de souci
End If
il y a donc de fortes chances pour que j'abandonne CBool....
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 5 sept. 2006 à 10:31
nQuotes est un entier dans ce code, ne pas sortir la phrase du contexte sinon on ne se comprendra plus.
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 5 sept. 2006 à 10:29
les deux écritures sont bien évidemment équivalentes, oui...
Asimengo, on ne joue ici qu'avec des nombres entiers
? 3.1 or 0
3
lors d'opérations bit a bit, VB supprime la partie décimale...
cs_asimengo
Messages postés280Date d'inscriptionjeudi 24 mars 2005StatutMembreDernière intervention18 mars 2009 5 sept. 2006 à 10:21
(3.1 and 1) = 1, de même cbool(3.1 and 1) = True est-ce à dire que 3.1 est impair?
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 5 sept. 2006 à 09:55
If nQuotes And 1 Then
et
If CBool(nQuotes And 1) Then
ne donnent pas idem pour le If ???
Bizzare, If teste si condition <> 0, normalement pas autre chose donc devrait être équivalent en plus court.
cs_Patrice99
Messages postés1221Date d'inscriptionjeudi 23 août 2001StatutMembreDernière intervention 9 septembre 2018 5 sept. 2006 à 09:27
Exact, ce n'est pas évident à retrouver, même via Google. C'est pour cela que je signale mes bouts de code quand l'occasion se présente.
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 5 sept. 2006 à 09:22
'nQuotes And 1' va renvoyer une valeur numérique.
CBool la transforme juste un Boolean (Vrai/Faux)
c'est une bonne habitude a prendre lorsque l'on fait des opérations bit à bit, en VB
le test
If CBool(nQuotes And 1) Then
est vrai si nQuotes est impair, c'est bien ce que l'on cherche...
cs_LogOff
Messages postés69Date d'inscriptiondimanche 6 octobre 2002StatutMembreDernière intervention14 juillet 2009 5 sept. 2006 à 08:38
Merci Patrice99, c'est noté. Tu conviendras quand même qu'on peut difficilement trouver ton code en lançant une recherche avec des mots-clefs comme 'ligne de commande' etc.
Quand vous avez des bouts de code comme ça, réutilisables et pas encore postés, ajoutez-les séparément, c'est bon pour tout le monde!
cs_LogOff
Messages postés69Date d'inscriptiondimanche 6 octobre 2002StatutMembreDernière intervention14 juillet 2009 5 sept. 2006 à 08:28
J'ai eu la réponse à ma question par Renfield (son post est arrivé pendant la rédaction du mien).
Tu peux expliquer l'utilisation de CBool stp (vb me dit juste: Convertit une expression en Boolean) ?
Merci,
cs_Patrice99
Messages postés1221Date d'inscriptionjeudi 23 août 2001StatutMembreDernière intervention 9 septembre 2018 5 sept. 2006 à 08:28
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 5 sept. 2006 à 08:26
VbNullChar
c'est non affichable
cs_LogOff
Messages postés69Date d'inscriptiondimanche 6 octobre 2002StatutMembreDernière intervention14 juillet 2009 5 sept. 2006 à 08:23
Merci PCPT pour ton post, l'idée de remplacer les espaces dans les chaînes entre guillemets par un chr(0) simplifie tout le code.
Ainsi que pour avoir corrigé ma gestion d'erreur qui provoquait elle-même une erreur!
Pour info.: chr(0), ça correspond à quel caractère (non affichable?) ?
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 5 sept. 2006 à 08:09
On peut même ne faire qu'une seule boucle :
Private Function ParseCommandLine(Optional ByVal strCommandLine) As String()
Dim i As Long
Dim nQuotes As Integer
Dim sChar As String
'# Si aucune chaine avec les arguments de ligne de commande n'a été fournie...
If IsMissing(strCommandLine) Then
'# On utilise celle recue par l'executable, obtenu grâce a la fonction Command$()
strCommandLine = Trim$(Command$())
Else
'# sinon, on utilise celle effectivement fournie par l'utilisateur.
strCommandLine = Trim$(strCommandLine)
End If
If LenB(strCommandLine) = 0 Then
ReDim ParseCommandLine(0) 'pour éviter l'erreur de ton Main ; pas testé?!!
Else
'# On regarde la chaine, caractère par caractère
For i = 1 To Len(strCommandLine)
'# On évite d'extraire deux fois le même caractère
sChar = Mid$(strCommandLine, i, 1)
'# Si le caractère considéré est une guillemet, on incrémente le compteur
If sChar = ChrW$(34) Then
nQuotes = nQuotes + 1
'# si c'est un espace...
ElseIf sChar = " " Then
'# ...et que nous sommes en dehors d'un 'tronçon' avec des guillemets,
'# on remplace l'espace par un carctère \0
If Not CBool(nQuotes And 1) Then
Mid$(strCommandLine, i, 1) = vbNullChar
End If
End If
Next i
'# tout tronçon de chaîne ouvert par des " doit être fermé
'# On teste donc si le nombre de guillemets est pair ou impair
If CBool(nQuotes And 1) Then
Err.Raise vbString, , "Construction de la chaîne de paramètres incorrecte"
Else
'# On découpe la ligne de commande à chaque \0 rencontré
'strCommandLine = Replace(strCommandLine, ChrW$(34), vbNullString)
ParseCommandLine = Split(strCommandLine, vbNullChar)
End If
End If
End Function
nous avons PCPT et moi même laissé le résultat tel quel...
reste que je pense qu'il serait de bon ton de supprimer les guillemets, dans le resultat. J'ai mis en commentaire la ligne qu'il te suffit d'activer si tu souhaite effectivement supprimer les guillemets
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 4 sept. 2006 à 21:27
salut,
c'est plus qu'optimisable....
Private Function ParseCommandLine(ByVal strCommandLine As String) As String()
strCommandLine = Trim$(strCommandLine)
If LenB(strCommandLine) = 0 Then
ReDim ParseCommandLine(0) 'pour éviter l'erreur de ton Main ; pas testé?!!
Else
Dim i As Integer, iCptQuotes As Integer
Dim aRes() As String
iCptQuotes = 0
For i = 1 To Len(strCommandLine)
If Mid$(strCommandLine, i, 1) Chr$(34) Then iCptQuotes iCptQuotes + 1
Next i
'tout tronçon de chaîne ouvert par des " doit être fermé
If iCptQuotes > 0 Then
If (iCptQuotes / 2 <> Int(iCptQuotes / 2)) Then
Err.Raise vbString, , "Construction de la chaîne de paramètres incorrecte"
Else
iCptQuotes = 0
For i = 1 To Len(strCommandLine)
If Mid$(strCommandLine, i, 1) = Chr$(34) Then
iCptQuotes = iCptQuotes + 1
ElseIf Mid$(strCommandLine, i, 1) = Chr$(32) Then
If (iCptQuotes / 2 <> Int(iCptQuotes / 2)) Then Mid$(strCommandLine, i, 1) = Chr$(0)
End If
Next i
End If
End If
If iCptQuotes > 0 Then
For i = 0 To UBound(aRes)
aRes(i) = Replace(aRes(i), Chr$(0), Chr$(32))
Next i
End If
ParseCommandLine = aRes
Erase aRes
End If
End Function
routine identique mais bien plus compacte ;)
à mettre sur codyx...
3 oct. 2006 à 17:47
voici un code fonctionnel (on m'a demandé ce code, je voulais filer une version claire...)
Private Sub Form_Load()
Dim i As Long
Dim xsParts() As String
xsParts = ParseCommandLine("")
For i = LBound(xsParts) To UBound(xsParts)
Debug.Print i, xsParts(i)
Next i
Unload Me
End Sub
Private Function ParseCommandLine(Optional ByVal vsCommandLine) As String()
Dim i As Long
Dim bInQuotes As Boolean
Dim nChar As Integer
'# Si aucune chaine avec les arguments de ligne de commande n'a été fournie...
If IsMissing(vsCommandLine) Then
'# On utilise celle recue par l'executable, obtenu grâce a la fonction Command$()
vsCommandLine = Trim$(Command$())
Else
'# sinon, on utilise celle effectivement fournie par l'utilisateur.
vsCommandLine = Trim$(vsCommandLine)
End If
If LenB(vsCommandLine) Then
'# On regarde la chaine, caractère par caractère
For i = 1 To Len(vsCommandLine)
'# On évite d'extraire deux fois le même caractère
nChar = AscW(Mid$(vsCommandLine, i, 1))
'# Si le caractère considéré est une guillemet, on incrémente le compteur
If nChar = 34 Then
bInQuotes = Not bInQuotes
'# si c'est un espace...
ElseIf nChar = 32 Then
'# ...et que nous sommes en dehors d'un 'tronçon' avec des guillemets,
'# on remplace l'espace par un carctère \0
If Not bInQuotes Then
Mid$(vsCommandLine, i, 1) = vbNullChar
End If
End If
Next i
'# tout tronçon de chaîne ouvert par des " doit être fermé
'# On teste donc si le nombre de guillemets est pair ou impair
If bInQuotes Then
Err.Raise vbString, , "Construction de la chaîne de paramètres incorrecte"
Else
'# On supprime les guillemets de la chaine finale
vsCommandLine = Replace(vsCommandLine, ChrW$(34), vbNullString)
'# On découpe la ligne de commande à chaque \0 rencontré
ParseCommandLine = Split(vsCommandLine, vbNullChar)
End If
Else
ReDim ParseCommandLine(0) As String
End If
End Function
7 sept. 2006 à 08:48
J'ai testé la fonction avec plusieurs cas de figure, cela marche parfaitement.
7 sept. 2006 à 02:54
++
6 sept. 2006 à 18:31
Quand à la simplicité du code, elle me parrait évidente : qu'est-ce qui est plus lisible : "if cBool(nQuotes and 1) Then..." ou "if not bQuotes Then..." ?
6 sept. 2006 à 13:28
et si cette proposition était valable (mais c'est pas le cas), je ne vois pas en quoi soudainement le code devient "plus simple" ;)
si?
6 sept. 2006 à 13:23
Déclarer bQuotes as boolean, et initialiser à true.
Ensuite dans la boucle de "comptage" des quotes, il suffit de faire bQuotes = not bQuotes.
Pour tester si c'est pair ou pas : if bQuotes then....
5 sept. 2006 à 20:56
Je ne connais que VB6 comme langage et tout ce que j'ai appris c'est sur ce site, je n'ai jamais pris aucun cours. Donc il me manque évidemment quelques bases importantes.
Comme dit plus haut : "je suis volontier preneur d'explication".
5 sept. 2006 à 20:41
If (i > 1) And (i < Len(strCommandLine)) Then
If Not CBool(nQuotes And 1) Then
If Mid$(strCommandLine, i + 1, 1) <> " " Then
strCommandLine = Left$(strCommandLine, i) & " " & Right$(strCommandLine, Len(strCommandLine) - i)
End If
End If
End If
marrant, sans CBool çà fausse tout ^^
5 sept. 2006 à 20:31
5 sept. 2006 à 20:26
If (i > 1) And (i < Len(strCommandLine)) Then
If nQuotes And 1 Then
If Mid$(strCommandLine, i + 1, 1) <> " " Then
strCommandLine = Left$(strCommandLine, i) & " " & Right$(strCommandLine, Len(strCommandLine) - i)
End If
End If
End If
5 sept. 2006 à 19:31
5 sept. 2006 à 18:16
"est-ce différent de 0 ?"
5 sept. 2006 à 18:14
5 sept. 2006 à 18:06
nop?
5 sept. 2006 à 18:01
C'est bien là que je ne trouve pas cela "normal".
False = 0
True = -1
Or, If bVar Then ..., ne devrait entrer dans la première partie du If que si bVar True donc -1.
Seulement si on fait, If 5 Then ... cela fonctionne également !
5 sept. 2006 à 17:55
400C0000 00000000
le bit droit est 0 donc résult 0 tout a fait normalement.
5 sept. 2006 à 17:44
pas mal interprété, non ....
(3.5 And 1) => 0
VB arrondit apparemment il doit y avoir un Cast vers un Long, en interne
5 sept. 2006 à 17:30
Néanmoins:
Renfield dit : lors d'opérations bit a bit, VB supprime la partie décimale...
(3.5 and 1) = 0, ne semble pas vérifier, ai-je mal interpreter ce qu'a dit Renfield?
5 sept. 2006 à 17:12
Lecture des manuels Intel (ce qu'un VBiste fait régulièrement...) indique clairement:
NOT => Flags affected: NONE
Quand je vous dis qu'il y a de la logique partout, he he.
5 sept. 2006 à 17:00
Certes, mais si bVar est un booléen, c'est quand même triste que Not bVar ne soit pas toujours correctement évalué !
Heureusement en DotNet avec compilation Strict, il est strictement impossible de se faire piéger ainsi comme en VB6, ou plus gravement comme en VBA
5 sept. 2006 à 16:17
VB/VBA/VBS ne dérogent (heureusement) pas à la règle, et un IF ne teste qu'une seule et unique chose :
que l'expression présente entre If et Then soit ou non différent de 0.
son évaluation, c'est encore autre chose...
mavar And 1 va effectuer une operation bit a bit, et générer une valeur numérique
(qui sera testée selon son égalité ou non avec 0)
rien d'autre a ajouter là dessus
5 sept. 2006 à 16:10
5 sept. 2006 à 16:08
donne un résultat sur registre EFlags (pas sur mavar puiqsque non affecté) seulement, le test est toujours sur 0 ou NON 0 dans tous les cas.
Il pourrait en aller autrement avec des 'objets' VB ou VBA mais sur des types primaires, If se comporte ici comme dans tout langage.
5 sept. 2006 à 16:03
5 sept. 2006 à 15:56
If mavar Then
' execute ok
End If
Je suis ok, mais pour :
If mavar And 1 Then OkExecute
Cela me parait moins evident.
Après je peux me tromper, si je mets ça dans le même sac que le reste (de certaines "non rigueurs" de VB) indûment. Dans ce cas je suis volontier preneur d'explication.
++
5 sept. 2006 à 15:31
If mavar Then
' execute ok
End If
'If' teste le NON 0 pour exécuter la condition comme dans tout langage normal, un cast superflu n'est en aucun cas de la rigueur programmatique, seulement perte de cycles car remplissage des bits à 1 (or eax, -1) totalement inutile.
If mavar And 1 Then OkExecute
sera traduit en:
test eax, 1
je LabelNON
il serait dommage d'en rajouter, non ?
5 sept. 2006 à 15:29
Elle renvoie "cmd.exe exe.exe" et ping
Mais elle fonctionne avec "cmd.exe exe.exe" /ping
PCPT > Codyx.Org est aussi là pour çà ;)
Oui mais j'ai trop l'habitude d'utiliser Google pour trouver ce que je cherche, car je n'aime pas attendre, et j'aime sa pertinence. Je me sert de Google pour retrouver la plupart des fonctions que j'utilise, car j'ai mis les sources de mes programmes sur le web grace à VBToHtml.
5 sept. 2006 à 15:04
Il est vrai que VB ne requiert pas le CBool dans le cas présent. Et je ne le met moi même jamais (ou presque).
Il s'agit à mon sens d'une des nombreuses 'fautes de programmation' que VB nous laisse faire. Certains diront souplesse, je préfère parler de fautes ou de code peu rigoureux que VB nous laisse programmer.
Ex : Utilisation de variables implicites, type casting...
Autre exemple :
Dim dVar As Double
Dim iVar as Integer
dVar = 3.2
iVar = dVar
Ceci ne posera pas non plus de problème !
++
5 sept. 2006 à 12:18
5 sept. 2006 à 11:59
c'est à cause de l'espace attendu avant le /ping...
5 sept. 2006 à 11:32
"cmd.exe exe.exe"/ping
le fichier cmd.exe exe.exe est evidament un seul fichier
5 sept. 2006 à 11:12
Bien qu'il ne soit pas requis dans de nombreux cas, il arrive que son absence soit génante :
a = 5
'# On teste si a est impair
If a And 1 Then
'# On arrive ici, c'est OK
End If
a = 5
'# On teste si a est pair
If Not (a And 1) Then
'# On arrive ici, ca n'est pas voulu
'# l'explication est simple :
'# a And 1 => 1
'# Not 1 => -2 et comme -2 est different de 0...
End If
a = 5
'# On teste si a est impair
If Not CBool(a And 1) Then
'# On n'arrive plus ici, c'est OK
End If
Pourtant, et bien que certains seront satisfaits de CBool, une petite discussion avec notre ami BruNews m'aura éclairé sur le fait qu'un cast est un cast et qu'il consomme des cycles...il n'est pas plus complexe de faire un test d'égalité avec 0 :
a = 5
'# On teste si a est pair
If (a And 1)=0 Then
'# On n'arrive pas ici, pas de souci
End If
il y a donc de fortes chances pour que j'abandonne CBool....
5 sept. 2006 à 10:31
5 sept. 2006 à 10:29
Asimengo, on ne joue ici qu'avec des nombres entiers
? 3.1 or 0
3
lors d'opérations bit a bit, VB supprime la partie décimale...
5 sept. 2006 à 10:21
5 sept. 2006 à 09:55
et
If CBool(nQuotes And 1) Then
ne donnent pas idem pour le If ???
Bizzare, If teste si condition <> 0, normalement pas autre chose donc devrait être équivalent en plus court.
5 sept. 2006 à 09:27
5 sept. 2006 à 09:22
CBool la transforme juste un Boolean (Vrai/Faux)
c'est une bonne habitude a prendre lorsque l'on fait des opérations bit à bit, en VB
le test
If CBool(nQuotes And 1) Then
est vrai si nQuotes est impair, c'est bien ce que l'on cherche...
5 sept. 2006 à 08:38
Quand vous avez des bouts de code comme ça, réutilisables et pas encore postés, ajoutez-les séparément, c'est bon pour tout le monde!
5 sept. 2006 à 08:28
Tu peux expliquer l'utilisation de CBool stp (vb me dit juste: Convertit une expression en Boolean) ?
Merci,
5 sept. 2006 à 08:28
http://patrice.dargenton.free.fr/CodesSources/Doc2Pdf.vbp.html#65
www.vbfrance.com/code.aspx?ID=29662
5 sept. 2006 à 08:26
c'est non affichable
5 sept. 2006 à 08:23
Ainsi que pour avoir corrigé ma gestion d'erreur qui provoquait elle-même une erreur!
Pour info.: chr(0), ça correspond à quel caractère (non affichable?) ?
5 sept. 2006 à 08:09
Private Function ParseCommandLine(Optional ByVal strCommandLine) As String()
Dim i As Long
Dim nQuotes As Integer
Dim sChar As String
'# Si aucune chaine avec les arguments de ligne de commande n'a été fournie...
If IsMissing(strCommandLine) Then
'# On utilise celle recue par l'executable, obtenu grâce a la fonction Command$()
strCommandLine = Trim$(Command$())
Else
'# sinon, on utilise celle effectivement fournie par l'utilisateur.
strCommandLine = Trim$(strCommandLine)
End If
If LenB(strCommandLine) = 0 Then
ReDim ParseCommandLine(0) 'pour éviter l'erreur de ton Main ; pas testé?!!
Else
'# On regarde la chaine, caractère par caractère
For i = 1 To Len(strCommandLine)
'# On évite d'extraire deux fois le même caractère
sChar = Mid$(strCommandLine, i, 1)
'# Si le caractère considéré est une guillemet, on incrémente le compteur
If sChar = ChrW$(34) Then
nQuotes = nQuotes + 1
'# si c'est un espace...
ElseIf sChar = " " Then
'# ...et que nous sommes en dehors d'un 'tronçon' avec des guillemets,
'# on remplace l'espace par un carctère \0
If Not CBool(nQuotes And 1) Then
Mid$(strCommandLine, i, 1) = vbNullChar
End If
End If
Next i
'# tout tronçon de chaîne ouvert par des " doit être fermé
'# On teste donc si le nombre de guillemets est pair ou impair
If CBool(nQuotes And 1) Then
Err.Raise vbString, , "Construction de la chaîne de paramètres incorrecte"
Else
'# On découpe la ligne de commande à chaque \0 rencontré
'strCommandLine = Replace(strCommandLine, ChrW$(34), vbNullString)
ParseCommandLine = Split(strCommandLine, vbNullChar)
End If
End If
End Function
nous avons PCPT et moi même laissé le résultat tel quel...
reste que je pense qu'il serait de bon ton de supprimer les guillemets, dans le resultat. J'ai mis en commentaire la ligne qu'il te suffit d'activer si tu souhaite effectivement supprimer les guillemets
4 sept. 2006 à 21:27
c'est plus qu'optimisable....
Private Function ParseCommandLine(ByVal strCommandLine As String) As String()
strCommandLine = Trim$(strCommandLine)
If LenB(strCommandLine) = 0 Then
ReDim ParseCommandLine(0) 'pour éviter l'erreur de ton Main ; pas testé?!!
Else
Dim i As Integer, iCptQuotes As Integer
Dim aRes() As String
iCptQuotes = 0
For i = 1 To Len(strCommandLine)
If Mid$(strCommandLine, i, 1) Chr$(34) Then iCptQuotes iCptQuotes + 1
Next i
'tout tronçon de chaîne ouvert par des " doit être fermé
If iCptQuotes > 0 Then
If (iCptQuotes / 2 <> Int(iCptQuotes / 2)) Then
Err.Raise vbString, , "Construction de la chaîne de paramètres incorrecte"
Else
iCptQuotes = 0
For i = 1 To Len(strCommandLine)
If Mid$(strCommandLine, i, 1) = Chr$(34) Then
iCptQuotes = iCptQuotes + 1
ElseIf Mid$(strCommandLine, i, 1) = Chr$(32) Then
If (iCptQuotes / 2 <> Int(iCptQuotes / 2)) Then Mid$(strCommandLine, i, 1) = Chr$(0)
End If
Next i
End If
End If
aRes = Split(strCommandLine, Chr$(32))
ReDim ParseCommandLine(UBound(aRes))
If iCptQuotes > 0 Then
For i = 0 To UBound(aRes)
aRes(i) = Replace(aRes(i), Chr$(0), Chr$(32))
Next i
End If
ParseCommandLine = aRes
Erase aRes
End If
End Function
routine identique mais bien plus compacte ;)
à mettre sur codyx...
++
PCPT [AFCK]