Récupérer une valeur numérique dans un texte

Très bien,

A une prochaine fois, sans doute...

Je suis de retour plus vite que prévue : IMPOSSIBLE de ajouter le point à la place de la virgule or ça pose problème car les valeurs sont extirpées pour aller dans un doc XML or il ne tolère pas les valeurs avec une virgule....

Sub Enleve()

Dim chaine As String
Dim chaine2 As String
Dim nbcarac As Variant
Dim nbcarac2 As Variant
Dim nbcarac3 As Variant
Dim Mot As String
Dim Prem As Integer
Dim sngNombre As Single
Dim valeur As String

DL = Range("Tableau3").Rows.Count

'Recherche 1ier nombre

For ligne = 1 To DL
Range("Tableau3[EPAISSEUR]")(ligne) = ""
Range("Tableau3[LARGEUR]")(ligne) = ""
chaine = ""
For nbcarac = 1 To Len(Range("Tableau3[NOM M3]")(ligne))
Mot = Range("Tableau3[NOM M3]")(ligne): chaine = Mid(Mot, nbcarac, 1)
If (Asc(chaine) < Asc("@")) And chaine <> " " And chaine <> "." Then Range("Tableau3[LARGEUR]")(ligne) = Range("Tableau3[LARGEUR]")(ligne) & chaine: Prem = 1
If Prem = 1 And chaine = "X" Then Exit For
Next nbcarac

'Recherche 2ième nombre

chaine = "": Prem = 0
For nbcarac2 = nbcarac + 1 To Len(Range("Tableau3[NOM M3]")(ligne))
Mot = Range("Tableau3[NOM M3]")(ligne): chaine = Mid(Mot, nbcarac2, 1)
If (Asc(chaine) < Asc("@")) Then Range("Tableau3[EPAISSEUR]")(ligne) = Range("Tableau3[EPAISSEUR]")(ligne) & chaine
If chaine = "." Then
Range("Tableau3[EPAISSEUR]")(ligne) = Range("Tableau3[EPAISSEUR]")(ligne) & ","
End If
Next nbcarac2

valeur = Range("Tableau3[EPAISSEUR]")(ligne).Text
valeur = Replace(valeur, ",", ".", 1, 1)
If CDbl(Range("Tableau3[EPAISSEUR]")(ligne).Value) >= 100 Then Range("Tableau3[EPAISSEUR]")(ligne) = ""
chaine = "": Prem = 0
Next ligne

End Sub

Oui parce que si je mettais le point directement impossible car il considère que comme il n'y a rien après ça fait par exemple 8.0 donc le point est inutile et il l'enlève

Salut Man,

Pour rappel, tu as une fonction qui extrait les nombres d'une chaine de caractères et qui peut remplacer des caractères...

Bon, je ne sais plus quel est le besoin maintenant mais il faudrait s'y intéresser, d'autant qu'il n'y a pas de boucle.

Function EXTRACT_NUMBER(chaine As String, Optional Occurrence As Integer) As String

Dim ExpReg As Object
Dim subdiv As Object 

Set ExpReg = CreateObject("vbscript.regexp")

With ExpReg
    .Global = True
    .Pattern = "\d+((,|\.){1}\d+)?"
    If .test(chaine) Then
        Set subdiv = .Execute(chaine)
        If subdiv.Count > 1 Then
            If Occurrence = 0 Then Occurrence = 1
            EXTRACT_NUMBER = replace(subdiv(Occurrence - 1).Value, ",", ".")
        Else
            EXTRACT_NUMBER = replace(subdiv(0).Value, ",", ".")
        End If
    End If
End With

End function

Cdlt,

PS : Elle est adaptable ! Si tu montrais des exemples de chaines et le résultat que tu attends, ça pourrait faire gagner beaucoup de temps

bonjour a tous

oserais-je dire que certains inhibe vbs de PC et que par consequent les regex walouh walouh

si vous le voulez bien faisons les choses simples

ici on va utiliser la metode mid en applicatif et oui cette methode est encore beaucoup ignoré mid ne sert pas qu'en lecture

et en ce qui concerne les regex vba a son petit lot aussi avec like

donc exemple

Sub test()
    chaine$ = "78,45abcdef1,8gjhgdfdt6,3gggblablablagggg45gjhghghgh78,33ghghgh"
    'ici nous allons utiliser "MID" en lecture et!!!!! applicatif pour remplacer!!!!!!!!!!!
    '(cette propriété de mid est encore beaucoup ignorée pourtant bien utile )
    For i = 1 To Len(chaine)
        If Mid$(chaine, i, 1) Like "[A-z]" Then Mid(chaine, i, 1) = " "
    Next
    'maintenant que l'on a remplacé toutes les lettres on se retrouve avec un moulin d'espaces
    ' pas de soucis on va donc réguler ces espace avec application.trim(qui non seulement trim une chaîne  mais régule à un seul espace consécutif )
    ' donc
    chaine = Application.Trim(chaine)
    'voyons voir
    MsgBox "voici la  suite de valeur" & vbCrLf & chaine
    'et donc mon tableau de valeur c'est
    montableau = Split(chaine, " ")
    'testons voir par exemple la 3 eme valeur donc index(2) (car split génère un array en base 0)
    MsgBox " il y a donc " & UBound(montableau) + 1 & " valeur(s) dans cette chaine " & vbCrLf & "valeur n°3 : " & montableau(2)
End Sub

think différent

Bonjour patricktoulon,

Alors, je n'ai rien compris à ta première phrase !

Pour ma part, je privilégierais les regex car ça évite de boucler sur les caractères, sachant qu'il faut a priori inclure cette opération dans une autre boucle... Donc j'imagine que c'est plus approprié et plus rapide.

En tout cas, merci car je ne savais pas qu'on pouvait utiliser mid en "écriture" ! Et pourquoi Mid est "typé" dans la condition ? et pourquoi pas après ?

Pour cet exercice, compte tenu du besoin, je dirais même qu'on peut modifier la condition comme ceci :

If not Mid$(chaine, i, 1) Like "[0-9,]" Then Mid(chaine, i, 1) = " "

Mais, je continue de penser que ça rester imparfait car on peut par exemple se retrouver (sait-on jamais) avec des virgules entre des lettres, virgules qu'il ne faudrait pas inclure.

Cdlt,

Bonjour 3GB le type est un oubli de ma part(code cochon) en suite comme je l'ai dis certains

Ne peuvent utiliser les regexs car ils inhibent VBS de leur PCs pour la sécurité

et non on ne met pas la virgule dans le motif sinon tu perds l option decimale

Bonjour Patrick,

D'accord, je me demandais si PC était un acronyme technique que je ne connaissais pas . En effet, et sur mac, les regex ne sont pas disponibles (à ma connaissance).

Non, justement, j'ai "inversé" le motif : au lieu d'enlever [A-z], j'enlève tout ce qui n'est pas [0-9,] donc je garde bien la virgule et ça permet d'enlever les éventuels caractères spéciaux ou accentués, mais malheureusement sans tenir compte de la nécessité de conserver uniquement les virgules comprises entre 2 chiffres...

bonsoir

oui ben teste donc ceci avec ta logique

bablabla15,56blabla,2,blabla,blabla45,587blablabla,3,56blablabla

LOL

Bonjour Patrick,

Je ne pense pas avoir besoin de tester puisque j'en connais le résultat mais si tu veux faire des essais, je t'en prie...

Like [A-z] permet d'enlever les lettres mais pas les caractères accentués et spéciaux.

Not Like [0-9,] permet de tout enlever sauf les chiffres et virgules, ce qui est mieux mais pas parfait puisque, pour les virgules, le pattern "#,#" n'est pas considéré étant donné qu'on examine seulement caractère par caractère sans tenir compte du bloc auquel ils appartiennent.

Il faudrait donc passer par une autre boucle pour n'avoir que les valeurs numériques.

re

tu est sur de ne pas vouloir tester par ce qu'avec ta logique j'obtient

de ca

ablabla15,56blabla,2,blabla,blabla45,587blablabla,3,56blablabla

j'obtiens ça

15,56 ,2, , 45,587 , 3,56

j'avais mis justement des coquilles dans la chaîne pour te montrer que tu est loin du compte avec un seul motif simple

le",2, ," est inexploitable dans le sens ou on ne sais pas a quel nombre il appartient et je parle même pas de l'item vide tout du moins qui contient qu'une virgule si on split la chaîne résultante par les espaces

Mais oui, c'est ce que je te dis depuis le début (je t'invite à me relire !) . Mais avec le like [A-z], c'est encore pire puisqu'on aurait les mêmes coquilles plus celles liées aux autres caractères...

Il faudrait donc rajouter une boucle pour épurer les mauvaises valeurs...

Alors qu'avec une expression régulière .

re

on rajoute pas d'autre boucles on fait 2 tests supplémentaires et pour cela on peut utiliser (par exemple )la négation de l’opérateur like

si mid(chaine,i,2) like un espace et une virgule après on la saute aussi

si mid(chaine,i,2) like une virgule mais pas un chiffre après on la saute aussi

comme ceci par exemple

Sub test()
    chaine = "ablabla15,56blabla,2,blabla,blabla45,587blablabla,3,56blablabla "
    For i = 1 To Len(chaine) - 1
        If Mid(chaine, i, 1) Like "[A-z]" Then Mid(chaine, i, 1) = " "
        If Mid(chaine, i, 2) Like " ," Then Mid(chaine, i + 1, 1) = " "
        If Mid(chaine, i, 2) Like "," & "[!0-9]" Then Mid(chaine, i, 1) = " "    'utilisation de la négation de l'opérateur like(equivalent à (not like"[0-9]")
    Next
    MsgBox Application.Trim(chaine)
End Sub

a noter que j'aurais pu l’écrire comme ça",[!0-9]"

Oui en effet mais ça devient compliqué... Le [A-z] n'est pas assez précis. Il faut gérer la fin de chaine car je ne sais pas comment se comporte la fonction mid mais j'imagine qu'elle retourne sur le premier caractère ou renvoie erreur. Et on se rapproche finalement des solutions préconisées avant.

Mais en l'absence d'expression régulière, c'est très bien, c'est sûr .

Edit : J'ai répondu un peu vite sur la fin de chaine, n'ayant pas vu le len - 1 .

Bonjour à tous,

Si [A-z] n'est pas assez précis, [A-zÀ-ÖÙ-öù-ÿŒœ] le sera peut-être

Salut Baboutz,

En effet ! Tu la gardes toujours dans la manche alors ? Mais le not like [0-9,] est très bien aussi...

re

bonjour Baboutz

on a pas le choix sans expression réguliere on ajoute un espace a la fin de la chaine

on teste mid(i,1) like"[A-z]"(maj et min pour englober les deux series)équivalent à"[A-Z-a-z]"

ensuite on a remplacer le caractère precédent par un espace si c'etait une lettre donc si on a une virgule

si mid(chaine,i,2) like " ,"

et si la virgule est suivie par une lettre

si mid(chaine,i,2) like ",[!0-9]" equivalent à si mid(chaine,i,1)="," and not mid(chaine ,i+1,1)like "[0-9]"

c'est pas complique comme je teste jusqu'au len(chaine)-1 vous comprenez maintenant pourquoi j'ajoute un espace a la fin

de toute facon a la fin je trim donc pas de soucis

il peut être très puissant l’opérateur like

comme on le vois dans cette démo je garde les bonnes virgule celles qui sont non désirées sont bien supprimées

demo7



patricktoulon, 3GB voulait mentionner le fait que [A-z] ne prend pas en compte les accents.

accent 3gb patrick

Tu la gardes toujours dans la manche alors ?

Bien au chaud

Mais le not like [0-9,] est très bien aussi...

Je n'ai pas du tout étudié votre cas, j'ai juste vu l'occasion de placer mon bout de code

et bien dans ce cas là tu prends la chose a l'envers pour la première ligne

like"[!0-9-,]"

ce qui est équivalent a not like numerique et not like virgule

Sub test()
    chaine = "ablabla15,56bàèéêëüäla,2,blabla,blàèéêëübla45,587blablabla,3,56blablabla "
    For i = 1 To Len(chaine) - 1
        If Mid(chaine, i, 1) Like "[!0-9,]" Then Mid(chaine, i, 1) = " "
        If Mid(chaine, i, 2) Like " ," Then Mid(chaine, i + 1, 1) = " "
        If Mid(chaine, i, 2) Like "," & "[!0-9]" Then Mid(chaine, i, 1) = " "    'utilisation de la négation de l'opérateur like(equivalent à (not like"[0-9]")
    Next
    MsgBox Application.Trim(chaine)
End Sub

pas compliqué

Je crois que le second tiret n'est pas nécessaire.

Oui, ça commence à être bien. Mais comme j'aime bien faire le malin : Quid du cas avec 2 virgules collées entre 2 nombres entiers ?

Non, plus sérieusement, c'est vraiment top et court !

virgule collées entre 2 nombres avec décimal est le 1er des cas insolubles

car vba ne pourrait pas deviner si l'entier du 2d ou une partie de l'entier ferait partie des décimales du premier

a moins d'avoir une règle supplémentaire quand au nombre de décimal par exemple

exemple

335,664,55 va faire deviner à vba toi si cest

335,6 et 64,55

ou

335,66 et 4,55

tu es drôle j'aime bien

Rechercher des sujets similaires à "recuperer valeur numerique texte"