Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

Word Utilisation des génériques avec InStr

Marcham

XLDnaute Junior
Bonjour,
Avec Word 2007, je souhaiterai trouver la position de deux chiffres entourés d'espaces dans une phrase.
En d'autre termes, voici 2 phrases :
18/02/2022 12:22 02 Bavaria Blue Edeka
107 mit 185 10 Fisch Lachs Edeka
J'aimerai, dans la première trouver la position 17 car le nombre 02 entouré d'espaces (" 02 ") est à la 17éme place.
Dans la deuxième phrase, trouver la position 12 car le nombre 10 entouré d'espaces (" 10 ") est à la 12éme place.
Voici 2 des multiples façons que j'ai essayé :
Dim Pos as integer
Pos = InStr(1, UneDeMes2Phrases, " ?? ") d'une part, et d'autre part Pos = InStr(1, UneDeMes2Phrases, " ## ")
J'ai aussi essayé en mettant des crochets : "[ ]", si je ne met pas les moustaches (""), j'ai l'erreur "Nom externe non défini".
J'ai fait aussi pas mal d'autres essais en vain.
Je dois certainement faire une erreur dans l'utilisation des caractères génériques ou peut-être il y a une incompatibilité de ces caractères avec l'instruction InStr().
Pouvez-vous m'éclairer ?
Ou me donner la solution ?
Amitié - Marc
 

patricktoulon

XLDnaute Barbatruc
bonjour
il te faut passer par un regex
la fonction gettwonumber cherche la chaine de deux carateres numerique entourés d'espaces
instr te donne la position

terminé
VB:
Sub test()
    Dim chaine$, part$
    chaine = "18/02/2022 12:22 02 Bavaria Blue Edeka"
    'chaine = "107 mit 185 10 Fisch Lachs Edeka"
    part = GettwoNumber(chaine)
    MsgBox "la chaine""" & part & " "" se trouve en position  " & InStr(1, chaine, part)
End Sub

Function GettwoNumber(chaine As String)
    Dim matchs
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .Pattern = "\s+\d{2}\s"
        Set matchs = .Execute(chaine)
        If matchs.Count > 0 Then GettwoNumber = matchs(0) Else GettwoNumber = "not found!"
    End With
End Function
 

Robert

XLDnaute Barbatruc
Repose en paix
Bonsoir Marcham, bonsoir le forum,

C'est tiré par les cheveux mais semble fonctionner sur Excel (pas testé avec Word).
En tous cas, pas d'erreur sur ton misérable exemple de deux lignes... À adapter :

VB:
Sub Macro1()
Dim O As Worksheet 'déclare la variable O (Onglet)
Dim TV As Variant 'déclare la variable TV (Tableau des Valeurs)
Dim T As String 'déclare la variable T (Texte)
Dim I As Integer 'déclare la variable I (Incrément)
Dim J As Integer 'déclare la variable J (incrément)
Dim K As Integer 'déclare la variable K (incrément)
Dim NE As Integer 'déclare la variable NE (Nombre d'Espaces)
Dim D As Integer 'déclare la variable D (Départ)
Dim P1 As Integer 'déclare la variable P1 (Position 1)
Dim P2 As Integer 'déclare la variable P2 (Position 2)
Dim TR() As Variant 'déclare la variable TR (tableau des Résultats)

Set O = Worksheets("Feuil1") 'définit l'onglet O
TV = Range("A1").CurrentRegion 'définit le tableau des valeurs TV
For I = 1 To UBound(TV, 1) 'boucle 1 : sur toutes les lignes I du tableau des valeurs TV
    D = 1: P1 = 0: P2 = 0: NE = 0 'réinitialise les variables D, P1, P2 et NE
    T = TV(I, 1) 'définit le texte T
    NE = UBound(Split(T, " ")) 'définit le nombre de fois NE qu'il y a un espace dans T
    For J = 0 To NE 'boucle 2 : sur tous les espace du texte T
        P1 = InStr(D, T, Split(T, " ")(J), vbTextCompare) 'définit la position P1
        P2 = InStr(P1, T, Split(T, " ")(J + 1), vbTextCompare): D = P2 'définit la position P2, redéfinit le départ D
        'condition : si P2 et égale à P1 + 3 et si le texte entre ses positions est numérique
        If P2 = P1 + 3 And IsNumeric(Split(T, " ")(J)) Then
            K = K + 1 'incrémente K
            ReDim Preserve TR(1 To K) 'redimensionne le tableau des résultats TR
            TR(K) = P1 - 1 'définit la variable TR(K)
            Exit For 'sort de la boucle 2
        End If 'fin de la condition
    Next J 'prochain espace de la boucle 2
Next I 'prochaine ligne de la boucole 1
'si K est supérieure à 1, renvoie le tableau transposé TR dans B1 redimensionnée
If K > 0 Then O.Range("B1").Resize(K, 1).Value = Application.Transpose(TR)
End Sub
 

patricktoulon

XLDnaute Barbatruc
après on fait simple avec les outils rudimentaires
VB:
Sub test2()
    chaine = "18/02/2022 12:22 02 Bavaria Blue Edeka"
    chaine = "107 mit 185 10 Fisch Lachs Edeka"
   i = 1
    For i = 1 To Len(chaine)
        If Mid(chaine, i, 1) = " " And Val(Trim(Mid(chaine, i, 4))) > 0 Then a = i
    Next
    MsgBox "la chaine " & Mid(chaine, a, 4) & " se trouve en  position " & a
End Sub

après on peut procéder à un jumping en avançant l'incrémentation de i dans la boucle
ici la boucle au lieu de tourner de 1 à len(chaine) elle va jumper d'espace en espace

elle va donc en fait tourner que deux fois au lieu de 17 avant de trouver

VB:
Sub test3()
    chaine = "18/02/2022 12:22 02 Bavaria Blue Edeka"
     i = 1
    For i = 1 To Len(chaine)
        x = x + 1
        i = InStr(i, chaine, " ")    'on avance i au dernier index de " " trouvé +1
        If Mid(chaine, i, 1) = " " And IsNumeric(Mid(chaine, i + 1, 2)) And Mid(chaine, i + 3, 1) = " " Then
            a = i: Exit For
        Else: i = i + 4
        End If
    Next
    MsgBox "la chaine " & Mid(chaine, a, 4) & " se trouve en  position " & a & vbCrLf & "la boucle n'a tourné que " & x & " fois"
End Sub
edit:
on peu faire comme ça aussi
VB:
Sub test3()
    chaine = "18/02/2022 12:22 02 Bavaria Blue Edeka"
    'chaine = "107 mit 185 10 Fisch Lachs Edeka"
    i = 1
    For i = 1 To Len(chaine)
        x = x + 1
        i = InStr(i, chaine, " ")    'on avance i au dernier index de " " trouvé +1
        If IsNumeric(Trim(Mid(chaine, i, 4))) And Val(Trim(Mid(chaine, i, 4))) < 100 Then
            a = i: Exit For
        Else: i = i + 1
        End If
    Next
    MsgBox "la chaine " & Mid(chaine, a, 4) & " se trouve en  position " & a & vbCrLf & "la boucle n'a tourné que " & x & " fois"
End Sub
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
Bonjour @Robert
il n'y a pas de condescendance là dedans c’était un peu d'humour
et le post je l'ai lu
tu donne un truc qui n'a rien a voir et tu demande a un novice ; qui ; (si on sait lire entre les lignes) n'a pas l'expérience pour traiter une adaptation

quand je veux être condescendant ,crois moi , j'y vais beaucoup plus fort que ça , je n'ai pas peur de mes opinions
a + Robert en espérant te retrouver de meilleur humeur
 

Robert

XLDnaute Barbatruc
Repose en paix
Re,

Alors désolé si c'était de l'humour... Ha ! Comme je regrette mes débuts dans ce forum où les gens avaient, en plus de leur savoir, de l'humilité et surtout un vrai humour (à José et bien d'autres)...
 

Marcham

XLDnaute Junior
Merci Robert et Patrick.
Tout d'abord, je vous remercie chacun pour vos réponses.
Certes, voici un post que j'aurai pu/dû poster sur un forum Word, mais je n'avais aucun murmure de réponse.
Mais étant donné que cela reste du VBA, j'ai osé mettre ça ici.
Par contre, n'allez pas vous crêper le chignon pour un manque (ou un excès) de bonne lecture, ça reste du VBA et je trouve toutes ces propositions très intéressantes.
Sinon, juste pour m'enrichir, que signifie le terme "regex". Je me suis auto formé en VBA et autres langage et à bientôt 65 ans, je ne peux pas connaitre l'évolution des nouveaux termes technique
J'ai aussi, de mon coté réfléchie sur une solution mais un événement familiale m'invite à rester silencieux quelques temps. Mais cela ne devrait pas m'empêcher de vous exposer ça, si cela fonctionne et que cela soit mieux (à mes yeux) que vos excellente propositions.
Amitié - Marc
 
Bonjour Marcham, Robert, Patrick, le forum

@Marcham , regex veut dire regular expression ou expression régulière en français. c'est une chaine de caractère qui définit un ensemble de chaines de caractères possibles. Issues du monde scientifique, elles ont été adoptées en informatique pour leur efficacité dans le traitement des chaines de caractères. Elles sont utilisables dans la majorité des langages de programmation, VBA compris.
Une recherche google vous renverra des milliers d'exemples.
Sans cela, ne vous inquiétez pas trop, Patrick, parfois (souvent ? ) trop rugueux, provoque des réactions épidermiques de degrés variables malgré sa compétence certaine.

Bien cordialement,
Je vous souhaite une excellente journée.
Bernard
 

patricktoulon

XLDnaute Barbatruc
Bonjour Bernard
ben c'est qui comprenne pas mon humour c'est tout
je suis encore moins tendre avec moi meme
de rire de nous ca fait un bien fou
quand ils auront compris ma philosophie il en rirons eux aussi

oui j'ai donné un exemple assez simple de regex qui renvoie les match en plus si plusieurs
après avec instr ma méthode jumping n'est pas mal non plus je me suis aperçu qu'elle fonctionnait de fois plus vite que le regex
ici c'est instr(X,chaine,string) on jump X au len(du string recherché ) a chaque fois que le mid(x,len(string) ne correspond pas , on évite ainsi des tour de boucles inutiles quand on travaille sur des paragraphes ça devient tout de suite plus intéressant
 

Marcham

XLDnaute Junior
Mais dîtes donc, c'est sensationnel ce truc "RegExp" mais l'élaboration du "Pattern" n'a pas l'air d'être simple.
j'ai commencé à fureter sur internet et vu des trucs carrément extra terrestre.
Par contre, dans un premier temps, je n'ai rien trouvé (après une recherche très légère) sur l'utilisation de "IgnoreCase".
Voilà ma prochaine phase d'auto formation.
j'ai déjà trouvé ce truc : https://www.automateexcel.com/fr/vba/expressions-rationnelles-regex/
Mais peut-être, pouvez-vous me mettre le pied à l’étrier en m'orientant ailleurs ?
Merci - Marc
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
avant de taper dans le regex
il faudrait que tu t’intéresse a
  1. instr et ces 3 arguments
  2. mid(chaine,depart,durée)
  3. like(qui est le regex allégé de VB ) et son pattern

quand tu aura compris like tu pourra t'attaquer au regex
 

Tupapa'u

XLDnaute Nouveau
Bonjour,
As-tu essayé avec la fonction "application.search ('texte cherché','texte de recherche')" plutôt qu'avec Instr(1,'texte de recherche','texte cherché') ?
 
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…