Newsgroup: it.comp.lang.visual-basic
Titolo: Text e gestione decimali

Ciao a tutti,
vorrei sapere come vi comportate voi con delle txt che devono contenere
campi decimali (importi).
In particolare come gestite caricamento dal database (formato del campo),
la modifica dell'utente e il controllo validità del campo quando l'utente
esce.
Personalmente i dati del DB mi vengono restituite in formato Win, quindi li
metto nelle txt formattati come "1.200,53", quando entro nel campo lo
trasformo in "1200.53" (per una vecchia compatibilità) e permetto di
inserire solo il punto e numeri.
All'invio (o lost_focus) lo riformatto come "1.200,53".
Alla memorizzazione su DB lo ritrasformo "1200.53", perchè Firebird lo
vuole in questo formato.
Ho dei problemi quando premo due volte invio sul campo (o invio + tab).
In pratica se scrivo "1200.53" la prima volta mi fa vedere "1.200,53" e a
quel punto al successivo invio/tab mi da "1.20" per il punto credo.
Usate qualche componente apposito che gestisca da solo la validità e
formattazione dei campi decimal/currency?
Grazie

 formattazione dei campi decimal/currency?
Nessun componente.
Basta una funzioncina che ti fai tu, che ti fa una scansione della 
stringa (dopo un trim$), identificando se un carattere è una cifra, un 
punto, una virgola o un qualunque altro separatore locale.
Se un carattere esce da tale range, la stringa non è un numero 
valido->errore
Se tutti i caratteri rientrano in tale range, devi decidere tu come 
vuoi interpretare il numero. Interpretando i separatori secondo le 
impostazioni locali o secondo un formato fisso. Ad esempio "1.234", 
interpretato secondo le impostazioni italiane è 
milleduecentotrentaquattro, secondo le impostazioni americane è uno e 
rotti. Tu cosa vuoi? Lo decidi, e poi ti fai restituire, dalla 
funzioncina, una stringa già formattata col punto come separatore 
decimale.
Se va su un Sql, è già pronta.
Se devi riportarla in valore, basta il Val (che è delocalizzato, ma 
anche l'output della tua funzioncina a questo punto lo è, quindi tutto 
ok).
Una volta scritta, con quella funzione lì sei a posto per tutta la 
vita.
Alberto
-- 
A questo punto hanno trovato un muro,
un muro duro, molto molto duro,
che siamo noi.

 ok).
Per ora faccio sempre una Val(usapunto(
Usapunto è questa:
Public Function UsaPunto(dato As String) As String
' Sostituisce il punto con la virgola che Interbase usa per i campi
' di tipo valuta. La VAL non riconosce la virgola e cdbl da errore
' se il campo non è convertibile
Dim cc As Variant
If Trim(dato) <> "" Then
  dato = Replace(dato, " ", "")
  cc = dato
  UsaPunto = Trim$(str$(cc))
Else
  UsaPunto = ""
End If
If Left(UsaPunto, 1) = "." Then UsaPunto = 0 & UsaPunto
End Function
Grazie e ciao.

 End Function
Oh my God...
Questo è proprio quello che io chiamo codice 'a funzionamento odierno'.
Cioè oggi va, domani non lo so.
Ti do alcuni indizi su cui lavorare:
- Quel cc=dato e poi STR$(cc) significa dare in pasto alle conversioni 
implicite e ai variant tutta l'identificazione dei valori della 
stringa. Non hai il minimo controllo di ciò che avviene.
- Quel UsaPunto = 0 & UsaPunto è un pugno negli occhi. Se vuoi 
concatenare uno zero almeno scrivilo come stringa...
Ho anche l'impressione, dalle tue risposte, che tu non abbia letto quel 
che dicevo delle funzionalità della funzioncina. Che, da un punto di 
vista logico, è esattamente la tua UsaPunto. Ma che ragiona in modo 
diverso.
Ciao


 diverso.
Se ho ben capito devo trasformare la gestione leggendo i separatori ed
agire su quelli. Avendo i separatori, la usapunto mi diventa un semplice
replace sepmigliaia in "" e replace sepdecim in "."
Un'altra cosa che mi piace poco è che al lost focus richiamo il KeyPress
della txt con chr(13) (invio).
Questo perchè sia che premo invio o che esca dal campo deve fare le stesse
cose.
A dire il vero questo sarebbe per tutti i campi non decimal (quella
gestione invio/lostfocus mi serve ad esempio nelle txt di ricerca che se
scrivo "A" invio o "A" tab deve farmi la stessa cosa), e quindi per i
decimal potrei mettere tutto sul validate no?
Anche perchè se ora uno usa l'invio su una txt decimal succede il problema
di cui all'inizio.
Grazie 

 Se metto l'impostazione in ENG
Intendevo dire se metto in ENG ado/Win mi da il valore con formato ENG se
mette in ITA me lo da in ITA.
Credo sia proprio windows che da il formato dei numeri con virgola.

 replace sepmigliaia in "" e replace sepdecim in "."
E' una scelta che devi prendere tu. VB ti può soddisfare in molti modi, 
ma devi avere ben chiaro nella tua testa il funzionamento.
Rifletti su questo:
Se su un pc in italiano, un utente scrive "1.23" (intendendo 1 euro e 
23 centesimi), tu cosa vuoi che il software faccia:
1) Interpreti come "uno e ventitre centesimi"
2) Interpreti come 1230 (intendendo quindi il separatore delle migliaia 
come segnaposto)
3) Dia errore
La scelta 2 è poco diffusa. La scelta 3 è quella che fai tu adesso. La 
scelta 1 è quella che faccio io e che puoi ottenere con un parser della 
stringa.
E se la stessa cosa viene scritta su un pc in inglese, perchè l'utente 
non sa che quel pc è in inglese, cosa vuoi che il sw faccia?
Se hai chiaro questo obiettivo (e tanti altri esempietti del genere), 
anche sviluppare il codice ti sarà facile.


 CStr, che come noto è una funzione localizzata.
Ni, nel senso che se faccio un debug.print del valore ado cambia a seconda
della localizzazione.
Addirittura quando estraggo i dati tramite l'IboConsole (l'interfaccia tipo
access) sotto formato di SQL mi da
INSERT INTO (IMPORTO) VALUES 2,58; se imposto ITA
INSERT INTO (IMPORTO) VALUES 2.58; se imposto ENG
Per questo ho pensato a Win.

 Per questo ho pensato a Win.
Non so cosa sia IboConsole.
Ma se quella cosa lì voleva essere un comando Sql, è un bug.


 Ma se quella cosa lě voleva essere un comando Sql, č un bug.
L'iboconsole č l'interfaccia per fare select o gestire il DB. (un po' come
access).
Volendo ti tira fuori tutti i dati dal DB sotto forma di insert into (e
quindi non si appoggia ad ADO).
Anche lě appunto mi tira fuori il decimal a seconda delle impostazioni, per
questo ho pensato che fosse Win direttamente a convertirlo.
Questo unita alla visualizzazione del valore di Ado mi ha fatto pensare a
Win/Firebird che cambia la visualizzazione del numero.
Trall'altro *mi pare* che se faccio un recordset aggiornabile
Rs.update "IMPORTO","1.200,50"
Lo prende correttamente invece nel command SQL devo usare la notazione ENG.
Comunque sia, il controllo/formattazione di una txt con campo decimal,
solitamente va fatto al _Validate vero?
Grazie e sorry per la niubbiaggine :)

 solitamente va fatto al _Validate vero?
Io lo faccio al validate, oppure prima di utilizzare il contenuto della 
textbox.
Dipende da come funziona il tuo sw.


 Dipende da come funziona il tuo sw.
Ti ringrazio, appena potrò rimettere mano ai programmi fatti, vedo di fare
una bella funzione che non dia problemi.
PS: sai per caso come con una DataGrid caricare un Recordset (e qui ci
sono), sconnettere questo, far lavorare l'utente, riconnettere e fare un
updatebath?
Perchè non appena setto a nothing la connessione del recordset la griglia
si svuota ovviamente. :\
Tnx :)