[REGEX] Recherche Patten de capture, un défi ?

Résolu
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 - 11 oct. 2023 à 20:43
Whismeril Messages postés 19044 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 mai 2024 - 27 févr. 2024 à 23:34

Bonjour à tous,

J'essaie vainement de créer un Patten de capture.

Voici la chaine concernée:

85339147802789523626847310205970239AR2950793415PC7098624031

De cette chaine, j'aimerais capturer les caractères qui sont après 10 jusqu'à AR.

Soit : 205970239

Les contraintes:

Après 85 il y a toujours 14 caractères variable.

Après 36 il y a toujours 6 caractères variable.

Le nombre de caractères entre 10 et AR et compris entre 1 et 20 caractères variable.

Après 29 il y a toujours 6 caractères variable.

Après 15 le nombre de caractères et compris entre 1 et 20 caractères variable.

85, 36, le couple 10 et AR, 29 et 15 serons toujours présent.

85 est toujours en début de chaine.

Les positions de 36, du couple 10 et AR, 29 et 15 peuvent changer

Dans ma chaine d'exemple nous avons:

85, 36, le couple 10 et AR, 29 et 15

Ça pourrait être:

85, 29, le couple 10 et AR, 15 et 36

Ou encore:

85, le couple 10 et AR, 15, 36, 29

J'espère être assez claire et que vous pourrez m'aider ?

142 réponses

NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
11 oct. 2023 à 22:51

Comment pourrais-je modifier mon code VBA pour être compatible?

Function ExtractInfoGS1_128(Chaine As String, numInfo As Integer) As String
    ' Création de l'objet RegExp
    ExtractInfoGS1_128 = "Erreur"
    Set regEx = CreateObject("VBScript.RegExp")
    regEx.Global = True
    regEx.IgnoreCase = True
    regEx.Pattern = "85(\d{14})36(\d{6})10((?<=10).{1,20}(?=AR))29(\d{6})15(PC\d+)$" 'Expression régulière
    If matches.Count = 1 Then
       Debug.Print "Identifiant de l'appareil : ", matches(0).submatches(0)
       Debug.Print "Date de fabrication : ", matches(0).submatches(1)
       Debug.Print "Date d'expiration : ", matches(0).submatches(2)
       Debug.Print "Numéro de lot/lot : ", matches(0).submatches(3)
       Debug.Print "Numéro de série : ", matches(0).submatches(4)
       ExtractInfoGS1_128 = matches(0).submatches(numInfo - 1)
    End If
End Function

Sub TestRegex()
Debug.Print ExtractInfoGS1_128("85339147802789523626847310205970239AR2950793415PC22412085", 4)
End Sub
0
Whismeril Messages postés 19044 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 mai 2024 656
12 oct. 2023 à 06:53

Ha c'est du VBA

le moteur de regex de VBA est ancien, je ne sais pas s'il prend en compte les prefixes et les suffixes.

Mais de toute façon, ils ne peuvent pas être au milieu.

D'autre part, quand je t'ai demandé si les 85, 36 et consorts avaient de l'importance tu m'as répondu non, donc pourquoi les remettre alors la regex qui ne s'en préoccupe pas est simple?


0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
12 oct. 2023 à 09:35

Bonjour @Whismeril,

Effectivement le moteur de RegEx de VBA ne prend en compte les préfixes et les suffixes!

Désolé, quand j'ai répondu que les 85, 36 et consorts n'avaient pas d'importance, j'ai pensé que cela pourrait être géré séparément.

Dans le genre:

Function ExtractInfo(txt As String, matrice) As String 
    With CreateObject("VBScript.RegExp")
        .Pattern = matrice
        .IgnoreCase = True
        ExtractInfo = .Execute(txt)(0)
    End With
End Function

Sub test10()
    Dim Chaine As String
    Chaine = "85339147802789523626847310205970239AR2950793415PC7098624031"
	Extract85 = ExtractInfo(Chaine, "(?<=85).(\d{14})") 
	Extract36 = ExtractInfo(Chaine, "(?<=36).(\d{6})")
	Extract10 = ExtractInfo(Chaine, "(?<=10).{1,20}(?=AR)") 
	Extract29 = ExtractInfo(Chaine, "(?<=29).(\d{6})") 
	Extract15 = ExtractInfo(Chaine, "(?<=15).{1,20}$") 
MsgBox Extract85 & vbCrLf & Extract36 & vbCrLf & Extract10 & vbCrLf & Extract29 & vbCrLf & Extract15
End Sub

Mais vu le moteur de RegEx de VBA pose problème !

Une autre approche est-elle possible ?

0
Whismeril Messages postés 19044 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 mai 2024 656
12 oct. 2023 à 16:50

Ok, donc finalement tu cherches à récupérer chacune des parties.

Est ce qu'une chaine dans laquelle il manquerait, une des "balises" doit être rejetée?

Est ce qu'une chaîne dans laquelle, une des balises est en double doit être rejetée?

PS, pour la coloration syntaxique, il faut choisir Basic comme langage dans la liste déroulante.


0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
Modifié le 12 oct. 2023 à 22:34

Bonjour,


J'ai pu "j'espère" résoudre mon problème de préfixes et suffixes!
Pour la balise 10 en fin de code-barres:
"10(.{1,20})$"
Pour la balise 10 qui n'est pas la dernière balise du code-barres:
"10(.{1,20})(?=GS)"
C'est la même chose pour la balise 21.

GS est la balise de fin des chaines de caractères lié aux balises 10 et 21.


Ça fonctionne pour le code-barres:
0100883873867792112209271723092710220927GS21PC23713163


Modification du code pour être en adéquation avec GS1, donc correction des informations:


01 = Numéro d'article (GTIN) = 14 caractères.
11 = Date de production = 6 caractères.
17 = Date d'expiration = 6 caractères.
10 = Le numéro de lot = variable 1 à 20 caractères, Jusqu’à GS, sauf si dernière position.    
21 = Le numéro de série = variable 1 à 20 caractères, Jusqu’à GS, sauf si dernière position.


Pour répondre aux questions:


1) Est-ce qu'une chaine dans laquelle il manquerait, une des "balises" doit être rejetée?


En considérant que les balises sont:
01, 11, 17, 10, 21 et GS.


Non la chaine ne doit pas être rejetée, tous les articles non pas forcément de numéro de lot "10", de numéro de série "21" ou de Date d'expiration "17"…
Exemple:
(01)05862455391075(11)220328(17)231231


2) Est-ce qu'une chaîne dans laquelle, une des balises est en double doit être rejetée?


Les articles qui possèdent un numéro de lot "10" et\ou un numéro de série "21" sont variables et ont la balise "GS" pour délimiter la fin de la chaine, sauf si le numéro de lot "10" ou le numéro de série "21" et en fin de chaine, dans ce cas pas de balise "GS"


Exemple, avec la balise de fin "GS" de "10" et sans balise "GS" de fin de "21" car il est en dernière position.
(01)00883873867792(11)220927(17)230927(10)220927GS(21)PC23713163


Exemple, avec la balise de fin "GS" de "10" et balise "GS" de fin de "21" car aucun des deux est en dernière position.
(01)03400934672248(21)10045423841916GS(10)X09897AGS(17)260430

Il ne peut pas y avoir de doublons sur les balises "01, 10, 11, 17, et 21" seulement des doublons sur GS.

Compléments d'informations:


Les balises peuvent avoir un ordre différant sauf "01" qui est toujours en 1er.
01, 11, 17, 10+GS, 21
01, 11, 10+GS, 21+GS, 17
01, 17, 11, 10+GS, 21


Comme évoqué plus haut, certaines balises peuvent manquer.
01, 11, 17
01, 10+GS, 21
01, 10+GS, 11
01, 11, 17, 10
01, 17, 10+GS, 21
01, 11, 21+GS, 17


Je pense que j'ai fait le tour, voici le code:

Function ExtractInfo(txt As String, matrice) As String
    With CreateObject("VBScript.RegExp")
        .Pattern = matrice
        .IgnoreCase = True
        If .test(txt) Then ExtractInfo = .Execute(txt)(0).submatches(0)
    End With
End Function

Sub test10()
    Dim Chaine As String
    
' -----------------------------------------------------------------------------------------

    Chaine = "0100883873867792112209271723092710220927GS21PC23713163" 'OK
    
    'Result
    '(01)00883873867792
    '(11)220927
    '(17)230927
    '(10)220927
    '(21)PC23713163 (No GS with 21, it's normal, it's in last position).
    
' -----------------------------------------------------------------------------------------
    
    'Chaine = "01034009301383801726013110DB20323GS2195918770106437" 'Not OK
    
    'Result
    '(01)03400930138380
    '(11) Not in the barcode, Displays a blank in the MsgBox.
    '(17)260131
    '(10)DB20323
    '(21)95918770106437 (No GS with 21, it's normal, it's in last position).
    
' -----------------------------------------------------------------------------------------
    
    'Chaine = "01034009301884081726060010ABS3514" 'Not OK

    'Result
    '(01)03400930188408
    '(11) Not in the barcode, Displays a blank in the MsgBox.
    '(17) 260600
    '(10) Not displayed ???, expected result: ABS3514 (No GS with 10, it's normal, it's in last position).
    '(21) Not in the barcode.
    
' -----------------------------------------------------------------------------------------
    
    'Chaine = "01034009346722482110045423841916GS10X09897AGS17260430" 'Not OK
    
    'Result
    '(01) 03400934672248
    '(11) Not in the barcode.
    '(21) Wrong displayed result: 004542, GS processing missing, expected result:10045423841916
    '(10) Wrong displayed result: 045423841916, expected result: X09897A
    '(17) 260430
    
' -----------------------------------------------------------------------------------------
    
    Extract01 = ExtractInfo(Chaine, "01(\d{14})")
    Extract11 = ExtractInfo(Chaine, "11(\d{6})")
    Extract17 = ExtractInfo(Chaine, "17(\d{6})")
    Extract10 = ExtractInfo(Chaine, "10(.{1,20})(?=GS)")
    Extract21 = ExtractInfo(Chaine, "21(.{1,20})$")
    MsgBox Extract01 & vbCrLf & Extract11 & vbCrLf & Extract17 & vbCrLf & Extract10 & vbCrLf & Extract21
End Sub

Quelques exemples de codes-barres sont commentés avec le résultat et les dysfonctionnements rencontrés.

0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
Modifié le 13 oct. 2023 à 12:04

Dans tes 2 ajouts, ce cas de figure ne devrait pas arriver.

La balise 01 et toujours en 1er position du code-barres et est toujours suivit de 14 caractères.

Sur ton 1er exemple:

01034009346722482110045423841916GS10X09897AGS17260430

IL y a 15 caractères entre la balise 01 et la balise 11, ce ne peut pas être le cas (toujours 14).

Dans le 2éme exemple:

01034009346711482110045423841916GS10X09897AGS17260430

Si on traite 01 en 1er les 14 caractères qui le suive ne devraient plus faire partie de l'équation et donc ignoré, non?

Pour rappel:

01 toujours suivit de 14 caractères.

11 et 17 toujours suivit de 6 caractères.

10 et 21 suivit de 1 à 20 caractères, Jusqu’à balise GS, sauf si dernière position.

Concernant 11 et 17 les dates, elles peuvent être au format jjmmaa ou aammjj il me semble même avoir vu mmaaaa ou aaaamm.

Le fait que le moteur RegEx de VBA soit ancien ne va pas faciliter les choses!

0
Whismeril Messages postés 19044 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 mai 2024 656
13 oct. 2023 à 16:41

Le fait que le moteur RegEx de VBA soit ancien ne va pas faciliter les choses!

Non parce que de toute façon le pattern va être compliqué, on ne pourra par nommer les groupes de captures, mais c'est pas bien gênant.

0
Whismeril Messages postés 19044 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 mai 2024 656
13 oct. 2023 à 17:44

IL y a 15 caractères entre la balise 01 et la balise 11, ce ne peut pas être le cas (toujours 14).

J'ai copié collé les séquences commentées de ton code en #10.

J'ai juste changé un 22 en 11 entre la 4eme ligne, issue de ton code et la 5éme


0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
Modifié le 13 oct. 2023 à 18:40

Dans le code-barres :
01034009346722482110045423841916GS10X09897AGS17260430
Le 14 eme caractère après la balise 01, c'est une balise 21.


Il peut y avoir un 11 entre les balises 01 et 21, c'est un peu pour cela que j'avais pensé aux patterns séparés et éventuellement exclure les parties déjà traitées du code-barres source et le recréer toute à la fin.

0
Whismeril Messages postés 19044 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 mai 2024 656
13 oct. 2023 à 18:19

Haaa

0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
Modifié le 14 oct. 2023 à 01:03

Peut-être une piste?
Ne semble pas fonctionner en VBA
J'ai copié collé les séquences commentées de mon code en #10 et ajouté les crochets " [] " autour des balises GS (Là une petite explication s'impose !).

0100883873867792112209271723092710220927[GS]21PC23713163
01034009301383801726013110DB20323[GS]2195918770106437
01034009301884081726060010ABS3514
01034009346722482110045423841916[GS]10X09897A[GS]17260430

https://regex101.com/r/IDcO7Z/1

Options gmx

- global (don't return after first match)

- multi line (^ and $ match start/end of line)

-extended (ignore whitespace)

^(?:
01(?P<g01>.{14})|
10(?P<g10>(?:(?!\[GS]).){1,20})(?:\[GS]|$)|
17(?P<g17>.{6})|
11(?P<g11>.{6})|
21(?P<g21>(?:(?!\[GS]).){1,20})(?:\[GS]|$)
)+$
0
Whismeril Messages postés 19044 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 mai 2024 656
14 oct. 2023 à 10:34

Essaye ceci.

Sub TestNeriXs()
Dim pattern01, pattern11, pattern17, pattern10, pattern21, pattern, code, capture, balise, resultat As String
Dim regex, matches As Object
Dim codes As Variant

codes = Array("0100883873867792112209271723092710220927GS21PC23713163", "01008838738677921723092710220927GS21PC23713163GS11220927", "0100883873867792112209271723092710220927GS21PC23713163", "01034009301383801726013110DB20323GS2195918770106437", "01034009301884081726060010ABS3514", "01034009346722482110045423841916GS10X09897AGS17260430")

Set regex = New RegExp

pattern01 = "^(01.{14})"
pattern11 = "(11\d{6})"
pattern17 = "(17\d{6})"
pattern10 = "(10.{1,20}?)(?:GS|$)"
pattern21 = "(21.{1,20}?)(?:GS|$)"

pattern = pattern01 + "(?:" + pattern11 + "|" + pattern17 + "|" + pattern10 + "|" + pattern21 + ")+$"

regex.pattern = pattern
For Each code In codes
    If (regex.Test(code)) Then
        Set matches = regex.Execute(code)
        For Each Match In matches
            a = Match.SubMatches.Count
            For i = 0 To a - 1
                capture = Match.SubMatches.Item(i)
                balise = Left(capture, 2)
                Select Case balise
                    Case "01"
                        resultat = balise + ": " + Right(capture, 14) + ", "
                
                    Case "11", "17"
                        resultat = resultat + balise + ": " + Right(capture, 6) + ", "
                
                    Case "10", "21"
                        resultat = resultat + balise + ": " + Right(capture, Len(capture) - 2) + ", "
                End Select
            Next
            Debug.Print code
            Debug.Print resultat
        Next
    End If
Next
End Sub

Pour voir le résultat, il faut afficher la fenêtre "Exécution"

Avec les quelques codes que j'ai mis en entrée, ça donne

0100883873867792112209271723092710220927GS21PC23713163
01: 00883873867792, 11: 220927, 17: 230927, 10: 220927, 21: PC23713163, 
0100883873867792112209271723092710220927GS21PC23713163
01: 00883873867792, 11: 220927, 17: 230927, 10: 220927, 21: PC23713163, 
01008838738677921723092710220927GS21PC23713163GS11220927
01: 00883873867792, 11: 220927, 17: 230927, 10: 220927, 21: PC23713163, 
0100883873867792112209271723092710220927GS21PC23713163
01: 00883873867792, 11: 220927, 17: 230927, 10: 220927, 21: PC23713163, 
01034009301383801726013110DB20323GS2195918770106437
01: 03400930138380, 17: 260131, 10: DB20323, 21: 95918770106437, 
01034009301884081726060010ABS3514
01: 03400930188408, 17: 260600, 10: ABS3514, 
01034009346722482110045423841916GS10X09897AGS17260430
01: 03400934672248, 17: 260430, 10: X09897A, 21: 10045423841916, 

Si ça te convient, j'expliquerai le pouquoi du comment


0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
14 oct. 2023 à 11:07

J'ai des erreurs de compilation, variable non défini et d'objet requis.

J'ai ajouté option explicit et essaie de débugger.

0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
14 oct. 2023 à 11:22

Erreur de compilation sur New RegExp, type non défini.

0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
14 oct. 2023 à 11:40

Oups, désolé, je suis partie sur un autre poste et ne l'avais pas ajouté!
Je test et reviens rapidement
En tous cas merci pour le temps passé!

0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
14 oct. 2023 à 13:39

Parfait, tous les codes-barres que j'ai testés ont matchés!
Pour l'utilisation final et si tu as encore un peu de temps.
La saisie du code-barres depuis un InputBox.
Les données extraites sur Feuil1

Idéalement:
La reprise du code-barres initial avec des parenthèses autour des balises, mais sans les balises GS
Les éléments du code-barres en dessous avec dénomination.

Pour:
0100883873867792112209271723092710220927GS21PC23713163
01: 00883873867792, 11: 220927, 17: 230927, 10: 220927, 21: PC23713163,

Cela donnerait:


(01)00883873867792(11)220927(17)230927(10)220927(21)PC23713163


(01) GTIN de l’article: 00883873867792
(11) Date de production: 220927
(17) Date d'expiration : 230927
(10) Numéro de lot: 220927
(21) Numéro de série: PC23713163

Je relis le code avant tes explications "le pourquoi du comment" ;)

0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
15 oct. 2023 à 14:43

Bonjour @Whismeril,

Un grand merci pour le travail effectué, les explications, le recueil des informations afin de bien cerner les besoins, très professionnel!

J'ai omis un élément que j'avais géré en amont.

Comme pour la balise GS, le scanne d'un code-barres peut afficher une balise en tout début du code-barres.

Ces balises sont:
]C1 = GS1-128 BarCode
]e0 = GS1 DataBar
]d2 = GS1 DataMatrix
]Q3 = GS1 QR Code
]J1 = GS1 DotCode

Ces balises sont couramment appelées FNC1

Exemple:
]C10100883873867792112207071723070710220707GS21PC22412085

Ces Balises FNC1 donnes juste une information et sont inutiles au traitement du Code-barres et ne sont pas toujours présentes.
J'avais traité de cette façon:

=SUBSTITUE(SUBSTITUE(SUBSTITUE(SUBSTITUE(SUBSTITUE(A5; "]C1"; ""); "]e0"; ""); "]d2"; ""); "]Q3"; ""); "]J1"; "")

Ce serait plus propre via RegEx de les supprimer si présentes, mais ça ne match plus quand j'essaie.

Pourrais-tu regarder?

J'ai repris le code pour ne gérer qu'un code a la fois, oui désolé je ne t'avais pas donné plus de précision.

Option Explicit

Sub TestNeriXs()
Dim pattern01, pattern11, pattern17, pattern10, pattern21, pattern, code, capture, balise, resultat, gtin, dateProd, dateExpi, numLot, numSerie As String
Dim regex, matches, Match As Object
Dim codes As Variant
Dim i As Integer
            
code = "0100883873867792112209271723092710220927GS21PC23713163"

Set regex = New RegExp

'écriture des patterns unitaires
pattern01 = "^(01.{14})"
pattern11 = "(11\d{6})"
pattern17 = "(17\d{6})"
pattern10 = "(10.{1,20}?)(?:GS|$)"
pattern21 = "(21.{1,20}?)(?:GS|$)"

'fusion du pattern complet
pattern = pattern01 + "(?:" + pattern11 + "|" + pattern17 + "|" + pattern10 + "|" + pattern21 + ")+$"

regex.pattern = pattern

    'on vérifie d'abord que la regex matche
    If (regex.Test(code)) Then
        'si oui, on recoupère les datas
        Set matches = regex.Execute(code)
        
        For Each Match In matches
            'pour chaque match, on récupère les groupes
            For i = 0 To Match.SubMatches.Count - 1
                capture = Match.SubMatches.Item(i)
                'on extrait la balise pour affecter le résultat comme il faut
                balise = Left(capture, 2)
                'j'ai choisi un select case, car ça se prête bien à la situation
                Select Case balise
                    Case "01"
                        gtin = Right(capture, 14)
                        resultat = "(01)" + gtin
                
                    Case "11"
                        dateProd = Right(capture, 6)
                        resultat = resultat + "(11)" + dateProd
                        
                    Case "17"
                        dateExpi = Right(capture, 6)
                        resultat = resultat + "(17)" + dateExpi
                        
                    Case "10"
                        numLot = Right(capture, Len(capture) - 2)
                        resultat = resultat + "(10)" + numLot
                        
                    Case "21"
                        numSerie = Right(capture, Len(capture) - 2)
                        resultat = resultat + "(21)" + numSerie
                End Select
            Next
            'on imprime le résultat dans la console
            Debug.Print resultat
            Debug.Print "(01) GTIN de l’article: " + gtin
            Debug.Print "(11) Date de production: " + dateProd
            Debug.Print "(17) Date d'expiration : " + dateExpi
            Debug.Print "(10) Numéro de lot: " + numLot
            Debug.Print "(21) Numéro de série: " + numSerie
        Next
    End If
End Sub
0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
15 oct. 2023 à 18:22

Solution 2 validée, ça match avec et sans FNC1, merci.

J'aimerais exposer une difficulté qui n'est pas liée directement à la demande initiale, mais qui l'impact.

Je me lance ici, mais si tu préfères que j'ouvre un nouveau poste dis le moi.

Cela concerne la balise GS.
Celle-ci fait partie (enfin je crois) des caractères non imprimables.

GS     = Group Separator
          = ASCII Code 29
          = Hexadecimal Code 1D
          = Unicode Escape Code \u001d

Sous NotePad ++, en saisissant au clavier la combinaison de douche Alt + 029, GS apparait sur fond noir.

Toujours sous NotePad++, onglet recherche, puis onglet remplacer
En saisissant \x puis le code GS hex 1D.
Soit:

Recherche: \x1D
Remplacer par: GS

Mode de recherche: Expression régulière

Le GS non imprimable et bien remplacé.

Un test entre NotePad++ et excel

Sous NotePad++ saisir 123 la combinaison de touche Alt+029 puis 456.
On voit bien 123GS456

En copiant cette ligne dans une cellule Excel on voix seulement 123456.

En re-copiant cette cellule et la collant sous NotePad++, on a bien 123GS456.

Le GS n'est pas vu mais est bien dans la cellule Excel.

Je cherche donc à faire la même chose.

Quelques pistes:

https://stackoverflow.com/questions/37024107/remove-unicode-characters-in-a-string

https://www.linkedin.com/pulse/removing-non-printing-characters-from-text-excel-using-ejaz-ahmed

https://stackoverflow.com/questions/47506560/function-which-removes-only-non-ascii-characters-in-a-column-in-access-table

https://stackoverflow.com/questions/41882525/vba-how-to-remove-non-printable-characters-from-data

0
Whismeril Messages postés 19044 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 mai 2024 656
15 oct. 2023 à 23:01

Essaye avec 

"(10.{1,20}?)(?:GS|$|\x1d)"

pour les patterns 10 et 21, ça devrait matcher si GS est écrit en "texte" ou si c'est le caractère x1d.


0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
16 oct. 2023 à 00:40

Arfff, je suis une tête de mule!

Je cherchais absolument à remplacer la balise GS soit \x1d par un GS écrit en "texte".
Ce n'est apparemment pas possible, il suffisait de l'exploiter.
3 H que je suis là-dessus
Ton pattern fonction. MERCI!!

Ça fonctionne aussi avec le D en majuscule.
Au passage attention, dans le code quand on utilise 1 \x1d un espace et ajouté en fin de ligne et 2 espaces si 2 \x1d sont utilisés.
Il ne faut surtout pas les supprimer car ça ampute le pattern.

J'ai commencé un UserForm pour interfacer le projet.
Je n'ai pas encore compris comment interagir avec ces éléments
En exemple, si tu pouvais me mettre en place l'utilisation du TextBox nommé "TxtCodeBarres" a la place de (code = "01034009346722482110045423841916GS10X09897AGS17260430") du Module?

Ça m'aiderait beaucoup.

Lien pour le téléchargement:
https://www.dropbox.com/scl/fi/cxlvmtmsev3626xrzh8fm/D-codeur-Code-Barres-GS1-128.xlsm?rlkey=1lgx32u2g4v3yksoqb67bs1co&dl=0

0
Whismeril Messages postés 19044 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 mai 2024 656
16 oct. 2023 à 08:10

Je n'aurais pas VBA sous la main avant ce soir. Mais de mémoire, selon le VB, il y a 2 possibilités avec les textbox

Code = TextBox.Value
Code = TextBox.Text

0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
16 oct. 2023 à 14:16

En formation aujourd'hui, donc pas de VBA non plus avant ce soir ;)

Mon problème ne porte pas sur l'utilisation des commandes, mais sur la mise en application du processus:
UserForm (pour l'acquisition) => Module (pour le traitement) => UserForm (pour le résultat) => feuil Excel pour la sauvegarde.

Le code-barres est scanné et affiché sur le TextBox (TxTCodeBarres).

Je n'ai pas compris comment coder CommandButton (BTDecod) pour le traitement du code-barres et affichage du "resultat" sur mon TextBox (TxtAllData) ?

0
Whismeril Messages postés 19044 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 mai 2024 656
17 oct. 2023 à 18:17

Le code modifié comme ça

Option Explicit

Function TestNeriXs(code As String) As String
Dim pattern01, pattern11, pattern17, pattern10, pattern21, pattern, capture, balise, resultat, gtin, dateProd, dateExpi, numLot, numSerie As String
Dim regex, matches, Match As Object
Dim i As Integer

Set regex = New RegExp

'écriture des patterns unitaires
pattern01 = "^(01.{14})"
pattern11 = "(11\d{6})"
pattern17 = "(17\d{6})"
pattern10 = "(10.{1,20}?)(?:GS|$)"
pattern21 = "(21.{1,20}?)(?:GS|$)"

'fusion du pattern complet
pattern = pattern01 + "(?:" + pattern11 + "|" + pattern17 + "|" + pattern10 + "|" + pattern21 + ")+$"

regex.pattern = pattern

'valeur par défaut si la regex ne matche pas
resultat = "Code incorrect"

'on vérifie d'abord que la regex matche
If (regex.Test(code)) Then
    'si oui, on recoupère les datas
    'comme je ne savais pas si tu récupères les codes un à un ou en lot (dans un fichier par exemple),
    'je suis parti du principe qu'il pouvait y avoir plusieurs matches
    Set matches = regex.Execute(code)
    
    For Each Match In matches
        'pour chaque match, on récupère les groupes
        For i = 0 To Match.SubMatches.Count - 1
            capture = Match.SubMatches.Item(i)
            'on extrait la balise pour affecter le résultat comme il faut
            balise = Left(capture, 2)
            'j'ai choisi un select case, car ça se prête bien à la situation
            Select Case balise
                Case "01"
                    gtin = Right(capture, 14)
                    resultat = "(01)" + gtin
            
                Case "11"
                    dateProd = Right(capture, 6)
                    resultat = resultat + "(11)" + dateProd
                    
                Case "17"
                    dateExpi = Right(capture, 6)
                    resultat = resultat + "(17)" + dateExpi
                    
                Case "10"
                    numLot = Right(capture, Len(capture) - 2)
                    resultat = resultat + "(10)" + numLot
                    
                Case "21"
                    numSerie = Right(capture, Len(capture) - 2)
                    resultat = resultat + "(21)" + numSerie
            End Select
        Next
        'on écrit le résultat complet
        resultat = resultat + vbCrLf + "(01) GTIN de l’article: " + gtin + vbCrLf + "(11) Date de production: " + dateProd + vbCrLf + "(17) Date d'expiration : " + dateExpi + vbCrLf + "(10) Numéro de lot: " + numLot + vbCrLf + "(21) Numéro de série: " + numSerie
    Next
End If
TestNeriXs = resultat
End Function

Et dans le bouton

Private Sub BTDecod_Click()
    TxtAllData.Value = TestNeriXs(TxTCodeBarres.Value)
End Sub

 TxTCodeBarres doit avoir la propriété multiline à true


0
Rejoignez-nous