formato numerico textbox



  • formato numerico textbox
    di roberto21 (utente non iscritto) data: 10/02/2015 20:16:26

    Mi scuso in anticipo per questa domanda che magari è stupida, ma mi sta un po' incasinando.
    Sulla mia userform ho una textbox destinata a contenere solo valori numerici. Per controllarla, uso una semplice sub:

    Private Sub TextBoxEntrata_Exit(ByVal Cancel As MSForms.ReturnBoolean)

    If Not IsNumeric(Me.TextBoxEntrata.Value) Then
    MsgBox "Only numeric values allowed"
    Cancel = True
    Else
    Me.CommandInserimento.Enabled = True
    End If
    End Sub

    Il primo problema è che questa trappola non scatta sia scrivendo (ad.es.) 20,34 che scrivendo 20.34, cioè sia scrivendo "all'italiana" che "all'americana" (virgola o punto decimale) gli va sempre bene. Pensavo che, a seconda di come è impostato il computer (punto o virgola decimale) uno dei due dovesse dare errore, ma invece pare (a me, almeno) che, siccome sia il punto che la virgola sono ammessi in un numero (come separatore decimale o delle migliaia), entrambi passano il controllo di ISNUMERIC.
    Il secondo problema correlato è che quando vado a copiare quanto presente nella textbox in una cella del foglio, 20.34 viene correttamente messo come numero, mentre 20,34 viene messo come testo (questo indipendentemente dal settaggio Italia o USA del pc). Infine, se provo a forzare il formato numerico con

    Format (textbox, standard)

    20,34 diventa 2.034 (duemila34). C'è qualcosa che mi sfugge o che posso fare per risolvere questo guazzabuglio?
     
    Private Sub TextBoxEntrata_Exit(ByVal Cancel As MSForms.ReturnBoolean)
        
        If Not IsNumeric(Me.TextBoxEntrata.Value) Then
            MsgBox "Only numeric values allowed"
            Cancel = True
        Else
              Me.CommandInserimento.Enabled = True
        End If
    End Sub



  • di Vecchio Frac data: 10/02/2015 20:31:52

    Avevo messo da qualche parte un esempio su come forzare l'inserimento in una textbox a un pattern di caratteri riconosciuto, lo cerco e se non lo trovo te lo riscrivo (bisogna intercettare il KeyPress nella textbox ed escludere i caratteri non ammessi). In questo modo eviti che si scrivano virgole se vuoi punti e viceversa.

    Per inserire nella cella, formatta la cella come numero prima (o dopo? da provare) dell'inserimento con NumberFormat.

    Sono quasi sicuro che Raffaele mi batterà per l'ennesima volta sul tempo ma io ci provo lo stesso ^_^





  • di scossa data: 10/02/2015 20:49:12

    Giusto uno spunto da adattare al tuo file, converte il . in , e non consente di inserirne più di una.
    Per eliminare gli altri caratteri basta verificare ulteriormente il keycode.



    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



     
    Private Sub CommandButton1_Click()
      Range("A1").Value = Me.TextBox1.Value * 1
    End Sub
    
    Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
      If KeyCode = 190 Or KeyCode = 110 Or KeyCode = 188 Then
        If InStr(Me.TextBox1.Text, ",") > 0 Then KeyCode = 0 Else KeyCode = 188
      End If
    End Sub
    



  • di Vecchio Frac data: 10/02/2015 20:51:57

    Eccoti la soluzione, mi pare anche che funzioni :)
    Non c'è neanche bisogno di validare il numero, lo fa la KeyPress che impedisce l'immissione di lettere e caratteri non numerici. E' consentita solo la virgola come vedi nella Like.
    La Replace nell'evento Exit della textbox è necessaria per trasformare il testo in numero.
    Se preferisci l'immissione con il punto separatore allora non serve nemmeno la Replace (il testo contiene già il punto e il testo viene considerato un numero da Excel).


     
    Option Explicit
    
    Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
        Range("A1") = Replace(TextBox1, ",", ".")
    End Sub
    
    Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
        If Chr(KeyAscii) Like "[!0-9,]" Then
            KeyAscii = 0
            Exit Sub
        End If
    End Sub






  • di Vecchio Frac data: 10/02/2015 20:52:37

    E se non è Raffaele, è scossa che mi batte sul tempo ^_^





  • di scossa data: 10/02/2015 21:09:42

    @Vecchio Frac: mi permetto di completre il tuo codice, per impedire di mettere più di una virgola.
    Ho anche cambiato la trasformazione del testo in numero moltiplicando per 1.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)

     
    Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      If IsNumeric(TextBox1.Value) Then Range("A1") = TextBox1.Value * 1
    End Sub
    
    Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
      Debug.Print KeyAscii
        If Chr(KeyAscii) Like "[!0-9,]" Then
            KeyAscii = 0
        Else
          If KeyAscii = 44 And InStr(TextBox1.Text, ",") > 0 Then KeyAscii = 0
        End If
    End Sub
    



  • di Vecchio Frac data: 10/02/2015 21:32:57

    Sì, ma infatti è un'ottima idea, io avevo abbozzato un pezzo di codice a memoria senza pensare a una validazione sofisticata. La mia era solo una battuta :)





  • di Roberto21 (utente non iscritto) data: 10/02/2015 23:26:07

    Grazie a tutti per i suggerimenti e l'interessamento. Per rispondere ad alcune osservazioni: la cella destinazione è già formattata come numero, ma quando arriva un testo sembra che questo abbia il sopravvento. Formattandola dopo va bene, ma non è tanto elegante: per chi ricorda il mio codice (sì, è sempre lo stesso progettino), io aggiungo una riga ad una tabella, per cui tutti i formati delle celle sono mantenuti.
    Poi, avevo tentato una soluzione con un controllo carattere per carattere (keyPress, codice qui sotto) ma dovevo decidere fra punto e virgola; siccome sembra che funzioni solo il punto, anche gli utenti "italiani" dovevano ricordarsi di usare il punto e non la virgola decimale, come abbiamo tutti imparato a scuola.
    In conclusione, l'idea del replace mi piace. Ho cambiato leggermente il codice come qui sotto, e sembra che funzioni, ma devo fare test più estensivi. Il controllo non è certamente a prova di bomba, p.es non controllo ancora se qualcuno (come dice scossa) scrive più virgole, per cui ci rifletto su e mi studio meglio le vostre proposte. Grazie ancora.
     
    Private Sub TextBoxEntrata_Exit(ByVal Cancel As MSForms.ReturnBoolean)
        ' OnlyNumbers
        If Not IsNumeric(Me.TextBoxEntrata.Value) Then
            MsgBox "Only numeric values allowed"
            Cancel = True
        Else
        'If Me.TextBoxEntrata.Value <> vbNullString Then
         '   Me.TextBoxUscita.Enabled = False
           Me.TextBoxEntrata = Replace(Me.TextBoxEntrata, ",", ".")
           Me.CommandInserimento.Enabled = True
        End If
    End Sub
    
    
    
    
    
    Private Sub TextBoxEntrata_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    Select Case KeyAscii
        Case Asc("0") To Asc("9")
        Case Asc("-")
            If InStr(1, Me.TextBox1.Text, "-") > 0 Or Me.TextBox1.SelStart > 0 Then
                KeyAscii = 0
            End If
        Case Asc(",")
            If InStr(1, Me.TextBox1.Text, ".") > 0 Then
                KeyAscii = 0
            End If
        Case Else
            KeyAscii = 0
    End Select



  • di Vecchio Frac data: 11/02/2015 11:11:22

    Nel tuo KeyPress è perfettamente inutile il case vuoto in Case Asc("0") To Asc("9")
    E il controllo OnlyNumbers è superfluo perchè il keyPress si preoccupa già di validare solo caratteri ammessi (numerici, virgola e segno meno).






  • di scossa data: 11/02/2015 12:03:01

    cit. V.F.: "Nel tuo KeyPress è perfettamente inutile il case vuoto in Case Asc("0") To Asc("9")"

    Sicuro, sciuro?
    Direi che serve, visto che poi c'è

    Case Else
    KeyAscii = 0



    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di roberto21 (utente non iscritto) data: 11/02/2015 12:57:09

    Vero, Vecchio Frac. Ma la chiamata a OnyNumbers è commentata, avrei dovuto cancellarla, era un'altra delle mie prove in cui chiamavo appunto quella sub per la verifica del contenuto. Poi ho cambiato il codice, ho commentato la chiamata (non si può mai sapere...) ed è rimasta lì. Quando avrò finito (???) ripulirò il codice.



  • di Vecchio Frac data: 11/02/2015 13:42:16

    cit. "Direi che serve, visto che poi c'è "
    ---> UCAS :)
    La logica dietro il KeyDown di scossa (e dietro il mio KeyPress con Like) è diversa, e mi pare anche meno confusionaria. Infatti mi ha indotto in confusione.





  • di Roberto21 (utente non iscritto) data: 14/02/2015 16:05:38

    So che rompo, ma anche questa è un po' strana. Siamo rimasti al replace, per cui nella mia textbox c'è un valore numerico col punto decimale. Come detto, ora a me funziona tutto, ma il mio pc è configurato all'americana, con punto decimale e virgola separatore migliaia. Se porto il codice su un pc configurato all'italiana, questo pezzo di codice (in cui metto il valore in una cella, poi ne calcolo una percentuale e la metto in un'altra cella sulla riga successiva) funziona per la prima parte (inserimento valore nella cella) ma il calcolo della percentuale non va (il valore è moltiplicato per cento). Entrambe le celle destinazione sono formattate come valuta con due decimali. Quindi p.es. se nella textbox ho 12.66, nella cella del valore mi va €12,66 e nella cella della percentuale mi va €8,858 invece di €0,0858. Notare che se nel pc "italiano" tolgo il replace e lascio nella textbox 12,66 questo valore viene scritto nella cella destinazione come TESTO (all. a sinistra con la virgola), e stranamente nella percentuale va ancora €8,858. In sostanza devo forzare il punto per evitare la formattazione come testo, ma rimane il problema del calcolo, in cui excel sembra tener conto della configurazione del pc ma in maniera che a me (ma forse non ho ben compreso il meccanismo) pare poco coerente.
    Per il momento ho risolto eliminando il calcolo dal codice e inserendo nella cella della percentuale la formula di calcolo a partire dalla cella inserita correttamente prima, ma un po' di curiosità mi rimane...
     
     'poi bisogna aggiungere una riga al foglio Banca....
    With Worksheets("Banca 2015")
    NewRowBanca = .Range("A2").End(xlDown).Row + 1
     .Cells(NewRowBanca, 1) = Format(Y, "00000")
     .Cells(NewRowBanca, 3) = Me.TextBoxDate
    
     .Cells(NewRowBanca, 4) = Me.TextBoxEntrata
    
    .Cells(NewRowBanca, 6) = "Pagamento Bancomat"
        ' e un'altra riga va aggiunta per le commissioni 
    NewRowBanca = NewRowBanca + 1
    .Cells(NewRowBanca, 1) = Format(Y, "00000")
    .Cells(NewRowBanca, 3) = Me.TextBoxDate
    
    .Cells(NewRowBanca, 5) = Me.TextBoxEntrata * 7 / 1000
    
    .Cells(NewRowBanca, 6) = "Commissioni"
    
    
    
    
     'poi bisogna aggiungere una riga al foglio Banca....
     With Worksheets("Banca 2015")
     NewRowBanca = .Range("A2").End(xlDown).Row + 1
     .Cells(NewRowBanca, 1) = Format(Y, "00000")
     .Cells(NewRowBanca, 3) = Me.TextBoxDate
    
    .Cells(NewRowBanca, 4) = Me.TextBoxEntrata
    
     .Cells(NewRowBanca, 6) = "Pagamento Bancomat"
    
    
               ' e un'altra riga va aggiunta per le commissioni 
    NewRowBanca = NewRowBanca + 1
    Y = "00026"
    .Cells(NewRowBanca, 1) = Format(Y, "00000")
    .Cells(NewRowBanca, 3) = Me.TextBoxDate
    
    .Cells(NewRowBanca, 5).FormulaR1C1 = "=R[-1]C[-1]*7/1000"
    
    .Cells(NewRowBanca, 6) = "Commissioni"