format di lettura



  • format di lettura
    di Slump (utente non iscritto) data: 05/08/2012 11:16:17

    Salve a tutti,
    ho la necessità di creare una macro che legga in una cella una stringa del tipo:
    xxxxx-ddd-C0020-fff-rrrrrr
    dopodiché devo incrementare lo 0020 a 0021 e riscrivere in un'altra cella xxxxx-ddd-C0021-fff-rrrrrr.
    Come posso scorporare la componente numerica da quella di testo?
    Grazie



  • di Vecchio frac data: 05/08/2012

    La soluzione riguarda il maneggiamento di stringhe e sottostringhe.
    la risposta completa dipende da numerosi fattori.

    la stringa ha un formato costante, regolare?
    gli elementi della stringa sono sempre separati dal carattere trattino "-" ?
    la sottostringa alfanumerica di cui vuoi incrementare la parte numerica si trova sempre in terza posizione?
    di questa sottostringa alfanumerica, il primo carattere è sempre un carattere alfabetico e i successivi sono sempre numerici?


    "xxxxx-ddd-c0020-fff-rrrrrr"
    "xxxxx-ddd-c0021-fff-rrrrrr"
    "come posso scorporare la componente numerica da quella di testo? "

    se vuoi evitare le macro, esiste anche una funzione apposita di excel che tratta l'estrazione di sottostringhe da una stringa di testo.
    come diceva vanni qualche tempo fa, fai vedere come cercheresti di implementare una soluzione, con i suggerimenti che ti ho fornito :) dopodichè vedremo di correggere il tiro e fornire soluzioni più ottimizzate.
    magari l'argomento interessa anche altre persone, quindi non lasciamolo cadere nel vuoto :)





  • di Slump (utente non iscritto) data: 05/08/2012 13:51:21

    Ok, grazie per la risposta.
    Il formato del campo da leggere è sempre uguale ed è come l'indicato. Sostanzialmente devo leggere il numero dopo la C del campo centrale (xxxxx-ddd-c0020-fff-rrrrrr), incrementarlo e riscriverlo in un campo successivo. Il campo numerico è sempre composto da quattro cifre dopo una lettera. Detto questo il modo di procedere mi verrebbe abbastanza semplice, vista la mia provenienza fortran (niente commenti...), imposterei una formattazione di lettura da cui verrebbe letto direttamente il numero e allo stesso modo lo riscriverei.
    Es.:
    READ(80,100) temp1,n,temp2
    n=n+1
    WRITE(80,100) temp1,n,temp2
    100 FORMAT(A11,I3,A11)

    Ma dire che sono novello in VBA è un eufemismo. Quindi mi sto ponendo i vari problemi man mano che si presentano. Questa operazione deve essere fatta all'interno di una macro perché è un pezzo di molte altre operazioni.



  • di Vecchio frac data: 05/08/2012

    Fortran va benissimo nel senso che conoscere un linguaggio ti aiuta a comprendere il meccanismo con cui devi ragionare. tradurlo in vba è semplciemente una questione di sintassi, di utilizzare le istruzioni appropriate.

    adesso ti do qualche suggerimento sulle istruzioni che ti serviranno: dall'editor di codice di excel (alt f11) nella finestra immediata (ctrl g) scrivi la parola chiave e poi premi f1 per la guida.
    metti insieme queste informazioni per produrre la macro che poi svilupperemo insieme.
    non sono presuntuoso o cattivo, ma non voglio fornirti subito il pesce quando posso mostrarti come si pesca (a meno che tu non abbia proprio urgenza); e non voglio monopolizzare il forum quando qui c'è altra genete validissima.. vanniiiiii dove seiiiii :)

    il riferimento alla cella del foglio di lavoro che contiene la stringa in esame si fa con l'oggetto range. ad esempio range("a1") è la cella a1 (si scrive anche con le quadre [a1]).

    puoi sia leggere il contenuto della cella (var = activesheet.range("a1")) che scriverci (activesheet.[a1]= "pippo").

    ti serve mid(stringa, start, length), che restituisce una sottostringa di una stringa a partire dal carattere indicato per length caratteri.

    split(sringa, delimitatore) invece restituisce un array di stringhe partendo da una stringa, in cui il delimitatore funge da separatore (split("ciao;a;tutti", ";") cosa farà?).

    sulla costruzione di sub e function invece, devi creare un modulo oppure agire nell'editor di un singolo foglio.
    le sub inizianto con private sub e terminano con end sub. nel corpo della procedura scrivi le istruzioni che, nel foglio, puoi anche associare ad un pulsante o a qualsiasi altro evento.
    di questo però ne parliamo se ti serve o quando ti serve ;)





  • di Vecchio frac data: 05/08/2012

    Dimenticavo che esiste anche format(valore, espressione), che attribuisce un formato anche personalizzato al valore indicato. restituisce una stringa. ti sarà utile per formattare un numero tenendo conto degli zeri iniziali.





  • di slump (utente non iscritto) data: 05/08/2012 17:05:38

    ok, fatto così:
    leggo
    stringaprecedente = Cells(i - 1, 3).Text
    numeroprecedente = CInt(Mid(char_prot_prec, 12, 4))

    incremento
    num_prot = numeroprecedente + 1

    ricostruisco e scrivo
    If num_prot < 10 Then
    charnum_prot = "000" & num_prot
    ElseIf num_prot < 100 Then
    charnum_prot = "00" & CStr(num_prot)
    ElseIf num_prot < 1000 Then
    charnum_prot = "0" & CStr(num_prot)
    Else: charnum_prot = CStr(num_prot)
    End If
    char_prot = "xxxxx-ddd-c" & charnum_prot & "-fff-rrrrrrr"


    molto poco elegante, non mi piace ed è poco flessibile. Ma funziona.
    Grazie moltissime, sei stato di grande aiuto con mid()



  • di Vecchio frac data: 05/08/2012

    Bravo! benissimo, perché funziona. e' un primo passo. apprezzo molto che ti sei applicato e hai ottenuto un ottimo risultato!
    ora vediamo di migliorare... :)
    ad esempio, ti ho suggerito format che permette di formattare un numero rappresentandolo anche con degli zeri non significativi: per ottenere "00045" posso utilizzare format(45, "00000").

    puoi ottimizzare ricorrendo ad una ricerca e sostituzione in place, con left, right e mid; oppure con la soluzione più elegante, con split e join.

    ti propongo due soluzioni, entrambe molto compatte, sottoforma di due funzioni richiamabili dal resto del codice, più o meno con:

    stringa_precedente = cells(i - 1, 3).text
    stringa_attuale = incrementa_numero(stringa_precedente)
    'a cui deve seguire l'istruzione per scrivere nella cella giusta la stringa_attuale

    p.s. quando proponi del codice, utilizza il secondo riquadro della schermata di inserimento del messaggio, così il codice viene formattato automaticamente
     
    '1.a soluzione
    Private Function incrementa_numero(s As String) As String
    Dim token1 As String, numero As String, token2 As String
        token1 = Left(s, 11)
        numero = Mid(s, 12, 4)
        token2 = Mid(s, 16)
        
        incrementa_numero = token1 & Format(Val(numero) + 1, "0000") & token2
    
    End Function
    
    '2.a soluzione
    Private Function incrementa_numero2(s As String) As String
    Dim v As Variant, numero As String
        
        v = Split(s, "-")
        v(2) = Left(v(2), 1) + Format(Mid(v(2), 2) + 1, "0000")
        incrementa_numero2 = Join(v, "-")
    
    End Function
    
    






  • di Harrybosch data: 06/08/2012

    Ciao ragazzi
    ho fatto un pò di giorni in relax, quindi non ho "sentito" subito il richiamo di francesco che ha già fornito le più valide soluzioni al caso.
    posso solo aggiungere che concordo sul fatto che la funzione "split-join" sia in assoluto il sistema più efficace; ti permette di memorizzare la stringa e spezzettarla, estrarne la parte, o parti, che interessano (in questo caso specifico l'incremento della parte numerica), e lavorare su questa per poi riunire la nuova stringa con il pezzettino modificato. sarebbe stata la soluzione che anch'io avrei proposto, molto simile a quella indicata da francesco (dal quale c'è sempre da imparare!).
    anch'io volevo fare i complimenti a slump, perchè è arrivato comunque allo scopo finale attraverso una strada diversa, seppur "meno elegante". io stesso "sfrutto" il forum proprio per cercare di migliorare le mie conoscenze e devo dire che il confronto con gli altri è indubbiamente uno dei sistemi più efficaci.

    ciao, vanni