Faisant suite à la question de Greg
"comment récupérer les chiffre 142 et le 9;
exemple
SCALE: 1//142.9g/"
Comme je l'indiquais dans ma réponse initiale, ce genre de problème
se résoud typiquement par un petit automate à états finis, suivant
la technique décrite dans l'article de la FAQ:
http://faq.vb.free.fr/index.php?question=133
Plutot qu'un long discours, voici comment on peut modéliser le
problème.
Description:
- Lire jusqu'au double slash
- Stocker les chiffres jusqu'à un point
- consommer le point
- lire les chiffres tant qu'il y en a (et les stocker)
Voici l'automate à états finis correspondant:
(Les états sont entre crochets carrés, les transitions entre
parenthèses. Les états finaux sont entre double crochets
carrés.).
Les états de sortie valides sont les états 6 et 7. L'état 4 est
final et invalide.
Il ne reste plus qu'à coder notre automate, ce qui se fait de façon
entièrement mécanique (c'est la beauté de la chose) :
Option Explicit
Function SplitScale(ByVal s As String, _
ByRef first As String, _
ByRef last As String) As Boolean
Dim etat As Integer
Dim car As String
Dim l As Long
Dim i As Long
Dim validStates As String
validStates = "6,7,"
l = Len(s)
If l > 0 Then
etat = 0
For i = 1 To l
car = Mid$(s, i, 1)
Select Case etat
Case 0
If IsSlash(car) Then
etat = 1
End If
Case 1
If IsSlash(car) Then
etat = 2
Else
etat = 0
End If
Case 2
If IsDigit(car) Then
first = first & car
etat = 3
Else
etat = 4 ' FIN
End If
Case 3
If IsDigit(car) Then
first = first & car
etat = 3
ElseIf IsDot(car) Then
etat = 5
Else
etat = 4 ' FIN
End If
Case 4
Exit For ' Force FIN
Case 5
If IsDigit(car) Then
last = last & car
etat = 6
Else
etat = 4 ' FIN
End If
Case 6
If IsDigit(car) Then
last = last & car
etat = 6
Else
etat = 7
End If
Case 7
etat = 7
End Select
Next i
End If
If InStr(validStates, Trim$(Str$(etat)) & ",") > 0 Then
SplitScale = True
Else
SplitScale = False
End If
End Function
Private Function IsDigit(ByVal car As String) As Boolean
If car >= "0" And car <= "9" Then
IsDigit = True
End If
End Function
Private Function IsSlash(ByVal car As String) As Boolean
If car = "/" Then
IsSlash = True
End If
End Function
Private Function IsDot(ByVal car As String) As Boolean
If car = "." Then
IsDot = True
End If
End Function
Et pour tester:
Dim s As String
Dim first As String
Dim last As String
Dim ret As Boolean
s = Text1.Text
ret = SplitScale(s, first, last)
Label1.Caption = ret & " " & first & " " & last
Et voila. On a maintenant une fonction qui non seulement
fait ce qu'on voulait (récupérer ce qu'il faut de part et d'autre
de la virgule) mais qui en plus valide syntaxiquement la chaine.
Et cerise sur le gateau, ce genre d'implémentation est simplissime
à lire et à modifier si nécessaire.
Faisant suite à la question de Greg "comment récupérer les chiffre 142 et le 9; exemple SCALE: 1//142.9g/"
Comme je l'indiquais dans ma réponse initiale, ce genre de problème se résoud typiquement par un petit automate à états finis, suivant la technique décrite dans l'article de la FAQ: http://faq.vb.free.fr/index.php?question3
Plutot qu'un long discours, voici comment on peut modéliser le problème.
Description: - Lire jusqu'au double slash - Stocker les chiffres jusqu'à un point - consommer le point - lire les chiffres tant qu'il y en a (et les stocker)
Voici l'automate à états finis correspondant: (Les états sont entre crochets carrés, les transitions entre parenthèses. Les états finaux sont entre double crochets carrés.).
Les états de sortie valides sont les états 6 et 7. L'état 4 est final et invalide.
Il ne reste plus qu'à coder notre automate, ce qui se fait de façon entièrement mécanique (c'est la beauté de la chose) :
Option Explicit
Function SplitScale(ByVal s As String, _ ByRef first As String, _ ByRef last As String) As Boolean
Dim etat As Integer Dim car As String Dim l As Long Dim i As Long Dim validStates As String
validStates = "6,7,"
l = Len(s)
If l > 0 Then
etat = 0 For i = 1 To l car = Mid$(s, i, 1) Select Case etat Case 0 If IsSlash(car) Then etat = 1 End If Case 1 If IsSlash(car) Then etat = 2 Else etat = 0 End If Case 2 If IsDigit(car) Then first = first & car etat = 3 Else etat = 4 ' FIN End If Case 3 If IsDigit(car) Then first = first & car etat = 3 ElseIf IsDot(car) Then etat = 5 Else etat = 4 ' FIN End If Case 4 Exit For ' Force FIN Case 5 If IsDigit(car) Then last = last & car etat = 6 Else etat = 4 ' FIN End If Case 6 If IsDigit(car) Then last = last & car etat = 6 Else etat = 7 End If Case 7 etat = 7 End Select Next i End If
If InStr(validStates, Trim$(Str$(etat)) & ",") > 0 Then SplitScale = True Else SplitScale = False End If End Function
Private Function IsDigit(ByVal car As String) As Boolean If car >= "0" And car <= "9" Then IsDigit = True End If End Function
Private Function IsSlash(ByVal car As String) As Boolean If car = "/" Then IsSlash = True End If End Function
Private Function IsDot(ByVal car As String) As Boolean If car = "." Then IsDot = True End If End Function
Et pour tester:
Dim s As String Dim first As String Dim last As String Dim ret As Boolean
s = Text1.Text ret = SplitScale(s, first, last) Label1.Caption = ret & " " & first & " " & last
Et voila. On a maintenant une fonction qui non seulement fait ce qu'on voulait (récupérer ce qu'il faut de part et d'autre de la virgule) mais qui en plus valide syntaxiquement la chaine.
Et cerise sur le gateau, ce genre d'implémentation est simplissime à lire et à modifier si nécessaire.
Bonne soirée !
Cordialement;
Superbe. Il y a bien longtemps que je n'avais pas entendu parler des automates à état fini.
Jean-marc a écrit :
Hello à tous,
Faisant suite à la question de Greg
"comment récupérer les chiffre 142 et le 9;
exemple
SCALE: 1//142.9g/"
Comme je l'indiquais dans ma réponse initiale, ce genre de problème
se résoud typiquement par un petit automate à états finis, suivant
la technique décrite dans l'article de la FAQ:
http://faq.vb.free.fr/index.php?question3
Plutot qu'un long discours, voici comment on peut modéliser le
problème.
Description:
- Lire jusqu'au double slash
- Stocker les chiffres jusqu'à un point
- consommer le point
- lire les chiffres tant qu'il y en a (et les stocker)
Voici l'automate à états finis correspondant:
(Les états sont entre crochets carrés, les transitions entre
parenthèses. Les états finaux sont entre double crochets
carrés.).
Les états de sortie valides sont les états 6 et 7. L'état 4 est
final et invalide.
Il ne reste plus qu'à coder notre automate, ce qui se fait de façon
entièrement mécanique (c'est la beauté de la chose) :
Option Explicit
Function SplitScale(ByVal s As String, _
ByRef first As String, _
ByRef last As String) As Boolean
Dim etat As Integer
Dim car As String
Dim l As Long
Dim i As Long
Dim validStates As String
validStates = "6,7,"
l = Len(s)
If l > 0 Then
etat = 0
For i = 1 To l
car = Mid$(s, i, 1)
Select Case etat
Case 0
If IsSlash(car) Then
etat = 1
End If
Case 1
If IsSlash(car) Then
etat = 2
Else
etat = 0
End If
Case 2
If IsDigit(car) Then
first = first & car
etat = 3
Else
etat = 4 ' FIN
End If
Case 3
If IsDigit(car) Then
first = first & car
etat = 3
ElseIf IsDot(car) Then
etat = 5
Else
etat = 4 ' FIN
End If
Case 4
Exit For ' Force FIN
Case 5
If IsDigit(car) Then
last = last & car
etat = 6
Else
etat = 4 ' FIN
End If
Case 6
If IsDigit(car) Then
last = last & car
etat = 6
Else
etat = 7
End If
Case 7
etat = 7
End Select
Next i
End If
If InStr(validStates, Trim$(Str$(etat)) & ",") > 0 Then
SplitScale = True
Else
SplitScale = False
End If
End Function
Private Function IsDigit(ByVal car As String) As Boolean
If car >= "0" And car <= "9" Then
IsDigit = True
End If
End Function
Private Function IsSlash(ByVal car As String) As Boolean
If car = "/" Then
IsSlash = True
End If
End Function
Private Function IsDot(ByVal car As String) As Boolean
If car = "." Then
IsDot = True
End If
End Function
Et pour tester:
Dim s As String
Dim first As String
Dim last As String
Dim ret As Boolean
s = Text1.Text
ret = SplitScale(s, first, last)
Label1.Caption = ret & " " & first & " " & last
Et voila. On a maintenant une fonction qui non seulement
fait ce qu'on voulait (récupérer ce qu'il faut de part et d'autre
de la virgule) mais qui en plus valide syntaxiquement la chaine.
Et cerise sur le gateau, ce genre d'implémentation est simplissime
à lire et à modifier si nécessaire.
Bonne soirée !
Cordialement;
Superbe. Il y a bien longtemps que je n'avais pas entendu parler des
automates à état fini.
Faisant suite à la question de Greg "comment récupérer les chiffre 142 et le 9; exemple SCALE: 1//142.9g/"
Comme je l'indiquais dans ma réponse initiale, ce genre de problème se résoud typiquement par un petit automate à états finis, suivant la technique décrite dans l'article de la FAQ: http://faq.vb.free.fr/index.php?question3
Plutot qu'un long discours, voici comment on peut modéliser le problème.
Description: - Lire jusqu'au double slash - Stocker les chiffres jusqu'à un point - consommer le point - lire les chiffres tant qu'il y en a (et les stocker)
Voici l'automate à états finis correspondant: (Les états sont entre crochets carrés, les transitions entre parenthèses. Les états finaux sont entre double crochets carrés.).
Les états de sortie valides sont les états 6 et 7. L'état 4 est final et invalide.
Il ne reste plus qu'à coder notre automate, ce qui se fait de façon entièrement mécanique (c'est la beauté de la chose) :
Option Explicit
Function SplitScale(ByVal s As String, _ ByRef first As String, _ ByRef last As String) As Boolean
Dim etat As Integer Dim car As String Dim l As Long Dim i As Long Dim validStates As String
validStates = "6,7,"
l = Len(s)
If l > 0 Then
etat = 0 For i = 1 To l car = Mid$(s, i, 1) Select Case etat Case 0 If IsSlash(car) Then etat = 1 End If Case 1 If IsSlash(car) Then etat = 2 Else etat = 0 End If Case 2 If IsDigit(car) Then first = first & car etat = 3 Else etat = 4 ' FIN End If Case 3 If IsDigit(car) Then first = first & car etat = 3 ElseIf IsDot(car) Then etat = 5 Else etat = 4 ' FIN End If Case 4 Exit For ' Force FIN Case 5 If IsDigit(car) Then last = last & car etat = 6 Else etat = 4 ' FIN End If Case 6 If IsDigit(car) Then last = last & car etat = 6 Else etat = 7 End If Case 7 etat = 7 End Select Next i End If
If InStr(validStates, Trim$(Str$(etat)) & ",") > 0 Then SplitScale = True Else SplitScale = False End If End Function
Private Function IsDigit(ByVal car As String) As Boolean If car >= "0" And car <= "9" Then IsDigit = True End If End Function
Private Function IsSlash(ByVal car As String) As Boolean If car = "/" Then IsSlash = True End If End Function
Private Function IsDot(ByVal car As String) As Boolean If car = "." Then IsDot = True End If End Function
Et pour tester:
Dim s As String Dim first As String Dim last As String Dim ret As Boolean
s = Text1.Text ret = SplitScale(s, first, last) Label1.Caption = ret & " " & first & " " & last
Et voila. On a maintenant une fonction qui non seulement fait ce qu'on voulait (récupérer ce qu'il faut de part et d'autre de la virgule) mais qui en plus valide syntaxiquement la chaine.
Et cerise sur le gateau, ce genre d'implémentation est simplissime à lire et à modifier si nécessaire.
Bonne soirée !
Cordialement;
Superbe. Il y a bien longtemps que je n'avais pas entendu parler des automates à état fini.