OVH Cloud OVH Cloud

je tourne en rond dans ma boucle + modulo 97

20 réponses
Avatar
---DGI972---
Bonjour,

J'ai besoin d'une lumière pour m'en sortir dans une boucle:
Le but est de générer un fichier csv avec un compteur du format:
*CCAQQQLLLSSSKK*
CC=01 (constante)
QQQ=Quantième du jour
L=1 (constante)
LL Compteur de 01 a 99 s'incrémente de 1 quand le compteur SSS passe à
11 21 31 etc..
SSS compteur de 001 à 999
KK contrôle de modulo 97

Je butte sur 2 Pb:

1/le Compteur LL step 11 (j'ai pasréussi non plus)
2/le contrôle de modulo 97 j'en ai trouvé des négatifs (bizarre non ?)

voici le lien de la formule pour 12 caractères
http://euler.ac-versailles.fr/webMathematica/reflexionpro/journees_premiere/arithmetiqueTL/arithmetiqueL.pdf

Voici mon code:

Dim Rep,fso,f,CAB,A,QUANT,QQQ,SSS,KK,L
Dim L0
Dim LL0
Dim SSS0
Set oFs=CreateObject("Scripting.FileSystemObject")
Const CC = "01" 'Centre=01'
L=0
strMESSAGE = "Nombre(s) "& vbCrLf & vbCrLf & _
LANG&" (L"&L&") ?" & vbCrLf & vbCrLf & _
vbCrLf & vbCrLf & _
" Pour tout annuler Effacez le zéro"

strTITRE = "Lot "&LANG&" (L"&L&")"
strLA = inputBox(strMESSAGE, strTITRE, strVal)
A=Mid(Year(Now),4,1)'Décennie de l'année'

QUANT=Date()-DateSerial(Year(Date()),1,1)+1 'Fabrication du quantième
if QUANT<100 then QUANT="0"&QUANT 'Quantième sur 3 caractères
if QUANT<10 then QUANT="0"&QUANT 'Quantième sur 3 caractères
QQQ=QUANT

Set oFile=oFs.OpenTextFile("C:\AF\AF_CAB.csv",2, True)
SSS0= strLA
if SSS0<>0 Then
SSS=1
LL0=1
L0=1
for CPT= 1 to SSS0
SSS=Right("000"&SSS,3)
LL0=Right("00"&LL0,2)
CAB0=CC&A&QQQ&L0&LL0&SSS

K1=Mid(CAB0,12,1)+Mid(CAB0,10,1)+Mid(CAB0,8,1)+Mid(CAB0,6,1)+Mid(CAB0,4,1)+Mid(CAB0,2,1)

K2=Mid(CAB0,11,1)+Mid(CAB0,9,1)+Mid(CAB0,7,1)+Mid(CAB0,5,1)+Mid(CAB0,3,1)+Mid(CAB0,1,1)
K=10-(((3*K1)+K2)Mod 97)'calcul mod 97 chiffre a 12 caractères'
KK=Right("00"&K,2)
CAB="*"&CAB0&KK&"*"
oFile.writeline CAB
SSS=SSS+1
if CPT = 11 or 21 or 31 or 41 or 51 or 61 or 71 or 81 or 91 then
LL0=LL0+1
next

OFile.Close
end if

Merci d'avance

10 réponses

1 2
Avatar
Jacques Barathon [MS]
"---DGI972---" <gilles.dermigny@*NO SPAM*laposte.net> wrote in message
news:
Ne vous inquiétez pas,je n'ai pas un mauvais esprit.


Pas de souci, alors!

Par contre mon LL est bien sur 2 caractères
LL SSS
01 001
01 002
....
01 010
02 011
02 012
....
02 019
02 020
03 021

et je n'arrive pas a l'incrémenter au passage du 011 021 031 etc ...
:'(


Perso, je n'incrémente pas, je recalcule à chaque fois, c'est plus simple...
:-)

La formule que j'applique consiste à diviser SSS par 10 et à prendre la
partie entière du résultat (fonction Int dans VBScript). Cette formule telle
quelle me donne la dizaine à laquelle appartient SSS. Comme dans ton exemple
la première dizaine (normalement 0) commence à 1, il faut ajouter 1 au
résultat. Et comme dans ta série chaque dizaine va de 1 à 10 au lieu de 0 à
9, j'enlève 1 à SSS avant de faire la division pour recaler le résultat. Ce
qui donne:

LL = INT( (SSS - 1) / 10) + 1

Après, il reste juste à gérer l'affichage de LL sur deux caractères - je ne
sais pas comment on fait en VBScript mais tu dois savoir.

Jacques

Avatar
Michel_D
Bonjour,

"---DGI972---" <gilles.dermigny@*NO SPAM*laposte.net> wrote in message
news:
Ne vous inquiétez pas,je n'ai pas un mauvais esprit.


Pas de souci, alors!

Par contre mon LL est bien sur 2 caractères
LL SSS
01 001
01 002
....
01 010
02 011
02 012
....
02 019
02 020
03 021

et je n'arrive pas a l'incrémenter au passage du 011 021 031 etc ...
:'(


Perso, je n'incrémente pas, je recalcule à chaque fois, c'est plus
simple... :-)

La formule que j'applique consiste à diviser SSS par 10 et à prendre la
partie entière du résultat (fonction Int dans VBScript). Cette formule
telle quelle me donne la dizaine à laquelle appartient SSS. Comme dans
ton exemple la première dizaine (normalement 0) commence à 1, il faut
ajouter 1 au résultat. Et comme dans ta série chaque dizaine va de 1 à
10 au lieu de 0 à 9, j'enlève 1 à SSS avant de faire la division pour
recaler le résultat. Ce qui donne:

LL = INT( (SSS - 1) / 10) + 1

Après, il reste juste à gérer l'affichage de LL sur deux caractères - je
ne sais pas comment on fait en VBScript mais tu dois savoir.

Jacques



D'aprés les prérequis (qui devrait être confirmer) il me semble que la
valeur ne doit pas bouger lorsque la valeur modulo 100 vaut 1 et donc si
c'est le cas on ne peut pas utiliser la méthode par le calcul.

LL SSS
01 001
01 002
....
01 010
02 011
02 012
....
02 019
02 020
03 021
....
07 090
08 091
....
08 101 => Pas d'incrémentation
....
08 110
09 111


Avatar
Michel_D
Bonjour,

"---DGI972---" <gilles.dermigny@*NO SPAM*laposte.net> wrote in message
news:
Ne vous inquiétez pas,je n'ai pas un mauvais esprit.


Pas de souci, alors!

Par contre mon LL est bien sur 2 caractères
LL SSS
01 001
01 002
....
01 010
02 011
02 012
....
02 019
02 020
03 021

et je n'arrive pas a l'incrémenter au passage du 011 021 031 etc ...
:'(


Perso, je n'incrémente pas, je recalcule à chaque fois, c'est plus
simple... :-)

La formule que j'applique consiste à diviser SSS par 10 et à prendre
la partie entière du résultat (fonction Int dans VBScript). Cette
formule telle quelle me donne la dizaine à laquelle appartient SSS.
Comme dans ton exemple la première dizaine (normalement 0) commence à
1, il faut ajouter 1 au résultat. Et comme dans ta série chaque
dizaine va de 1 à 10 au lieu de 0 à 9, j'enlève 1 à SSS avant de faire
la division pour recaler le résultat. Ce qui donne:

LL = INT( (SSS - 1) / 10) + 1

Après, il reste juste à gérer l'affichage de LL sur deux caractères -
je ne sais pas comment on fait en VBScript mais tu dois savoir.

Jacques



D'aprés les prérequis (qui devrait être confirmer) il me semble que la
valeur ne doit pas bouger lorsque la valeur modulo 100 vaut 1 et donc si
c'est le cas on ne peut pas utiliser la méthode par le calcul.


Petite rectification dans la suite mais qui ne remet pas en cause le fond du
problème :

LL SSS
01 001
01 002
.....
01 010
02 011
02 012
.....
02 019
02 020
03 021
.....
09 090
10 091
.....
10 101 => Pas d'incrémentation
.....
10 110
11 111



Avatar
---DGI972---
Bonjour,

"Jacques Barathon [MS]" wrote in message
news:%
Personnellement j'ai toujours trouvé VBScript plus difficile à
appréhender que PowerShell, mais c'est sans doute une question d'état
d'esprit. :-)


Je voulais parler de "tournure d'esprit" et non pas d'état d'esprit...
Encore que, parfois!

Jacques


Ne vous inquiétez pas,je n'ai pas un mauvais esprit.

Par contre mon LL est bien sur 2 caractères
LL SSS
01 001
01 002
.....
01 010
02 011
02 012
.....
02 019
02 020
03 021

et je n'arrive pas a l'incrémenter au passage du 011 021 031 etc ...



Essaye avec ce que suit :

If (CPT Mod 100)>1 And (CPT Mod 10)=1 Then LL0=LL0+1


non ca marche pas comme je veux c'est pareil que CPT-1
:'(




Avatar
---DGI972---
Bonjour,

"---DGI972---" <gilles.dermigny@*NO SPAM*laposte.net> wrote in message
news:
Ne vous inquiétez pas,je n'ai pas un mauvais esprit.


Pas de souci, alors!

Par contre mon LL est bien sur 2 caractères
LL SSS
01 001
01 002
....
01 010
02 011
02 012
....
02 019
02 020
03 021

et je n'arrive pas a l'incrémenter au passage du 011 021 031 etc ...
:'(


Perso, je n'incrémente pas, je recalcule à chaque fois, c'est plus
simple... :-)

La formule que j'applique consiste à diviser SSS par 10 et à prendre la
partie entière du résultat (fonction Int dans VBScript). Cette formule
telle quelle me donne la dizaine à laquelle appartient SSS. Comme dans ton
exemple la première dizaine (normalement 0) commence à 1, il faut ajouter
1 au résultat. Et comme dans ta série chaque dizaine va de 1 à 10 au lieu
de 0 à 9, j'enlève 1 à SSS avant de faire la division pour recaler le
résultat. Ce qui donne:

LL = INT( (SSS - 1) / 10) + 1

Après, il reste juste à gérer l'affichage de LL sur deux caractères - je
ne sais pas comment on fait en VBScript mais tu dois savoir.

Jacques



D'aprés les prérequis (qui devrait être confirmer) il me semble que la
valeur ne doit pas bouger lorsque la valeur modulo 100 vaut 1 et donc si
c'est le cas on ne peut pas utiliser la méthode par le calcul.


Petite rectification dans la suite mais qui ne remet pas en cause le fond du
problème :

LL SSS
01 001
01 002
.....
01 010
02 011
02 012
.....
02 019
02 020
03 021
.....
09 090
10 091
.....
10 101 => Pas d'incrémentation
.....
10 110
11 111


Si Si il doit y avoir une incrémentation au passage de 101.
En fait LL est un compteur de lot
un lot est constitué de 10 documents maximun
donc au 11 ième document le compteur de lot s'incrémente de 1.




Avatar
Michel_D
Bonjour,

"---DGI972---" <gilles.dermigny@*NO SPAM*laposte.net> wrote in
message news:
Ne vous inquiétez pas,je n'ai pas un mauvais esprit.


Pas de souci, alors!

Par contre mon LL est bien sur 2 caractères
LL SSS
01 001
01 002
....
01 010
02 011
02 012
....
02 019
02 020
03 021

et je n'arrive pas a l'incrémenter au passage du 011 021 031 etc ...
:'(


Perso, je n'incrémente pas, je recalcule à chaque fois, c'est plus
simple... :-)

La formule que j'applique consiste à diviser SSS par 10 et à prendre
la partie entière du résultat (fonction Int dans VBScript). Cette
formule telle quelle me donne la dizaine à laquelle appartient SSS.
Comme dans ton exemple la première dizaine (normalement 0) commence
à 1, il faut ajouter 1 au résultat. Et comme dans ta série chaque
dizaine va de 1 à 10 au lieu de 0 à 9, j'enlève 1 à SSS avant de
faire la division pour recaler le résultat. Ce qui donne:

LL = INT( (SSS - 1) / 10) + 1

Après, il reste juste à gérer l'affichage de LL sur deux caractères
- je ne sais pas comment on fait en VBScript mais tu dois savoir.

Jacques



D'aprés les prérequis (qui devrait être confirmer) il me semble que la
valeur ne doit pas bouger lorsque la valeur modulo 100 vaut 1 et
donc si
c'est le cas on ne peut pas utiliser la méthode par le calcul.


Petite rectification dans la suite mais qui ne remet pas en cause le
fond du
problème :

LL SSS
01 001
01 002
.....
01 010
02 011
02 012
.....
02 019
02 020
03 021
.....
09 090
10 091
.....
10 101 => Pas d'incrémentation
.....
10 110
11 111


Si Si il doit y avoir une incrémentation au passage de 101.
En fait LL est un compteur de lot
un lot est constitué de 10 documents maximun
donc au 11 ième document le compteur de lot s'incrémente de 1.



Dans ce cas comme la valeur 1 doit être écartée :

If CPT>1 And (CPT Mod 10)=1 Then LL0=LL0+1





Avatar
---DGI972---
Bonjour,

"---DGI972---" <gilles.dermigny@*NO SPAM*laposte.net> wrote in message
news:
Ne vous inquiétez pas,je n'ai pas un mauvais esprit.


Pas de souci, alors!

Par contre mon LL est bien sur 2 caractères
LL SSS
01 001
01 002
....
01 010
02 011
02 012
....
02 019
02 020
03 021

et je n'arrive pas a l'incrémenter au passage du 011 021 031 etc ...
:'(


Perso, je n'incrémente pas, je recalcule à chaque fois, c'est plus
simple... :-)

La formule que j'applique consiste à diviser SSS par 10 et à prendre la
partie entière du résultat (fonction Int dans VBScript). Cette formule
telle quelle me donne la dizaine à laquelle appartient SSS. Comme dans
ton exemple la première dizaine (normalement 0) commence à 1, il faut
ajouter 1 au résultat. Et comme dans ta série chaque dizaine va de 1 à
10 au lieu de 0 à 9, j'enlève 1 à SSS avant de faire la division pour
recaler le résultat. Ce qui donne:

LL = INT( (SSS - 1) / 10) + 1

Après, il reste juste à gérer l'affichage de LL sur deux caractères - je
ne sais pas comment on fait en VBScript mais tu dois savoir.

Jacques



D'aprés les prérequis (qui devrait être confirmer) il me semble que la
valeur ne doit pas bouger lorsque la valeur modulo 100 vaut 1 et donc si
c'est le cas on ne peut pas utiliser la méthode par le calcul.


Petite rectification dans la suite mais qui ne remet pas en cause le fond
du
problème :

LL SSS
01 001
01 002
.....
01 010
02 011
02 012
.....
02 019
02 020
03 021
.....
09 090
10 091
.....
10 101 => Pas d'incrémentation
.....
10 110
11 111


Si Si il doit y avoir une incrémentation au passage de 101.
En fait LL est un compteur de lot
un lot est constitué de 10 documents maximun
donc au 11 ième document le compteur de lot s'incrémente de 1.



Dans ce cas comme la valeur 1 doit être écartée :

If CPT>1 And (CPT Mod 10)=1 Then LL0=LL0+1


non ca marche pas le lot s'incrémente aprés le 012

*0181071 01 009 56*
*0181071 01 010 55*
*0181071 01 011 54*
*0181071 02 012 23*

mais il semblerait que la formule magique de M Jacques Barathon
fonctionne, j'ai éssayé jusqu'a SSS0™9 et le résultat me semble
correcte:

LL0 = INT( (SSS - 1) / 10) + 1

Merci je sors enfin de cette impasse pour moi
merci encore






Avatar
---DGI972---
"---DGI972---" <gilles.dermigny@*NO SPAM*laposte.net> wrote in message
news:
Ne vous inquiétez pas,je n'ai pas un mauvais esprit.


Pas de souci, alors!

Par contre mon LL est bien sur 2 caractères
LL SSS
01 001
01 002
....
01 010
02 011
02 012
....
02 019
02 020
03 021

et je n'arrive pas a l'incrémenter au passage du 011 021 031 etc ...
:'(


Perso, je n'incrémente pas, je recalcule à chaque fois, c'est plus simple...
:-)

La formule que j'applique consiste à diviser SSS par 10 et à prendre la
partie entière du résultat (fonction Int dans VBScript). Cette formule telle
quelle me donne la dizaine à laquelle appartient SSS. Comme dans ton exemple
la première dizaine (normalement 0) commence à 1, il faut ajouter 1 au
résultat. Et comme dans ta série chaque dizaine va de 1 à 10 au lieu de 0 à
9, j'enlève 1 à SSS avant de faire la division pour recaler le résultat. Ce
qui donne:

LL = INT( (SSS - 1) / 10) + 1

Après, il reste juste à gérer l'affichage de LL sur deux caractères - je ne
sais pas comment on fait en VBScript mais tu dois savoir.

Jacques


Merci M Barathon

ca marche comme je le souhaite et avec un petit:

LL=Right("00"&LL,2)

je l'ai bien sur 2 caractères.

Merci encore


Avatar
---DGI972---
Re-bonsoir,

--------------------------------------------------------------------------------------
Pour une raison obscure,
les sauts de ligne de la seconde partie ont été dévorés ...

re-voici donc une version lisible ....
---------------------------------------------------------------------------------------

J'avoue ne pas bien comprendre ton code ...
Je me contente de traiter les pb que tu soulèves.

1. Que fait vraiment
la ligne " if CPT = 11 or 21 or 31 or ... ... "

Concrètement, je pense que la machine compare CPT
avec le OU logique entre toutes ces valeurs
(ce qui devrait donner 127 si je ne m'abuse...)
Est-ce là ce que tu désires ? ;o)

Si le compteur SSS peut aller jusqu'à 999
LL0, qui s'incrémente quant le chiffre des unités de SSS vaut 1
tester le chiffre des unités ...
C'est à dire
ChiffreUnit = SSS - 10*int(SSS/10)
ou plus chic
ChiffreUnit = SSS - 10*(SSS10)

puis , il faut poser


If ChiffreUnit = 1 then

LL0 = LL0 + 1
End If

2. KK doit-il être le reste modulo 97 du "nombre"

01AQQQ1LLSSS
ou son complément à 97 ?
( comme les codes de contrôle du N° INSEE)

Quoi qu'il en soit ce calcul

============ >> K1=Mid(CAB0,12,1)+Mid(CAB0,10,1 ... etc K2=Mid(CAB0,11,1)+Mid(CAB0,9,1) ...
etc..
K-(((3*K1)+K2)Mod97)

============= > est faux.

Déjà,

ce calcul ne donnera pas forcément un positif
... puique on calcule
10 moins [un nombre entre 0 et 96]...

La méthode classique pour un nb de
12 chiffres, expliquée dans le document
que tu cites en référence
consiste à prendre les 6 chiffres du haut
et les 6 du bas :

Haut = left(CAB0,6)
Bas = Right(CAB0,6)

ensuite on calcule

ResteHaut =Haut Mod 97
resteBas = Bas Mod 97

et, sachant que le reste mod 97 de 10^6 est 27
on en déduit

Reste = (27*ResteHaut + ResteBas) Mod 97

Le petit VBS suivant calcule la clé du numéro INSEE
( qui est à 13 chiffres soit 7 + 6 )

=========== VBS 1 coupez là =============== > NUM = inputbox("N° INSEE sans La clé : ")
Haut = left(NUM,7)
Bas = Right(NUM,6)
ResteHaut = Haut Mod 97
resteBas = Bas Mod 97
Reste = (27*ResteHaut + ResteBas) Mod 97
CL = 97 - Reste
CLE = right("00" & CL,2)

Msgbox "La clé est " & CLE
========== VBS 1 coupez là ============== >
On peut envisager une procédure récursive pour
calculer ce code de contrôle pour tout "numéro" de N chiffres

Dans la proposition ci-dessous,
je découpe les 4 chiffres de droite...
(le reste de 10^4 module 97 est 9)

La validité de la saisie
( que des chiffres) est préalablement vérifiée.
Ce second script étant plus polyvalent,
il mérite peut-être d'être conservé ;o)

========= VBS 2 coupez là ============== > Nombre = InputBox("Plein de chiffres : ")
PasBon = False
for i = 1 to len(Nombre)
C = asc(mid(Nombre,i,1))
PasBon = PasBon Or C<48 Or C>57
next
If PasBon then
Msgbox "Saisie incorrecte !"
else
CL = 97 - Reste(Nombre)
CLE = right("00" & CL,2)
msgbox "Clé : " & CLE
end if
' --------------------------------------------

Function Reste(XXX)
dim RB, RH
dim NbCh, B

NbCh = len(XXX)
If NbCh > 4 then
B = Right(XXX,4)
RB = B Mod 97
RH = Reste(Left(XXX,NbCh-4))
Reste = (9*RH + RB) Mod 97
Else
Reste = XXX mod 97
End If
End Function
========== VBS 2 coupez là =========== >

A+

HB


Effectivement c'est beaucoup mieux avec les retours chariots
la fonction Reste fonctionne a merveille.
Mon Modulo 97 est maintenant correcte

Merci encore


Avatar
Michel_D

[..]

Dans ce cas comme la valeur 1 doit être écartée :

If CPT>1 And (CPT Mod 10)=1 Then LL0=LL0+1


non ca marche pas le lot s'incrémente aprés le 012


Car tu utilise la valeur au début de la boucle et tu incrémente à la fin de
la boucle donc en fait il faut incrémenter lorsque le modulo 10 = 0 et non
pas lorsque le modulo 10 = 1, ce qui donne donc :

If (CPT Mod 10)=0 Then LL0=LL0+1


*0181071 01 009 56*
*0181071 01 010 55*
*0181071 01 011 54*
*0181071 02 012 23*

mais il semblerait que la formule magique de M Jacques Barathon
fonctionne, j'ai éssayé jusqu'a SSS0™9 et le résultat me semble correcte:

LL0 = INT( (SSS - 1) / 10) + 1

Merci je sors enfin de cette impasse pour moi
merci encore



1 2