COMPTEUR AVEC VALEUR PRÉCÉDÉE DE ZÉRO

yomm Messages postés 515 Date d'inscription dimanche 17 février 2002 Statut Membre Dernière intervention 10 mars 2008 - 24 mars 2004 à 16:58
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015 - 28 mars 2004 à 22:09
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/21444-compteur-avec-valeur-precedee-de-zero

cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
28 mars 2004 à 22:09
Salut Vers_ion,
Je tiens une partie de l'aide, une autre de mon experience dans ce langage.
Le test qui tue :
dim x as long
dim str as String
for x = 1 to 10000
'lignes à commenter pour voir la différences
str = x 'cas 1
str = CStr(x) ' cas 2
next
il y a plusieurs secondes de différences de traitement.
Il faut pour faire un programme efficace avoir la même rigueur sur la gestion de la mémoire qu'en C
VeRs_iOn Messages postés 22 Date d'inscription jeudi 11 mars 2004 Statut Membre Dernière intervention 26 mars 2004
28 mars 2004 à 20:02
merci pour ces précisions...d'où les tiens tu ?
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
27 mars 2004 à 19:42
Vers_ion -> Je vais t'apporter quelques réponses qui vont parfaitement conforter tes dires...
Le vb sait parfaitement faire des conversions implicites. En gros, quand on passe une valeur à une variable, le programme teste si la valeur est du bon type, si ce n'est pas le cas, il cherchera à utiliser TOUS les convertisseurs possibles pour que ça fonctionne. Si aucun convertisseur n'est disponible on a une erreur de type incompatible.
Le problème c'est que ça rame, et que de temps en temps on a des TRES mauvaises surprises. Par exemple les lignes suivantes donnent des résultats très fantaisistes et pas toujours cohérents :
"2" + 2 donne "22" mais 2 + "2" peut donner 4 ou "22" selon la version du VB.
Pour éviter ces problèmes, le vb nous offre un mécanisme de conversion explicite. Les fonctions sont les suivantes :
CStr (renvoie une string avec une conversion de date au format très aléatoire)
CDbl et CDate qui renvoient un double (une date est stockée dans un double en jour depuis le 01/01/1900 ou 31/12/1899 en fonction du sytème d'exploitation et à cause d'un vieux bug corrigé depuis qui consistait à traiter le 29/02/1900 comme une date valide)
CByte, CInt et CLng renvoient des entiers sur 1, 2 et 4 octets respectivement
Je n'utilise pas les deux dernières, et je ne suis pas sûr de la syntaxe : CCurrency et CSingle
Tout ceci pour dire que la meilleur optimisation d'un code avec conversion de type c'est ça si on ne connait pas le type d'entré :
Function (nbre As Variant)
Dim _nbre as Long
_Nbre = CLng(nbre)
...
End Function
yomm Messages postés 515 Date d'inscription dimanche 17 février 2002 Statut Membre Dernière intervention 10 mars 2008 3
27 mars 2004 à 16:49
LOL ;-)
VeRs_iOn Messages postés 22 Date d'inscription jeudi 11 mars 2004 Statut Membre Dernière intervention 26 mars 2004
27 mars 2004 à 13:58
ben oui mais non ça a vraiment AUCUN EFFET, comme dit plus haut, ni pour les erreurs ni pour quoi que ce soit d'autre...

+ ;)
yomm Messages postés 515 Date d'inscription dimanche 17 février 2002 Statut Membre Dernière intervention 10 mars 2008 3
26 mars 2004 à 19:05
on continu la chaine de commentaire histoire de faire des commentaire: :D

en fait c'est juste histoire de pourvoir vérifié avant de mettre la valeur dans la variable ;-) histoire de pas générer d'erreur

@+
VeRs_iOn Messages postés 22 Date d'inscription jeudi 11 mars 2004 Statut Membre Dernière intervention 26 mars 2004
26 mars 2004 à 18:08
lu, je continue dans la série je-me-prends-la-tête-pour-3-lignes-de-code :D

je ne connais pas le fonctionnement de vb à fond, mais je pense que si jamais tu passes une valeur numérique à une fonction qui demande explicitement une string, vb la convertira avant, et passera effectivement une string à l'éxécution de la procédure...ce qui est rassurant, car ça permet d'être sur que toutes les variables passées dans une procédure sont vraiment du type attendu (sinon conversion, ou erreur)

ton cstr est donc bien inutile...

@+
yomm Messages postés 515 Date d'inscription dimanche 17 février 2002 Statut Membre Dernière intervention 10 mars 2008 3
26 mars 2004 à 14:50
>>zebiker
autre chose tu peux télécharger le zip ki te montrera facilement comment l'utiliser :-)
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
26 mars 2004 à 14:35
Il faut d'abord que tu créé un module de classe qui s'appelerait CCompteur.
Tu copies le code et tu ajoutes évetuellement les améliorations proposées. Je t'invite même à y réfléchir.

Ensuite dans le même projet tu fais :

Dim Compteur as New CCompteur
Compteur.Increment
Dim x as String
x = Compteur.Value '<-- récupération de la valeur

Tu peux utiliser Value comme une variable. Je t'invite à consulter l'aide en ligne sur les propriétés (Properties) pour en apprendre plus.
zebiker Messages postés 34 Date d'inscription vendredi 10 janvier 2003 Statut Membre Dernière intervention 12 novembre 2008
26 mars 2004 à 14:27
dsl de casser le niveau de vos discussions, mais comment ca marche pour recuperer la valeur du compteur ????
merci
yomm Messages postés 515 Date d'inscription dimanche 17 février 2002 Statut Membre Dernière intervention 10 mars 2008 3
26 mars 2004 à 10:15
alors nouveau petit commentaire ;-)
voici un copier-coler de mon premier pour expliquer :
Public Property Let Value(ByVal vValue As String)
mValue = Trim(CStr(vValue))
End Property

------------------------------------------------------------------------------
petiti truc tout de même, pour définir la valeur (à 50 par exemple) du compteur on est pas obligé d'écrire :
MonCompteur.Value = "050"
mais on peut se contenter de
MonCompteur.Value = 50
------------------------------------------------------------------------------

Donc voilà, la fonction demande en paramètre un String en effet...mais pour facilité la manipulation on peut prendre la liberté de mettre une valeur ......voilà pourquoi je convertis un string en string ;-)

Voilà ....à VeRs_iOn et moi ça devrai faire un truc pas trop mal ;-)

@+
VeRs_iOn Messages postés 22 Date d'inscription jeudi 11 mars 2004 Statut Membre Dernière intervention 26 mars 2004
25 mars 2004 à 21:14
oui bon d'accord, petire erreur ^^

je te bats, puisque je l'ai fait en 2 min, il est vrai en utilisant honteusement le copier-coler

pour nous remettre à égalité, voilà une erreur de ta part :
Public Property Let Value(ByVal vValue As String)
mValue = Trim(CStr(vValue))
End Property

tu convertis un string en string, voilà qui est assez inutile ! ^^

pour la gestion des valeurs négatives, j'avais pensé à ton truc mais je l'ai perdu dans le feu de l'action, alors bien joué :D

@llez +
yomm Messages postés 515 Date d'inscription dimanche 17 février 2002 Statut Membre Dernière intervention 10 mars 2008 3
25 mars 2004 à 21:02
petit truc ke je viens de noté....
Tu ne fait pas référence à Min...Donc petit complément juste pour dire ke la méthode a utiliser est la même pour Min...
en modifiant le les procédure Min et Max ainsi:

Public Property Get Max() As Integer
Max = mMax
End Property
Public Property Let Max(ByVal xMax As Integer)
mMax = xMax
if len(cstr(Abs(mmax))) > len(formatcompteur) then = string(len(cstr(abs(mmax))),"0")
End Property

Public Property Get Min() As Integer
Min = mMin
End Property
Public Property Let Min(ByVal vMin As Integer)
mMin = vMin
if len(cstr(Abs(vMin))) > len(formatcompteur) then = string(len(cstr(abs(mMin))),"0")
End Property

Et oui,vu ke VeRs_iOn parle de valeur négatives, autant le gérer maintenant ;-) ... j'ai pas testé mais ça me semble correcte....
yomm Messages postés 515 Date d'inscription dimanche 17 février 2002 Statut Membre Dernière intervention 10 mars 2008 3
25 mars 2004 à 20:39
>> VeRs_iOn
Non, tu te trompes je répondrais ke j'ai fais ça pour les nombres positifs LOL (merci de l'erreur non vonlu mais elle m'arange bien ;-) )

sinon ta méthode semble tout a fait correct..je vais pas testé ...mais je vois pas de problème à première vu...moi j'ai pri pour habitude te toujours mettre de Trim(CStr(valeur)) mais c'est juste un reflexe preso au cas ou j'utilise Str au lieur de CStr (d'ailleurs je fais bien car dans ce source le cas s'est présenté ;-) )

C'est vrai ke je fais de l'économie de variable .... ;-) et ke passé par une variable de longueur de chaine est un bon compromi !!!Je dirai pour ma défence ;-) ke j'ai fai ça en 5 minutes (au boulot mais faut pas le dire LOL) en réponse à une question sur le forum LOL (regardz moi ce type ki cherche des excuz bidon LOL....)

Enfin voilà, je trouve ta remark util et merci à toi.....
VeRs_iOn Messages postés 22 Date d'inscription jeudi 11 mars 2004 Statut Membre Dernière intervention 26 mars 2004
25 mars 2004 à 20:12
Plus simple :D

Public Min As Integer

Private mMax As Integer
Private mValue As Integer
Private formatcompteur as string

Public Property Get Max() As Integer
Max = mMax
End Property

Public Property Let Max(ByVal xMax As Integer)
mMax = xMax
formatcompteur = string(len(cstr(mmax)),"0")
End Property

Public Sub Init()
mValue = mMin
End Sub

Private Sub Class_Initialize()
mValue = 0
mMin = 0
mMax = 999
formatcompteur = "000"
End Sub

Public Sub Increment()
If mValue < mMax Then mValue = mValue + 1
End Sub

Public Sub Decrement()
If mValue > mMin Then mValue = mValue - 1
End Sub

Public Property Get Value() As String
Value = format(mvalue, formatcompteur)
End Property

Public Property Let Value(ByVal vValue As String)
mValue = cint(val(vValue))
End Property

je l'ai pas testé mais ça doit marcher, même pour les nombres négatifs (le tien devrait logiquement les écrire sous la forme "0-12", "00-3" etc..., ce qui n'est pas très sérieux, même si tu répondras sans doute que tu n'as fait ça que pour les nombres négatifs)
yomm Messages postés 515 Date d'inscription dimanche 17 février 2002 Statut Membre Dernière intervention 10 mars 2008 3
25 mars 2004 à 18:34
merci de tes remark ........merci des tes conseils et de l'info quant au CStr .....mais c'est bon je connais et si tu regarde mon code c'est d'ailleurs ce que j'utilise!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Donc tu ne m'apprend rien....(même si j'avou l'avoir oublié pour une conversion).......Quant à Format(nb,"0") c'est vrai ke c'est netement plus simple ke CStr (là je me lache car je trouve ça un peu gros comme remark...)
et puis ce que j'aime bien c'est qu'entre tes deux posts....la fonction left s'est transformée en right ;-) ....j'avais pas fait la remark car j'en avais déjà assez dit....enfin bref...

Tout ça pour dire que la prochaine fois que tu ve commenté un source en affirmant direct: "Salut, plus simple" .......réfléchi a deux fois.....je suis plutôt du genre cool mais y a des c0n partout et tu pourrais un jour tomber sur un gars moins diplomate ;-) .... de plus je suis ouvert à tout commentaire si tu lis les posts des mes autres sources...ce n'est pas la critik ki me dérange dans ton post mais le fait ke tu balance " Salut, plus simple" alors ke ton code ne marche pas!!!!

sur ce ke tu proposes je fais le récapitulatif des erreurs:

pour : Value = Format$(mValue, String$("0",len(mMax)))
-par exemple si mMax=999 =>len(mMax) renvoie 2 au lieu de 3 comme tu le souhaiterais
-String$("0",999) renvoi "" au lieu de "000" comme tu le souhaiterais
-heureusement au moins que Format(50,"000") donne bien "050" sinon rien de ce que propose cette solution ne marcherait

pour : Value = left(String("0",len(mMax)) & mValue, len(mMax))
-pas de commentaire sur String("0",len(mMax) vu ke c'est c'est écrit juste au dessus mais rien que dans ça y a déjà 2 erreurs ce qui fait 3 vu ke tu utilise de nouveau len(mMax) juste après
-pour left("000" & "1",3) comme pour left("000" & "11",3) ou pour left("000" & "111",3) le réultat est "000" et oui la fonction a utiliser est right et non left......

ton code est plus simple je suis tout à fait d'accord.....domage k'okune des deux solutions ke tu propose ne fonctionne ;-)

Mais t'en fais pas je ne t'en ve pas.....je voulais juste mettre les choses au clair pour des newbi ki lirai ça ......et ki instinctivement modifirai mon source avec ton "amélioration".....
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
25 mars 2004 à 17:30
Je n'ai effectivement pas testé mon code.
Il est d'ailleur probable que len(mMax) me renvoi la taille en octet de la valeur numérique (soit 2 parce integer représente 2 octets)
Pour bien faire il faudrait rajouter len(Trim(Cstr(mMax))) qui renvoie bien la taille de la chaine de caractère.
En fait il bien plus rapide de calculer une fois pour toute les 3 ou 4 zéros et d'utiliser la fonction format ou right(zero & chaine, len(...)) parce que tu ne recalcule plus la longueur de la chaine.
Pour éviter le " " devant tu peux utiliser la conversion explicite (CStr) plutot que la fonction de conversion (Str) ou plus simplement Format(nb,"0")
yomm Messages postés 515 Date d'inscription dimanche 17 février 2002 Statut Membre Dernière intervention 10 mars 2008 3
25 mars 2004 à 17:28
au fait j'ai testé la ta deuxième proposition sous vb également ....
avec les mêmes valeur de test soit 50 et 999 j'ai le même résultat : "50"
donc si c'est ton but y a plus simple
Value = Trim(CStr(mValue))
et là je suis d'accord si mValue 50 alors Value "50"
mais c'est pas le but de ce programme ;-)

sinon pour info:
si mMax = 999
len(mMax)=2 pour VB
et
String("0", Len(mMax)) = ""
donc merci de ton commentaire voulant simplifier ce que j'ai fait mais tu comprendras aisément je pense que je ne vais pas utiliser ce que tu as fait......

PS:Je rappelle que c'est pas méchament que je te dis ça...simplement tu ve simplifier mon code (ce qui sous-entends que mon code n'est pas top...) aucun problème c'est une bonne démarche....mais assure toi que ce que tu proposes fonctionne correctement ;-)
yomm Messages postés 515 Date d'inscription dimanche 17 février 2002 Statut Membre Dernière intervention 10 mars 2008 3
25 mars 2004 à 17:20
>> Warny
merci pour ta remarque mais as tu testé ton code? C'est pas méchant ce ke je di mais :
exemple:
si mValue =50
si mMax = 999
alors Format$(mValue, String$("0", Len(mMax))) donne: "50"
c'est pas vraiment le but rechercher!!!!!

Petit commentaire supplémentaire:
premier truc a savoir : évite d'utiliser les fonctions demandant des String en paramètre en passant de Integer en directe car VB à quelques fois un comportement étrange!!!! Juste un exmple :
Dim Toto As String

Toto = Str(5) 'Str  converti une valeur en texte
Debug.Print Len(Toto)


resultat de la manip: 2
et oui toto = " 2"

Voilà pourquoi mon code est un peu plus lourd mais au moins je maitrise entièrement les valeurs de mes variables...et ça évite des bugs éventuels ;-)
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
25 mars 2004 à 15:19
Salut, plus simple
Public Property Get Value() As String
Value = Format$(mValue, String$("0",len(mMax)))
End Property

ou (pour le fonctionnement en vbs)
Public Property Get Value() As String
Value = left(String("0",len(mMax)) & mValue, len(mMax))
End Property
yomm Messages postés 515 Date d'inscription dimanche 17 février 2002 Statut Membre Dernière intervention 10 mars 2008 3
24 mars 2004 à 16:58
petiti truc tout de même, pour définir la valeur (à 50 par exemple) du compteur on est pas obligé d'écrire :
MonCompteur.Value = "050"
mais on peut se contenter de
MonCompteur.Value = 50

Voilà ce code est sans prétention...c'est juste que plutôt que de le mettre en réponse sur le post d'origine , je me suis qu'il serait plus accessible à tout le monde en faisant un source...
Rejoignez-nous