Calcul clé conteneur
Bonjour à tous,
pour mon boulot, j'ai en gestion un gros volume de conteneur maritime.
Ils sont tous recensés dans un fichier.
Dans une colonne je rentre l'immatriculation et dans les deux colonnes suivantes j'ai un calcul de clé et dans la deuxième il vérifie si le dernier chiffre et la clé sont identique.
Pour ce faire j'ai deux formules excel qui me prenne de la mémoire, car il calcule en permanence et le temps de calcul avec deux processeur peut prendre 1 à 2 minutes (environ 8000 lignes).
Je souhaiterais faire le calcul de clé avec un code VBA trouvé sur wikipédia mais je ne comprend pas où le mettre et comment il peut faire le calcul dans la colonne souhaitée lorsque je tape une immatriculation.
En pièce jointe un tableau avec quelques lignes de conteneurs et voici le code VBA trouvé (en anglais évidemment) :
[u]Code Sample (Visual Basic)
[/u]
Below is the Visual Basic (VBA) code to create a custom "ISO6346Check" function in Microsoft Excel (Alt + F11) that returns the correct check digit:
Function ISO6346Check(k As String) ' Calculates the ISO Shipping Container Check Digit
Dim i%, s&
Application.Volatile
For i = 1 To 10
s = s + IIf(i < 5, Fix(11 * (Asc(Mid(k, i)) - 56) / 10) + 1, Asc(Mid(k, i)) - 48) * 2 ^ (i - 1)
Next i
ISO6346Check = (s - Fix(s / 11) * 11) Mod 10
End Function
Merci de votre aide
Bonjour,
une fonction personnalisée utilisable sur feuille doit être mise dans un module Standard, MACROs par exemple.
Ensuite ça s'utilise comme une fonction native d'excel :
=ISO6346Check(A2)Mais ne t'attend forcément à un gain phénoménal. Une feuille peut utiliser tous les threads et faire plusieurs calculs simultanément, en vba c'est un seul thread. Tu gagneras au moins en lisibilité.
eric
Bonsoir,
Je n'ai aucune idée de la chose !
Elle est construite pour fonctionner en feuille de calcul. Je conseille donc que tu remplaces dans un premier temps ta formule en C par celle que j'ai mise en D, afin de vérifier sa validité sur un échantillon suffisant.
Elle devrait déjà améliorer le temps de recalcul...
Toutefois, pour se passer complètement de formule, tu peux utiliser une procédure évènementielle intervenant au changement de valeur dans la colonne A.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim clé%
If Target.Column = 1 And Target.Row > 2 Then
If Target <> "" Then
clé = ISO6346Check(Target.Value)
Target.Offset(, 1) = IIf(CInt(Right(Target, 1)) = clé, "CLE OK", "PB CLE")
Else
Target.Offset(, 1).ClearContents
End If
End If
End SubTu la trouveras dans le module de la feuille.
Je l'ai invalidée en plaçant une apostrophe devant Private (et en plaçant une ligne : Sub EnAttente() pour que le code reste à l'intérieur d'une procédure afin que cela ne déclenche pas d'erreur...) Pour la mettre en service, il faut supprimer cette ligne en attente et l'apostrophe devant Private.
La proc. s'exécutera automatiquement chaque fois que la valeur en colonne A change : elle calculera la clé, fera la comparaison et placera le résultat en B ; si A est vide (a été effacée) elle effacera B.
Tu pourras supprimer la colonne C devenue inutile.
Il ne serait pas inutile d'épurer et optimiser un peu ton code en grande partie enregistré... mais c'est un autre problème...
Tu auras au moins le code de la fonction qui, lui, est correctement écrit...
Cordialement.
edit : J'avais tronqué la fonction dans proc Change... c'est rectifié et j'ai remplacé le fichier...
Bonsoir,
merci pour vos réponses nocturnes
Je teste tout ça tout à l'heure et je vous tiens au courant.
Bonsoir MFerrand et eriiic
Merci pour vos solutions qui fonctionne.
Je veux l'adapter à mon fichier original, mais les colonnes sont E, F et G
E = Immatriculation
F = CLE OK ou PB CLE
G = CLE
MFerrand a écrit :Private Sub Worksheet_Change(ByVal Target As Range) Dim clé% If Target.Column = 1 And Target.Row > 2 Then If Target <> "" Then clé = ISO6346Check(Target.Value) Target.Offset(, 1) = IIf(CInt(Right(Target, 1)) = clé, "CLE OK", "PB CLE") Else Target.Offset(, 1).ClearContents End If End If End Sub
Quelles données dois-je modifier pour l'adapter ?
j'ai trouvé (enfin j'espère):
target column = 5 (colonne E)
target row = 6 (colonne F)
ensuite je coince sur la ligne target.offset, quelle chiffre correspond à qui ?
MFerrand a écrit :Tu pourras supprimer la colonne C devenue inutile.
Je veux garder cette colonne, car s'il y a un problème de clé, je dois pouvoir avoir la vrai clé.
Merci
Bonsoir,
Si ce qui était en A est en E, comme tu l'as vu, tu remplaces : If Target.Column = 1 par If Target.Column = 5. Et pour Target.Row >1, c'est parce que les données commencent ligne 2, si elles commencent ligne 6, tu mettras : Target.Row > 5...
Ces conditions constituent le cadrage de la plage dans laquelle la procédure va se se déclencher si un changement s'y produit.
Je veux garder cette colonne, car s'il y a un problème de clé, je dois pouvoir avoir la vrai clé.
Dans ce cas, à la suite de la ligne :
Target.Offset(, 1) = IIf(CInt(Right(Target, 1)) = clé, "CLE OK", "PB CLE")qui porte la mention dans la colonne voisine, soit F, même ligne, tu ajoutes une ligne :
Target.Offset(, 2) = cléqui ajoutera la clé calculée en colonne G.
Cordialement.
Bonjour Mferrand
merci pour ces explications, ça marche correctement.
Merci pour ton aide
Cordialement