Newsgroup: it.comp.lang.visual-basic
Titolo: Problema separatore numerico , e .

Ciao a tutti,
ho un problemino riguardo all'uso di numeri con la virgola.
In pratica mi sono fatto una function che mi converte da numero con la
virgola a numero col punto (in modo da poter fare i calcoli e le val).
In visualizzazione vorrei perň che siano usate le impostazioni di Win,
quindi in italia 10,55 mentre in ENG 10.55
Ho un problema con la format (dato, "0.00") nel caso in cui le impostazioni
siano:
Sep Decimale= "."
Sep Migliaia= ","
e faccio una format di 1.00 questa mi da 100.00 e non lascia 1.00, anche
1,00 me lo trasforma in 100.00.
Questo perchč vorrei che l'utente possa usare in inserimento . o , a seconda
di cosa voglia, ma mi serve che in visualizzazione sia come le impostazioni
di windows.
Avete qualche consiglio?
Grazie :)

 anche 1,00 me lo trasforma in 100.00.
Alt.
Stai facendo confusione.
Se il Format$ deve formattare un numero, occorre che tu gli passi un numero,
e lui ti restituirà una stringa.
Se passi al format$ una stringa (anche se contenente un numero), lui sarà
costretto a effettuare un CDbl implicito, e questo CDbl è sensisible alle
impostazioni internazionali.
Siccome invece la tua function è immune dalle impostazioni internazionali,
stai facendo due operazioni, una innestata nell'altra, non 'compatibili'.
Cioè, se la variabile 'dato', che hai indicato nel format$, è una stringa
restituita dalla tua function, in realtà stai scrivendo:
format$(CDbl(dato), "0.00")
e siccome dentro a 'dato' hai una stringa che non necessariamente è
convertibile in modo corretto col CDbl, bum.
Ciao
Alberto
--
"Non mi sembra più granda del Delfino..."
"A partir dal fat che la merda liquida
l'as drisa gnan a puntlarla,
còsta chì l'è piò granda, gnuranta."

 Il CStr fa al caso tuo.
Ho dei problemi perchč devo cmq formattare il numero con 2 decimali e se
faccio con impostazioni Italiane:
10.2 il cstr mi lascia 10.2 e la format mi restituisce 102,00 beccando la
virgola come separatore migliaia
Stessa cosa se ho impostazioni in ENG e scrivo 10,2 me lo butta come 102.00
In ogni caso il valore su cui faccio le operazione č controllato
preventivamente che sia numeric tramite IsNumeric, quindi sai cosa posso
usare?
Tnx :)

 usare?
IsNumeric non è molto affidabile.
Secondo me ti conviene fare una funzione che tenta la conversione in CDbl e
se va in errore non è un numero.
Ciao

Credo che la tua situazione in questo momento sia precaria :)
Hai detto che l'utente può, a sua scelta, utilizzare la virgola o il 
punto come separatore decimale.
Ok... ci può anche stare.
Poi hai detto che passi la stringa digitata dall'operatore a una tua 
funzione, che sostituisce la virgola con il punto.
A questo punto credo già che la tua funzione vada modificata: che 
l'operatore utilizzi la virgola o il punto, in ogni caso devi sostituire 
il separatore utilizzato dall'utente con quello di sistema.
Io per ottenere il separatore di sistema faccio una cosa molto semplice 
(sperando che funzioni...):
Dim Separatore As String
Separatore = Mid$(Format$(0, "0.00"), 2, 1)
E così puoi modificar il nocciolo della tua funzione come segue:
Function Converti(ByVal N As String) As Double
    Converti = CDBL(Replace$(Replace$(N, ",", Separatore), ".", Separatore))
End Function
In questo modo è sicuro che, punto o virgola che ci sia, la tua stringa 
viene convertita in Double in modo corretto.
L'unico dubbio che mi viene è: il secondo parametro di Format$ - per 
ottenere il separatore decimale di sistema - risente delle impostazioni 
di sistema? O si può sempre scriverlo in quel modo?
-- 
Quando noi ignoranti eravamo di più,
tutto era più bello...
(Adriano Celentano)

 posso usare?
Andrea, ascolta.
Devi innanzitutto chiarirti le idee.
Una cosa sono le stringhe, e una cosa sono tipi numerici.
Se hai una stringa, il fatto che questa contenga un valore non la trasforma
in un numero.
Se sottoponi una stringa a un Format$, e nel formato che vuoi indichi un
formato numerico, il Format$ ESIGE un numero.
Siccome però tu passi una stringa, Vb, che, ripeto, è troppo buono, cerca di
adeguarsi e effettua la cosa che gli sembra più ovvia, ossia un CDbl.
A questo punto, ti trovi a incasinarti con degli avanti-indietro di
conversioni stringa-numero, di cui purtroppo una metà delocalizzata e una
metà localizzata.
E, ancora peggio, questa conversione avviene in maniera implicita, ossia
senza che tu l'abbia scritta, e quindi non ti accorgi del caos.
Posta un po' di codice e vedo cosa si può fare.
Ciao
Alberto

 se va in errore non è un numero.
Che si fott@no se non scrivono numeri ^_^
In ogni caso questa è una demo, quindi poi nel prg finale sarà ottimizzato
meglio:)
Grazie :D

 funzione, che sostituisce la virgola con il punto.
No, quella funzione la utilizzo solo per fare calcoli interni, in quando
10,5*3 mi darebbe 31.5 mentre 10.5*3 mi darebbe 30 almeno con le
impostazioni italiane.
Quindi tengo sempre la virgola, solo che val(10,50) mi da 10 e quindi ho
bisogno di fare val(usapunto(10,50)) in questo modo posso fare i calcoli con
i decimali
Cmq domani faccio altre prove al limite controllo le impostazioni di win
come mi hai detto tu (o leggendo con le API le impostazioni internazionali
dirette).
Grazie :)

 Grazie :)
Nada!
-- 
Quando noi ignoranti eravamo di piů,
tutto era piů bello...
(Adriano Celentano)

 meglio:)
Anche perchè è difficile ottimizzare "peggio" :)
-- 


 double1=cstr(text1)
Anche questa te l'ha detta il capo?
Alberto

 End Function
mmm... a occhio non funziona :)
Inoltre non č piů semplice cosě?
Function Converti(ByVal N As String) As Double
    Converti = Val(Replace$(N, ",", "."))
End Function
Nota personale: non mi piace trattare i numeri secondo le impostazioni
internazionali: si finisce sempre per fare casini.
Piů semplice costringere l'utente a usare "." come separatore decimale (lo
si usa da 30 anni sulle calcolatrici, ormai dovrebbe essere una consuetudine
acquisita).
Tra l'altro l'uso della virgola costringe l'utente a cercare il tastino
vicino alla M oppure al programmatore di riempire il programma di controlli
sui KeyDown (che poi non sono mai uno uguale all'altro e ci ne si dimentica
sempre qualcuno).
Unico accorgimento: non usare tastiere IBM italiane che con il "." del pad
numerico scrivono ",".
Ciao

Andrea ha scritto:

Devi utilizzare l'api GetLocaleInfo per ricavarti le impostazioni del
separatore decimale. C'č anche un mio vecchio post che tratta la cosa.
Ciao Marco 
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 Ciao
Ciao :)


 riportare poi le cose alla normalità.
Approfondiamo.
La nostra politica è quella di non imporre un formato.
Per diversi motivi:
- Abbiamo clienti con sedi all'estero, quindi un formato fissato
nell'applicazione sarebbe scorretto.
- Proprio perchè gli utenti sono di diversi paesi, possono trovarsi in sedi
diverse dalla propria, ad usare Pc di altri, con altre impostazioni. E non
posso pretendere che il sig. Rossi, quando va nella sede di Londra, si
ricordi che deve digitare il punto anzichè la virgola.
- Con la diffusione di listini informatici e di preventivi via e-Mail, il
copia-incolla è all'ordine del giorno. E se uno copiaincolla un importo,
deve essere correttamente interpretato in qualunque posto ciò accada.
- Quest'ultimo punto fa cadere tutti i discorsi di chi controlla la
digitazione sull'evento key_qualcosa
Quindi, come abbiamo risolto?
Funzioncina nostra, neppure troppo complessa, che prende una stringa e
restituisce una stringa contenente il numero formattato col separatore "."
[punto].
A questo punto, la stringa ottenuta all'interno dell'applicativo può:
- essere usata direttamente in stringhe Sql
- essere convertita in maniera precisa e delocalizzata in un valore
numerico, con un semplice Val
Come opera la funzioncina magica?
Fa una scansione della stringa, cercando le occorrenze di 3 cose:
- Punto
- Virgola
- Separatore decimale locale (che potrebbe anche essere un altro carattere,
chissà...).
Poi esegue una serie di considerazioni, per determinare quale di queste
occorrenze sia un separatore delle migliaia e quale dei decimali.
L'unico principio di fondo è che se c'è un solo separatore, in tutta la
stringa, questo verrà interpretato come separatore decimale.
Quindi, "1.000" o "1,000" significa unovirgolazerozerozero
Mentre "1.000,00" o "1,000.00" significa millevirgolazerozero
Ognuno, ovviamente, adeguerà il ragionamento alla proprio politica.
Saluti
Alberto

 Ah beh parole sacrosante :)
Ci siamo passati tutti :)
Ciao

 Mentre "1.000,00" o "1,000.00" significa millevirgolazerozero
mmm... e se uno sbaglia e scrive "1.00,00"?
Secondo me anche questo è complicarsi la vita :)
Ciao

 Secondo me anche questo è complicarsi la vita :)
Inizialmente. Quando devi scrivere la funzioncina magica, non è semplice.
Soprattutto, per arrivare a definire una serie di regole su come
interpretare i diversi casi, ci vuole tempo e sperimentazione.
Ma una volta che è a punto, la applichi ad occhi chiusi e il problema non si
pone più.
Ciao
Alberto

> Posta un po' di codice e vedo cosa si può fare.
Allora mi sono capito male col capo.
In pratica vuole che l'utente possa inserire solo il PUNTO ed è inteso come
separatore decimale.
Quindi al gotfocus faccio un Usapunto che sarebbe:
Public Function UsaPunto(dato As String) As String
Dim cc As Variant
  dato = Replace(dato, " ", "")
  cc = dato
  UsaPunto = Trim$(str$(cc))
End Function
Al lost focus gli do il formato di win e dato che l'utente può inserire SOLO
il punto posso usare la VAL (che altrimenti se usavo la , tagliava)
Evento LostFocus:
txtEcon(Index) = Format(Val(txtEcon(Index)), "standard")
In pratica le cose si sono moooooolto semplificate e in questo modo forzando
l'utente non ci dovrebbero essere casi che non funzionano, cmq testerò per
bene :)
Grazie a tutti.
PS: avevo abbozzato una function, che non funziona in alcuni casi ma il
resto li fa, se qualcuno la vuole usare come base la posto:
sSep=separatore dec. delle impostazioni Internaz.
sDec= sep. Migliaia
entrambi sono letti con l'api di windows
Questa non funziona sempre nel caso nei primi casi c'è da controllare che il
punto o la virgola siano al posto dei decimali, altrimenti 1.250 (intero) me
lo trasforma in 1,250 con le impostazioni ita in pratica c'è da fare il
controllo qui * e di sotto nel caso in cui sSep=".". In ogni caso è stata
abbozzata, e non testata bene...
Grazie
Public Function CNum(VarStr As String) As Double
Select Case sSep  'Quale è il separatore decimale nelle Imp. Intern.
  Case ","
    If InStr(VarStr, ",") = 0 Then
      If InStr(VarStr, ".") > 0 Then
        CNum = Replace(VarStr, ".", sSep) *
      Else 'non ci sono ne punti ne virgole
        CNum = VarStr
      End If
    Else  'Esiste la , nella VarStringa
      If InStr(VarStr, ".") > 0 Then
        If Mid(VarStr, Len(VarStr) - 2, 1) = sDec Then 'sono stati *forse*
messi i simboli al contrario
          VarStr = Replace(VarStr, sSep, "")
          CNum = Replace(VarStr, sDec, sSep)
          'CNum = Replace(VarStr, "P", sSep)
        Else
          CNum = VarStr 'Considero che sia messa giusta
        End If
      Else 'non ci sono punti ma virgole
        CNum = VarStr
      End If
    End If
  Case "."
    If InStr(VarStr, ".") = 0 Then
      If InStr(VarStr, ",") > 0 Then
        CNum = Replace(VarStr, ",", sSep)
      Else 'non ci sono ne punti ne virgole
        CNum = VarStr
      End If
    Else  'Esiste il . nella VarStringa
      If InStr(VarStr, ",") > 0 Then
        If Mid(VarStr, Len(VarStr) - 2, 1) = sDec Then 'sono stati *forse*
messi i simboli al contrario
          VarStr = Replace(VarStr, sSep, "")
          CNum = Replace(VarStr, sDec, sSep)
        Else
          CNum = VarStr 'Considero che sia messa giusta
        End If
      Else 'non ci sono virgole ma punti
        CNum = VarStr
      End If
    End If
End Select
End Function

 abbozzata, e non testata bene...
Questa non l'ho capita.
Io inibirei la possibilità di digitare il separatore delle migliaia (ma c'è
davvero qualcuno che scrive le cifre con il separatore delle migliaia???)
Ma a 'sto punto non ti conviene lasciare scrivere quello che vogliono e
nell'evento Validate (che c'è apposta) controllare che quanto scritto sia
convertibile in numero?
Ciao

 migliaia???)
Non hai idea di quanti lo facciano (nda: io, ad esempio...).
Con l'Euro la quantità di operatori che usano il separatore delle migliaia è
diminuito, perchè adesso al più si arriva a digitare qualche milione, ma con
le Lire o altre valute è un disastro.
Fai un ordine in Lire Turche. Un pc costa un paio di miliardi, se devi
comprare un capannone ci vogliono le TeraLire...
A parte questo, come dicevo, con la diffusione dei listini informatizzati e
delle offerte via e-Mail, il copiaincolla è all'ordine del giorno.


 convertibile in numero?
Questa function l'avevo buttata giù prima, poi il capo mi ha detto di
considerare solo il PUNTO e non considerare i separatori migliaia, quindi
l'ho lasciata lì senza usarla, nel caso ce ne fosse il bisogno la base ce
l'ho...
L'ho postata per la memoria di Google :P

 L'ho postata per la memoria di Google :P
Speriamo funzioni meglio di UsaPunto() :)
Vista la differenza do complessità ho i miei dubbi :P
P.S.: quando sei stanco di venire caziato dimmelo pure che smetto :)
Ciao

 P.S.: quando sei stanco di venire caziato dimmelo pure che smetto :)
No vai tranqui, per ora reggo :)
-- 
Freccia@Buldozzer63 :D

 Cmq mi pare di averla provata...
Male a quanto pare, se quella postata č quella che usi.
Dai retta a un cretino: riscrivila da zero pensando prima a cosa ti serve e
come deve comportarsi nelle varie casistiche, e lascia perdere la Str() che
ha comportamenti strani e non č piů supportata.
Ciao

 > > sempre qualcuno).
Se poi ci aggiungiamo che VB vede il separatore decimale del tastierino
numerico sempre allo stesso modo la frittatta è fatta!
In altri sw ms questa cosa non succede: una cella di excel gestisce in
maniera corretta il VBKeyDecimal in base alle impostazioni internazionali.
A questo punto devo per forza pistolare nell'evento keydown - keypress.
