je tourne en rond dans ma boucle + modulo 97

Le
---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 (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'
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Úte()-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:AFAF_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Ì&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-(((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
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
moi
Le #3764461
Bonsoir

---DGI972--- wrote:
J'ai besoin d'une lumière pour m'en sortir dans une boucle:
(...)




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 suivante ?
if CPT = 11 or 21 or 31 or 41 or 51 or 61 or 71 or 81 or 91 then
LL0 = LL0 +1

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
doit 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 = 0 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 ton calcul est faux :
============ 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-(((3*K1)+K2)Mod97)==============Déjà, ce calcul ne donnera pas forcément un positif ...puique on calcule10 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érenceconsiste à prendre les 6 chiffres du haut et les 6 du bas :Haut = left(CAB0,6)Bas = Right(CAB0,6)ensuite on calculeResteHaut = Haut Mod 97resteBas = Bas Mod 97et, sachant que le reste mod 97 de 10^6 est 27on en déduitReste = (27*ResteHaut + ResteBas) Mod 97Le 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 97resteBas = Bas Mod 97Reste = (27*ResteHaut + ResteBas) Mod 97CL = 97 - ResteCLE = 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 decontrôlepour tout "numéro" de N chiffresdans la proposition ci-dessous, je découpe les 4 chiffres de droite...(le reste de 10^4 module 97 est 9)============= VBS 2 coupez là ===============Nombre = InputBox("Le nombre avec plein de chiffres ")PasBon = Falsefor i = 1 to len(Nombre)C = asc(mid(Nombre,i,1))PasBon = PasBon Or C<48 Or C>57nextIf PasBon then Msgbox "Saisie incorrecte !"else CL = 97 - Reste(Nombre)CLE = right("00" & CL,2)msgbox "Clé : " & CLEend if' --------------------------------------------Function Reste(XXX)dim Bas, ResteBas,ResteHautdim NombreChiffresNombreChiffres = len(XXX)If NombreChiffres > 4 thenBas = Right(XXX,4)ResteBas = Bas Mod 97ResteHaut = Reste(Left(XXX,NombreChiffre-4))Reste = (9*ResteHaut + ResteBas) Mod 97ElseReste = XXX mod 97End IfEnd Function============= VBS 2 coupez là ===============La validité de la saisie ( que des chiffres) est vérifiée.Ce second script étant plus polyvalent,il mérite peut-être d'être conservé ;o)A+HB

moi
Le #3764451
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

---DGI972---
Le #3764441
Bonsoir,

Je reconnais c'est très brouillon et moi même je ne me comprends pas.
lol
Le compteur SSS peut aller jusqu'a 999 mais le compteur LL0 doit
s'incrémenter lorsque SSS passe à 11, 21, 31 etc voir ex:
LLSSS
01001
01002
....
01010
02011
02012
....
02019
02020
03021

Pour le calcul mod97 mon chiffre fait 12 caractères jele découpe en 6 +
6 ou 7 + 5?

Pour le code je remettre les lignes dans l'ordre avec le retour chariot
et je vous tiens au courant.

Merci encore pour votre aide.

Bonsoir

---DGI972--- wrote:
J'ai besoin d'une lumière pour m'en sortir dans une boucle:
(...)




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 suivante ?
if CPT = 11 or 21 or 31 or 41 or 51 or 61 or 71 or 81 or 91 then
LL0 = LL0 +1

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
doit 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 = 0 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 ton calcul est faux :
============ > 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-(((3*K1)+K2)Mod97)==============Déjà,
ce calcul ne donnera pas forcément un positif ...puique on calcule10
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érenceconsiste à
prendre les 6 chiffres du haut et les 6 du bas :Haut = left(CAB0,6)Bas =
Right(CAB0,6)ensuite on calculeResteHaut = Haut Mod 97resteBas = Bas Mod
97et, sachant que le reste mod 97 de 10^6 est 27on en déduitReste =
(27*ResteHaut + ResteBas) Mod 97Le 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 97resteBas = Bas Mod
97Reste = (27*ResteHaut + ResteBas) Mod 97CL = 97 - ResteCLE = 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 decontrôlepour tout "numéro" de N chiffresdans la proposition
ci-dessous, je découpe les 4 chiffres de droite...(le reste de 10^4 module 97
est 9)============= VBS 2 coupez là ===============Nombre = InputBox("Le
nombre avec plein de chiffres ")PasBon = Falsefor i = 1 to len(Nombre)C =
asc(mid(Nombre,i,1))PasBon = PasBon Or C<48 Or C>57nextIf PasBon then Msgbox
"Saisie incorrecte !"else CL = 97 - Reste(Nombre)CLE = right("00" &
CL,2)msgbox "Clé : " & CLEend if'
--------------------------------------------Function Reste(XXX)dim Bas,
ResteBas,ResteHautdim NombreChiffresNombreChiffres = len(XXX)If
NombreChiffres > 4 thenBas = Right(XXX,4)ResteBas = Bas Mod 97ResteHaut =
Reste(Left(XXX,NombreChiffre-4))Reste = (9*ResteHaut + ResteBas) Mod
97ElseReste = XXX mod 97End IfEnd Function============= VBS 2 coupez là
===============La validité de la saisie ( que des chiffres) est vérifiée.Ce
second script étant plus polyvalent,il mérite peut-être d'être conservé
;o)A+HB



Jacques Barathon [MS]
Le #3856481
Perso, je n'ai pas compris grand chose à ton code, et notamment comment tu
prends les valeurs en entrée, mais voici quelques formules en PowerShell
pour traiter les différents cas soulevés. D'une manière générale, je crois
vraiment que vus les traitements que tu fais régulièrement subir à des
fichiers texte, PowerShell est beaucoup plus adapté que VBScript. Mais c'est
toi qui vois... :-)

Le but est de générer un fichier csv avec un compteur du format:
*CCAQQQLLLSSSKK*
CC (constante)
QQQ=Quantième du jour


$qqq = [DateTime]::Now.DayOfYear

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


$ll = [int][math]::Floor(($sss - 1) / 10) + 1
$ll = $ll.ToString("D3")

Au fait, j'affiche LL ($ll dans mon script) sur 3 chiffres, car sauf erreur
de ma part, quand SSS est compris entre 991 et 999, LL est égal à 100.

KK contrôle de modulo 97


Je suppose que le contrôle s'effectue sur les 12 chiffres récoltés
précédemment. Au fait, j'en ai bien 12 en ayant pourtant ajouté un 3e
chiffre à LL, parce que dans ton exemple tu as un "A" qui n'est pas cité
dans tes explications. Est-ce une coquille, ou traites-tu ce A comme un
chiffre en hexadécimal, ce qui laisserait supposer que tu traites toute la
ligne en hexadécimal dans ton calcul de modulo? En tout cas, dans mon
exemple je fais comme si ce A n'existait pas:

$ligne = "01$($qqq)1$ll$sss"
$kk = [int]([double]$ligne % 97)
$kk = $kk.ToString("D2")
$compteur = "$ligne$kk"

La variable $compteur devrait contenir la chaîne au format que tu souhaites,
aux astérisques près; je te laisse les rajouter si tu y tiens :-).

Jacques

Jacques Barathon [MS]
Le #3856471
J'ai oublié de forcer l'affichage du quantième sur 3 chiffres...

QQQ=Quantième du jour


$qqq = [DateTime]::Now.DayOfYear
$qqq = $qqq.ToString("D3")


Jacques


---DGI972---
Le #3856461
Jacques Barathon [MS] a couché sur son écran :
Perso, je n'ai pas compris grand chose à ton code, et notamment comment tu
prends les valeurs en entrée, mais voici quelques formules en PowerShell pour
traiter les différents cas soulevés. D'une manière générale, je crois
vraiment que vus les traitements que tu fais régulièrement subir à des
fichiers texte, PowerShell est beaucoup plus adapté que VBScript. Mais c'est
toi qui vois... :-)

Le but est de générer un fichier csv avec un compteur du format:
*CCAQQQLLLSSSKK*
CC (constante)
QQQ=Quantième du jour


$qqq = [DateTime]::Now.DayOfYear

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


$ll = [int][math]::Floor(($sss - 1) / 10) + 1
$ll = $ll.ToString("D3")

Au fait, j'affiche LL ($ll dans mon script) sur 3 chiffres, car sauf erreur
de ma part, quand SSS est compris entre 991 et 999, LL est égal à 100.

KK contrôle de modulo 97


Je suppose que le contrôle s'effectue sur les 12 chiffres récoltés
précédemment. Au fait, j'en ai bien 12 en ayant pourtant ajouté un 3e chiffre
à LL, parce que dans ton exemple tu as un "A" qui n'est pas cité dans tes
explications. Est-ce une coquille, ou traites-tu ce A comme un chiffre en
hexadécimal, ce qui laisserait supposer que tu traites toute la ligne en
hexadécimal dans ton calcul de modulo? En tout cas, dans mon exemple je fais
comme si ce A n'existait pas:

$ligne = "01$($qqq)1$ll$sss"
$kk = [int]([double]$ligne % 97)
$kk = $kk.ToString("D2")
$compteur = "$ligne$kk"

La variable $compteur devrait contenir la chaîne au format que tu souhaites,
aux astérisques près; je te laisse les rajouter si tu y tiens :-).

Jacques


Bonjour,

Vous avez surement raison pour PowerShell mais je ne suis pas un
programmeur de métier et j'ai trouvé que VBScript ressemble un peu au
Basic. De plus il n'est pas en natif dans toute les machines mais
promis, un jour je m'y mets ....

Désolé pour le non claireté de mon code (ca vous donne mon niveau) ...
LL est sur 2 chiffres c'est une sorte de compteur de dizaine mais a
partir de 11, 21 31 etc...
A c'est la décénie de l'année.
KK est bien sur 12 chiffres
et les * c'est pour faire un code a barre de type 39

merci, je vais essayer de transcrire la formule de la variable $ll en
VBScript pour voir si cela me convient.


Jacques Barathon [MS]
Le #3863461
"---DGI972---" news:

Vous avez surement raison pour PowerShell mais je ne suis pas un
programmeur de métier et j'ai trouvé que VBScript ressemble un peu au
Basic. De plus il n'est pas en natif dans toute les machines mais promis,
un jour je m'y mets ....


Personnellement j'ai toujours trouvé VBScript plus difficile à appréhender
que PowerShell, mais c'est sans doute une question d'état d'esprit. :-)

Pour ce qui est de l'absence de PowerShell en natif, évidemment c'est un
frein pour l'utilisation de scripts du genre ouverture de session qui
doivent s'appliquer à tous les postes d'une entreprise. Encore que,
PowerShell est plutôt léger à installer (hormis le pré-requis du Framework
.NET v2) et peut être déployé à distance sans grand souci.

Mais surtout, dans votre cas j'avais plutôt l'impression que les traitements
que vous effectuez sont des tâches d'exploitation, donc plutôt concentrées
sur un serveur ou un poste d'administrateur. Il est donc facile dans ce cas
d'installer PowerShell sur ces quelques postes où seront écrites, testées et
exécutées les tâches en question.

Désolé pour le non claireté de mon code (ca vous donne mon niveau) ...
LL est sur 2 chiffres c'est une sorte de compteur de dizaine mais a partir
de 11, 21 31 etc...


J'insiste: si SSS va jusqu'à 999, LL sera sur 3 chiffres avec SSS > 990.

A c'est la décénie de l'année.
KK est bien sur 12 chiffres


Donc KK sur 13 chiffres avec un LL à 3 chiffres.

Jacques

Jacques Barathon [MS]
Le #3869931
"Jacques Barathon [MS]" 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

---DGI972---
Le #3880631
"Jacques Barathon [MS]" 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 ...
:'(


Michel_D
Le #3891401
Bonjour,

"Jacques Barathon [MS]" 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



Publicité
Poster une réponse
Anonyme