Riconoscere i valori in una stringa



  • Riconoscere i valori in una stringa
    di Hellboy (utente non iscritto) data: 19/10/2015 11:55:52

    Ciao ragazzi, devo realizzare un progettino.
    Sto scrivendo VBE di excel una funzione, nella quale passo 2 parametri ,ovvero una stringa e la sua lunghezza.
    Ecco qua:
    Public Function Movimentazione(StringaPassata As String, LunghezzaStringa As Integer) As Integer

    la stringa è del tipo
    T23.43G34.34
    D22.13L4

    Ovvero, lettere e numeri(il punto dev'essere interpretato come numero).

    Vorrei che per ogni blocco il programma di dicesse:

    "Il valore "&lettera&" =" &Valore

    Ma non riesco ad implementare un ciclo funzionale , sto diventando matto. Potete aiutarmi ?
    Il valore della lettera puo' essere ottenuto anche sottoforma si stringa e poi riconvertito ?


     
    Public Function Movimentazione(StringaPassata As String, LunghezzaStringa As Integer) As Integer
    
    Dim ContatoreCaratteriTesto As Integer
    Dim CarattereOttenutoDallaLettura As String
    Dim ValoreCarattereCNC As String
    Dim CarattereAcquisito As String
    Dim QuantiCaratteriDopoIlValoreNonNumerico As Integer
        ContatoreCaratteriTesto = 1
        CarattereOttenutoDallaLettura = ""
        ValoreCarattereCNC = 0
        CarattereAcquisito = ""
        QuantiCaratteriDopoIlValoreNonNumerico = 0
         
         
         
    '''da questo ciclo devo ricavare la lettera ed il numero che la accompagna, Es: G0.125 Lettera=G  Numero=0.125
         Do While ContatoreCaratteriTesto <= LunghezzaStringa
                  CarattereOttenutoDallaLettura = Mid(StringaPassata, ContatoreCaratteriTesto, 1)
                  If IsNumeric(CarattereOttenutoDallaLettura) = False And CarattereOttenutoDallaLettura <> "." Then
                     CarattereAcquisito = CarattereOttenutoDallaLettura
                     MsgBox " Ora valuto il carattere " & CarattereAcquisito
                     QuantiCaratteriDopoIlValoreNonNumerico = 0
                  Else
                     'In questa parte dovrei riuscire a scoprirre il valore numerico della lettera sotto esame
                     
                     '.... penso ci vorrebbe un ciclo do while fino a che dalla prima lettera si trova la seconda
                     'ma che nel frattempo immagazzini il valore, e una volta uscito dal ciclo
                     'mi dica Il valore associato a G è 0.125 e continui fino ad esaminare tutta la riga
                  End If
                     
                 MsgBox " Qui il messaggio "
                 ContatoreCaratteriTesto = ContatoreCaratteriTesto + 1
         Loop
    
    End Function
    
    



  • di hellboy (utente non iscritto) data: 19/10/2015 17:40:18

    al momento sono riuscito a costruire un array dove posizione le posizione delle lettere nella stringa dati, ora dovrei anallizzare tutta la stringa es estrapolare di volta in volta la parte che mi interessa per poter dire .... " la lettera Y ha il valore 123" , "La lettera G ha il valore 10.23" e cosi via.... ma non riesco.
     
    Dim Cont As String
    Dim CarattereFunzione As String
    Dim PosizioneCarattereFunzione(1 To 5) As Integer ' Un massimo di 5 caratteri presenti per ogni riga penso possa bastare
    Dim IndiceArray As Integer
    Dim N As Integer
    Cont = ""
    IndiceArray = 0
    Dim i As Integer
    
    For N = 1 To Len(StringaPassata)
    If IsNumeric(Mid(StringaPassata, N, 1)) Or StrComp(Mid(StringaPassata, N, 1), ".") = 0 Then
       Cont = Cont & Mid(StringaPassata, N, 1)
    Else
      CarattereFunzione = Mid(StringaPassata, N, 1)
      IndiceArray = IndiceArray + 1
      PosizioneCarattereFunzione(IndiceArray) = N
    End If
    Next
    
    i = 1
    Do While i <= IndiceArray
       MsgBox "i=" & i & "  Indice=" & IndiceArray
       MsgBox " Lettera trovata in posizione " & PosizioneCarattereFunzione(i)
       i = i + 1
    Loop
    



  • di Mister_x (utente non iscritto) data: 19/10/2015 18:01:12

    ciao

    ma la tua funzione in pratica cosa deve fare???
    ad una funzione si possono passare molti parametri, ma il ritorno e' solamente un valore,
    sia che sia di testo o numerico ma solamente uno, msgbox non penso che si possa fare in quanto avresti ogni volta che excel ricalcola, molteplici messaggi
    quindi ricapitolando dai tuoi dati esposti
    T23.43G34.34
    D22.13L4

    cosa vorresti ritrovarti nella cella dove vai ad inserire la tua funzione????
    T23.43
    G34.34
    D22.13
    L4
    quale di questi risultati ???

    prova a postare un file tuo e metti manualmente cosa vuoi ottenere nella cella accanto

    ciao






  • di Hellboy (utente non iscritto) data: 20/10/2015 07:57:29

    Es di testo che devo decifrare
    F13.23M6
    L1Z7.000
    L2X0.000Y0.000T15000M3

    leggo il primo rigo e scopro che
    ...quindi alla funzione passero' il valore F13.23 e M6
    per scoprire che F vale 13.23 ed M vale 6,
    distinguendo le lettere ed i valori ad esse associati.
    E cosi per l'ultimo rigo dove ci sono più lettere e quindi più valori.

    Ma non devo usare nessuna cella di EXCEL, ma tutto tramite VB Script.....
    possiamo anche pensare di fa apparire un messaggio con la dicitura "F vale 13.23" poi me la giostro io.

    Grazie dell'interessamento.



  • di isy data: 20/10/2015 09:38:15

    Ciao

    Propongo questa function, inserisci il codice in un modulo
     
    Option Explicit
    
    Function SplitOnCapital(str As String) As String
        Dim Length As Long, x As Long
        Dim par As String, cod As String
        If str = "" Then Exit Function
            Length = Len(str)
            If Length > 1 Then
                For x = Length To 2 Step -1
                par = Mid(str, x, 1)
                cod = Asc(par)
                If (cod > 64 And cod < 91) Or (cod > 191 And cod < 222) Then
                str = Left(str, x - 1) + " " + Mid(str, x)
                End If
            Next
            SplitOnCapital = str
            End If
    End Function



  • di hellboy (utente non iscritto) data: 20/10/2015 10:16:51

    Intanto, complimenti per la pulizia del codice !!!

    ...come risultato mi ridà quello che già ero riuscito a fare, ora, dovrei modificare questo codice per farmi dire dal programma:
    T vale 10, Y vale 30, G vale 4.32 .... per ogni riga letta, in modo da sapere per ogni carattere il suo valore numerico.



  • di Mister_x (utente non iscritto) data: 20/10/2015 10:20:08

    ciao

    dato che non vuoi visualizzare nessun dato su celle ti passo una sub() ,che se attivata ti fa questo lavoro sulla cella attiva
    puoi mettere un bottone collegata a questa per attivarla

    ti passo anche il file di prova

    ciao
     
    Option Explicit
    Sub DividiTesto()
    Dim i As Long
    Dim testo As String, DivSt As String
    testo = ActiveCell.Value
    DivSt = ""
    For i = 1 To Len(testo)
    If Asc(Mid(testo, i, 1)) >= 48 And Asc(Mid(testo, i, 1)) <= 57 Then
      DivSt = DivSt & Mid(testo, i, 1)
    ElseIf Mid(testo, i, 1) = "." Then
       DivSt = DivSt & Mid(testo, i, 1)
    Else
       DivSt = DivSt & Chr(10) & Mid(testo, i, 1)
    End If
    Next i
     MsgBox (DivSt)
    End Sub
    






  • di isy data: 20/10/2015 10:24:22

    Ciao

    Aggiungi un ciclo split all'interno della function

    Allega un file d'esempio dove mostri come devono apparire i dati sul foglio



  • di hellboy (utente non iscritto) data: 20/10/2015 10:39:05

    ho aggiunto qualche riga al codice per cercare di farti capire meglio il mio problema.

    Intanto già stiamo al 97% della risoluzione :) :)

    Dove ho scirtto il messaggio MsgBox "Hai ottenuto il seguente valore" & DivSt
    in DivSt dovrebbe uscirmi il valore T10 (quello che poi passero' tramite funzione, ma questo ce la faccio anche da solo)

    Il codie che hai scritto è perfetto, ma mi interessa poter dividere le varie righe...

    Il file di testo che leggo è questo
    F0M0.000Y0.000S15000T3
    F0M-13.000Y0.000W7.000

    e vorrei che tramite messaggio, scomponesse le stringhe e mi trovasse i risultati.
    Msgbox " "&Valore dove valore = F0
    Msgbox " "&Valore dove valore = M0.000
    ...
    ....
    ...
    Msgbox " "&Valore dove valore = W7.000


     
    Dim i As Long
    Dim DivSt As String
    DivSt = ""
    For i = 1 To Len(Str)
    If Asc(Mid(Str, i, 1)) >= 48 And Asc(Mid(Str, i, 1)) <= 57 Then  ' qui leggo il valore numerico
      DivSt = DivSt & Mid(Str, i, 1)
    ElseIf Mid(Str, i, 1) = "." Then   ' qui leggo il punto
       DivSt = DivSt & Mid(Str, i, 1)
    Else
       If DivSt <> "" Then
          MsgBox "Hai ottenuto il seguente valore" & DivSt
          DivSt = ""
          DivSt = DivSt & Chr(10) & Mid(Str, i, 1)  ' qui leggo le lettere
       Else
          DivSt = DivSt & Chr(10) & Mid(Str, i, 1)  ' qui leggo le lettere
       End If
    End If
    Next i



  • di hellboy (utente non iscritto) data: 20/10/2015 10:45:18

    oppure, li dove leggi i caratteri della stringa, non capisco come fai a mandare a capo.
    Li , quando mandi a capo, prima di inziare la nuova stringa, dovremmo estrapolare quello letto che è quello che mi interessa.



  • di Albatros54 data: 20/10/2015 11:51:38

    Se ho capito, prova il codice sotto, selezionando piu celle dove hai i valori
    Ciao
    albatros54
     
    Sub DividiTesto()
    Dim i As Long
    Dim testo As String, DivSt As String, rng As Range, cl As Range
     Set rng = Selection
    DivSt = ""
    For Each cl In rng
    For i = 1 To Len(cl)
    If Asc(Mid(cl, i, 1)) >= 48 And Asc(Mid(cl, i, 1)) <= 57 Then
      DivSt = DivSt & Mid(cl, i, 1)
    ElseIf Mid(cl, i, 1) = "." Then
       DivSt = DivSt & Mid(cl, i, 1)
    Else
       DivSt = DivSt & Chr(10) & Mid(cl, i, 1)
    End If
    Next i
    MsgBox (DivSt)
    DivSt = ""
    Next
     
    End Sub
    






  • di isy data: 20/10/2015 11:52:52

    Ciao

    Sempre con una Function
    In questa ho aggiunto un secondo parametro per indicare quale valore stringa visualizzare.
     
    Option Explicit
    
    Function SplitOnCapital(str As String, Optional Match As Long) As String
        Dim Length As Long, x As Long
        Dim par As String, cod As String
        Dim arr
        If str = "" Then Exit Function
            Length = Len(str)
            If Length > 1 Then
                For x = Length To 2 Step -1
                    par = Mid(str, x, 1)
                    cod = Asc(par)
                    If (cod > 64 And cod < 91) Or (cod > 191 And cod < 222) Then
                    str = Left(str, x - 1) + " " + Mid(str, x)
                    End If
                Next
                arr = Split(str, " ")
                If Match > UBound(arr) Then
                  SplitOnCapital = ""
                Else
                  SplitOnCapital = Mid(arr(Match), 2, 80)
                End If
            End If
    End Function



  • di Mister_x (utente non iscritto) data: 20/10/2015 12:09:08

    ciao

    PS Dichiarare sempre le variabili, e non tagliare le Sub() quando si passano
    Dire sempre a chi ti Rivolgi

    stesso concetto di prima

    ciao
     
    Option Explicit
    
    Sub DividiTesto2()
    Dim i As Long
    Dim DivSt As String, Str As String
    Str = ActiveCell
    DivSt = ""
    For i = 1 To Len(Str)
    If Asc(Mid(Str, i, 1)) >= 48 And Asc(Mid(Str, i, 1)) <= 57 Then  ' qui leggo il valore numerico
      DivSt = DivSt & Mid(Str, i, 1)
    ElseIf Mid(Str, i, 1) = "." Then   ' qui leggo il punto
       DivSt = DivSt & Mid(Str, i, 1)
    Else
       If DivSt <> "" Then
          MsgBox "Hai ottenuto il seguente valore" & DivSt
          DivSt = ""
          DivSt = DivSt & Chr(10) & Mid(Str, i, 1)  ' qui leggo le lettere
       Else
          DivSt = DivSt & Chr(10) & Mid(Str, i, 1)  ' qui leggo le lettere
       End If
    End If
    Next i
    MsgBox "Hai ottenuto il seguente valore" & DivSt 'ultimo messaggio
    End Sub
    






  • di hellboy (utente non iscritto) data: 20/10/2015 12:18:46

    Grazie Mister_x, cosi funge alla grande !!! :) :)
    Bel codice, spero un giorno di riuscire anche io a scrivere cosi !!!
    Complimenti.



  • di Hellboy (utente non iscritto) data: 20/10/2015 16:22:14

    Scusate, avevo cantato vittoria troppo presto.
    Il codice è favoloso, trova le coppie caratteri+numeri in un rigo X letto.
    Pero' riesco a passare il valore ad una funzione,solo quando arrivo a fine rigo.

    Es:
    Del rigo X0.01T-23Z87
    Vorrei passare ad una funzione i 3 valori
    X0.01
    T-23
    Z87
    ma riesco a passare solo Z87.
     
    Option Explicit
    ''Con questa funzione trovo le coppie caratteri+numeri nel rigo letto
    Public Function DividiStringa(Str As String) As String
    
    Dim i As Long
    Dim DivSt As String
    DivSt = ""
    For i = 1 To Len(Str)
    If (Asc(Mid(Str, i, 1)) >= 48 And Asc(Mid(Str, i, 1)) <= 57) Or Mid(Str, i, 1) = "." Or Mid(Str, i, 1) = "-" Then ' qui leggo il valore numerico
      DivSt = DivSt & Mid(Str, i, 1)
    Else
       If DivSt <> "" Then
          DividiStringa = DivSt
          MsgBox " 1 " & DividiStringa
          DivSt = ""
          DivSt = DivSt & Chr(10) & Mid(Str, i, 1)  ' qui leggo le lettere
       Else
          DivSt = DivSt & Chr(10) & Mid(Str, i, 1)  ' qui leggo le lettere
       End If
    End If
    Next i
    DividiStringa = DivSt
    MsgBox " 2 " & DividiStringa
    
    End Function



  • di HELLBOY (utente non iscritto) data: 20/10/2015 16:36:05

    Perchè in pratica, è vero che mi trova i valori delle coppia LETTERE+NUMERI,
    ma dentro al ciclo non riesco a passare i valori, anche se li trovo , e quando esce fuori dal ciclo, mi passa solo l'ultimo valore (Coppia lettera+numero) trovato.
     
    Dim i As Long
    Dim DivSt As String
    DivSt = ""
    For i = 1 To Len(Str)
    If (Asc(Mid(Str, i, 1)) >= 48 And Asc(Mid(Str, i, 1)) <= 57) Or Mid(Str, i, 1) = "." Or Mid(Str, i, 1) = "-" Then ' qui leggo il valore numerico
      DivSt = DivSt & Mid(Str, i, 1)
    Else
       If DivSt <> "" Then
          DividiStringa = DivSt
          MsgBox " 1 " & DividiStringa
    
    DOVREI INSERIRE UNA FUNZIONE DAL NOME  "PASSA VALORE"  QUI
          
          DivSt = ""
          DivSt = DivSt & Chr(10) & Mid(Str, i, 1)
       Else
          DivSt = DivSt & Chr(10) & Mid(Str, i, 1)
       End If
    End If
    Next i
    DividiStringa = DivSt
    
    DOVREI INSERIRE LA STESSA  FUNZIONE DAL NOME  "PASSA VALORE"  QUI
    
    
    MsgBox " 2 " & DividiStringa
    



  • di Mister_x (utente non iscritto) data: 20/10/2015 17:39:45

    ciao

    ricordati che dalla funzione ritorna un solo elemento

    comunque questa funzione, (Inserire in un modulo di classe) fa quello che tu speri di ottenere, avrai ancora dei proplemi in quanto quello che vedi non e' un valore reale ma un ritorno di dati
    comunque ammettiamo in A1 il tuo valore in
    B1=dividitesto(A1) Ps questa cella come le altre che utilizzerai va formattata a generale e in allineamento spunta ritorno a capo

    ciao
     
    Option Explicit
    Function DividiTesto(Str As Range) As String
    Dim i As Long
    Dim stringa As String, DivT As String
    stringa = Str.Value
    DivT = ""
    For i = 1 To Len(stringa)
     If (Asc(Mid(stringa, i, 1)) >= 48 And Asc(Mid(stringa, i, 1)) <= 57) Or _
         Mid(stringa, i, 1) = "." Or Mid(stringa, i, 1) = "-" Then
         DivT = DivT & Mid(stringa, i, 1)
     Else
         DivT = DivT & Chr(10) & Mid(stringa, i, 1)
     End If
    Next i
    DividiTesto = Mid(DivT, 2, Len(DivT))
    End Function
    






  • di Hellboy (utente non iscritto) data: 21/10/2015 11:24:45

    Grazie...penso di aver risolto, aggirando il problema.
    Dal momento che avevo bisogno di avere i campi letti, tutti separati per coppie di valori LETTERA+NUMERO
    utilizzando l'algoritmo qui sopra, ho aggiunto qualche riga per far scrivere i valori separati in un foglio excel
    e quindi ora li ho divi cella per cella con le coppie CARATTERE+NUMERO.

    Il codice non sarà bellissimo, ma funziona :)



     
    Dim i As Long
    Dim RigoOrizzontale As Long
    Dim DivSt As String
    DivSt = ""
    RigoOrizzontale = 1 ' inizia dalla cella 1
    For i = 1 To Len(Str)
    
    If (Asc(Mid(Str, i, 1)) >= 48 And Asc(Mid(Str, i, 1)) <= 57) Or Mid(Str, i, 1) = "." Or Mid(Str, i, 1) = "-" Then ' qui leggo il valore numerico
      DivSt = DivSt & Mid(Str, i, 1) ' qui compongo la stringa
    Else
       If DivSt <> "" Then
          Foglio2.Cells(RigoVerticale, RigoOrizzontale) = DivSt
          RigoOrizzontale = RigoOrizzontale + 1
          MsgBox "(1) - Ha collocato bene " & DivSt & "?"
          DivSt = ""
          DivSt = DivSt & Chr(10) & Mid(Str, i, 1)
       Else
          DivSt = DivSt & Chr(10) & Mid(Str, i, 1)
       End If
    End If
    Next i
    Foglio2.Cells(RigoVerticale, RigoOrizzontale) = DivSt
    MsgBox "(1) - Ha collocato bene " & DivSt & "?"