* * * *

Privacy Policy

Blog italiano

Clicca qui se vuoi andare al blog italiano su Lazarus e il pascal.

Forum ufficiale

Se non siete riusciti a reperire l'informazione che cercavate nei nostri articoli o sul nostro forum vi consiglio di visitare il
Forum ufficiale di Lazarus in lingua inglese.

Lazarus 1.0

Trascinare un file nel programma
DB concetti fondamentali e ZeosLib
Recuperare codice HTML da pagina web
Mandare mail con Lazarus
Stabilire il sistema operativo
Esempio lista in pascal
File INI
Codice di attivazione
Realizzare programmi multilingua
Lavorare con le directory
Utilizzare Unità esterne
TTreeView
TTreeview e Menu
Generare controlli RUN-TIME
LazReport, PDF ed immagini
Intercettare tasti premuti
Ampliare Lazarus
Lazarus e la crittografia
System Tray con Lazarus
UIB: Unified Interbase
Il file: questo sconosciuto
Conferma di chiusura di un applicazione
Liste e puntatori
Overload di funzioni
Funzioni a parametri variabili
Proprietà
Conversione numerica
TImage su Form e Panel
Indy gestiore server FTP lato Client
PopUpMenu sotto Pulsante (TSpeedButton)
Direttiva $macro
Toolbar
Evidenziare voci TreeView
Visualizzare un file Html esterno
StatusBar - aggirare l'errore variabile duplicata
Da DataSource a Excel
Le permutazioni
Brute force
Indy 10 - Invio email con allegati
La gestione degli errori in Lazarus
Pascal Script
Linux + Zeos + Firebird
Dataset virtuale
Overload di operatori
Lavorare con file in formato JSON con Lazarus
Zeos ... dietro le quinte (prima parte)
Disporre le finestre in un blocco unico (come Delphi)
Aspetto retrò (Cmd Line)
Lazarus 1.0
Come interfacciare periferica twain
Ubuntu - aggiornare free pascal e lazarus
fpcup: installazioni parallele di lazarus e fpc
Free Pascal e Lazarus sul Raspberry Pi
Cifratura: breve guida all'uso dell'algoritmo BlowFish con lazarus e free pascal.
Creare un server multithread
guida all'installazione di fpc trunk da subversion in linux gentoo
Indice
DB concetti fondamentali e connessioni standard
Advanced Record Syntax
DB concetti fondamentali e DBGrid
DB concetti fondamentali e TDBEdit, TDBMemo e TDBText
Advanced Record Syntax: un esempio pratico
Superclasse form base per programmi gestionali (e non)
Superclasse form base per programmi gestionali (e non) #2 - log, exception call stack, application toolbox
Superclasse form base per programmi gestionali (e non) #3 - traduzione delle form
Superclasse form base per programmi gestionali (e non) #4 - wait animation
Un dialog per la connessione al database:TfmSimpleDbConnectionDialog
Installare lazarus su mac osx sierra
immagine docker per lavorare con lazarus e free pascal
TDD o Test-Driven Development
Benvenuto! Effettua l'accesso oppure registrati.
Dicembre 22, 2024, 03:20:29 am

Inserisci il nome utente, la password e la durata della sessione.

72 Visitatori, 0 Utenti

Autore Topic: defaultsettings.decimalseparator cambia da solo  (Letto 426 volte)

tito_livio

  • Full Member
  • ***
  • Post: 184
  • Karma: +4/-0
defaultsettings.decimalseparator cambia da solo
« il: Dicembre 16, 2024, 06:37:37 pm »
Ciao a tutti.
Premetto che lavoro con Windows e in tutte le macchine dove girano i miei programmi il separatore è settato nel sistema operativo come virgola.
In alcuni miei programmi, però, tratto dei numeri reali in formato double usando il punto come separatore decimale.

Semplificando, l'utente inserisce dei valori in delle tedit e poi questi dati vengono convertiti da stringa a double ed elaborati.
Una volta che i dati sono stati elaborati, i risultati vengono scritti dal programma in altre tedit.
Nel programma viene settato defaultsettings.decimalseparator:='.' e l'utente inserisce i valori usando il '.' .

Tutto funziona benissimo ma casualmente e come se autonomamente venisse impostata, all'interno del programma, la virgola come separatore decimale.
A questo punto il programma comincia a scrivere i risultati con la virgola e va in errore perché trova i valori dell'utente scritti col punto.

La cosa succede solo su alcuni PC, come se in Windows si verificasse un evento che "comanda" sui settaggi interni del programma.
La cosa mi succedeva anche nei tempi lontani del Delphi, a quei tempi avevo risolto mettendo decimalseparator:='.' in varie parti dell'applicativo, adesso però non funziona.
Avete qualche idea di cosa succede in proposito e come fare per risolvere?
Grazie in anticipo.

bonmario

  • Hero Member
  • *****
  • Post: 1380
  • Karma: +11/-1
Re:defaultsettings.decimalseparator cambia da solo
« Risposta #1 il: Dicembre 16, 2024, 07:53:30 pm »
Ciao,
anni fa mi era successa la stessa cosa, col l'istruzione "TryStrToFloat", poi ho scoperto che la stessa istruzione era stata ridefinita con un parametro in più: "Const FormatSettings: TFormatSettings".
Da allora, chiamo questa col parametro in più, passandogli come ultimo parametro una mia variabile "FormatSettings" contenente i valori che voglio io.

Ciao, Mario

quack

  • Jr. Member
  • **
  • Post: 89
  • Karma: +7/-0
Re:defaultsettings.decimalseparator cambia da solo
« Risposta #2 il: Dicembre 16, 2024, 08:29:22 pm »
Solitamente invece del componente TEdit uso TFloatSpinEdit così posso leggere o assegnare il valore tramite la proprietà Value e bypasso il problema.
Virgola e punto vengono convertiti nel carattere di sistema automaticamente dopo la digitazione.

Uso invece

  DefaultFormatSettings.DecimalSeparator
  DefaultFormatSettings.DefaultFormatSettings

se devo salvare i risultati in dei file di testo, in questo modo mi assicuro
che la formattazione sia sempre la stessa.

Ciao
qk
« Ultima modifica: Dicembre 21, 2024, 01:29:09 pm da quack »
SO: Fedora\W10
Lazarus: Trunk
FPC: Trunk\3.2.2

tito_livio

  • Full Member
  • ***
  • Post: 184
  • Karma: +4/-0
Re:defaultsettings.decimalseparator cambia da solo
« Risposta #3 il: Dicembre 16, 2024, 08:50:10 pm »
Ciao,
anni fa mi era successa la stessa cosa, col l'istruzione "TryStrToFloat", poi ho scoperto che la stessa istruzione era stata ridefinita con un parametro in più: "Const FormatSettings: TFormatSettings".
Da allora, chiamo questa col parametro in più, passandogli come ultimo parametro una mia variabile "FormatSettings" contenente i valori che voglio io.

Si, è vero quello che tu dici, io ho semplificato ma in realtà questi valori double vengono trattati in troppi modi e posti del programma.
Uso anch'io "TryStrToFloat"  ma anche "FloatToStrF", poi queste variabili finiscono in un db o in file di testo o xml, appaiono a video, quindi non vorrei intervenire in così tanti punti del sorgente e in così tanti tipi di conversione.

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1437
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:defaultsettings.decimalseparator cambia da solo
« Risposta #4 il: Dicembre 16, 2024, 09:49:41 pm »
La problematica non ha una soluzione generale.

Il carattere di separazione dei decimali dipende da una impostazione, visibile e modificabile nel pannello di controllo relativo all'"Area Geografica". Questa impostazione ovviamente deriva dalla "lingua" o meglio regione di installazione di Windows.

Questo però non vuole dire che settando quel valore tutto vada a posto. Ci sono controlli grafici (sia in LCL che in VCL) e anche delle "routine" che usano delle impostazioni fisse perchè derivate da ormai secolari (per non dire millenarie) usanze primitive.

Quindi due cose si possono fare:

1) come accenavano i precedenti post, impostare una variabile di tipo TFormatSettings e modificare ciò che più a noi va bene-

2) controllare la documentazione dei singoli oggetti che generano numeri in formato stringa per verificare che non ci siano problematiche.

Ovviamente la varibile di cui sopra DOVRA' ESSERE USATA in tutte le funzioni di conversione. Non ci sono alternative.

Per la scrittura nei vari "posti", anche li ci sono poche soluzioni se non prevedere delle tipologie di conversione a priori.

Ad esempio io sui file INI (che ancora uso per alcuni settaggi dei miei programmi) ho derivato la classe TIniFiles e nascosto (override) i metodi originali ReadFloat e WriteFloat esponendo i miei che filtrano i risultati correggendoli e richiamando le funzioni originali (io lavoro con tutte le lingue più improbabili e non posso avere problemi di questo tipo).

Per tutto il resto uso sempre il TFormatSetting della variabile globale nel programma.

Alcuni controlli li tratto a se stanti come accennato (ad esempio la tastiera virtuale) di Delphi.

Altro consiglio: non esporre mai un numero float in stringa a meno che non sia impossibile altrimenti. E' fondamentale ciò.

Ciao
« Ultima modifica: Dicembre 16, 2024, 09:51:47 pm da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

tito_livio

  • Full Member
  • ***
  • Post: 184
  • Karma: +4/-0
Re:defaultsettings.decimalseparator cambia da solo
« Risposta #5 il: Dicembre 16, 2024, 11:03:00 pm »
Solitamente invece del componente TEdit uso TFloatSpinEdit così posso leggere o assegnare il valore tramite la proprietà Value e bypasso il problema.
Virgola e punto vengono convertiti nel carattere di sistema automaticamente dopo la digitazione.

Ok con TFloatSpinEdit si può prendere il value e fare i calcoli giusti però essendo un componente che rappresenta un numero "reale" sotto forma di stringa per essere visibile, se cambia (da solo) il decimalseparator lui mi farà vedere il numero con un altro decimal separator.
Comunque è interessante il componente , lo devo approfondire.

  DefaultFormatSettings.DecimalSeparator
  DefaultFormatSettings.DefaultFormatSettings

Questo invece mi è poco chiaro

tito_livio

  • Full Member
  • ***
  • Post: 184
  • Karma: +4/-0
Re:defaultsettings.decimalseparator cambia da solo
« Risposta #6 il: Dicembre 17, 2024, 12:11:14 am »
2) controllare la documentazione dei singoli oggetti che generano numeri in formato stringa per verificare che non ci siano problematiche.

Ovviamente la varibile di cui sopra DOVRA' ESSERE USATA in tutte le funzioni di conversione. Non ci sono alternative.

Per la scrittura nei vari "posti", anche li ci sono poche soluzioni se non prevedere delle tipologie di conversione a priori.

Infatti anch'io penso, a questo punto, che non ci siano alternative, però se il problema si manifesta, con lo stesso programma, solo su alcune macchine, allora vuol dire che una problematica c'è ed è propria di quelle macchine.

Altro consiglio: non esporre mai un numero float in stringa a meno che non sia impossibile altrimenti. E' fondamentale ciò.

A volte i float si devono convertire per forza in stringa per tanti motivi. Questi dati in float volte si devono stampare, visualizzare o inviare ad altri sistemi.
Nel mio caso, fortunatamente, si devono rappresentare al massimo tre cifre decimali e ci sono delle precise regole di arrotondamento.

bonmario

  • Hero Member
  • *****
  • Post: 1380
  • Karma: +11/-1
Re:defaultsettings.decimalseparator cambia da solo
« Risposta #7 il: Dicembre 17, 2024, 07:32:56 am »
Ok con TFloatSpinEdit si può prendere il value e fare i calcoli giusti però essendo un componente che rappresenta un numero "reale" sotto forma di stringa per essere visibile, se cambia (da solo) il decimalseparator lui mi farà vedere il numero con un altro decimal separator.

Potresti valutare anche un "TMaskEdit": gli dici tu direttamente come vuoi che venga scritto quel valore

https://wiki.freepascal.org/TMaskEdit

L'ho usato solo una volta, in un programma in cui l'utente doveva inserire una versione nel formato "XX.YY.ZZ_KKK", credo che possa andare bene anche nel tuo caso

Ciao, Mario

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1437
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:defaultsettings.decimalseparator cambia da solo
« Risposta #8 il: Dicembre 17, 2024, 09:29:30 am »
Infatti anch'io penso, a questo punto, che non ci siano alternative, però se il problema si manifesta, con lo stesso programma, solo su alcune macchine, allora vuol dire che una problematica c'è ed è propria di quelle macchine.
La problematica è legata ai settaggi del sistema operativo o a qualche componente che filtra i dati (può essere anche qualche funzione del SO stessa).

Fai attenzione, ciò che non è definito può sempre generare situazioni non previste. Se non imposti l'uso del "TFormatSetting" nelle funzioni di conversione che interessano le stringhe vuol dire che ti và bene quello che ti arriva:
l'esempio stupido è con i separatori di data e ora ... a seconda della "formazione" del PC questi possono essere  (anzi sono) diversi, anche se tutti sono settati con la lingua Italiana ... Win XP, Win 7, Win 8, Win 10, Win 11 ... aggiornamenti ....

Ciascuno di questi aveva impostazioni diverse e se un PC proviene come aggiornamento del SO da quelli vecchi chi può dire come sono settati ora ? Non parliamo dei PC con SO inglese o americano e il language pack Italiano che sembrano tutto e per tutto nativi Italiani, fatto salvo alcune impostazioni ....

Comunque, ciò che faccio io e non lasciare nulla al caso (almeno cerco). Non si trasmette nulla in stringa, se devo trasmettere a "qualcuno" con precisione di tre cifre allora preferisco trasmettere il (float *1000) arrotondato come intero. Esempio 100,002 -> 100002 e non ci sono problemi.

Se devo stampare e devo usare un formato preciso, quindi devo assolutamente impostare i TFormatSetting. Se devo scrivere in un file di "scambio" se non ci sono regole prestabilite è indifferente come scrivi la stringa ... se comunichi con un inglese si aspetta il 'punto', un francese la 'virgola', un vietnamita un carattere 'xxxx' (ho sparato a caso non prendete per buono ciò). Questo a livello di software, però con i francesi dobbiamo comunicare così come con gli altri e quindi dobbiamo necessariamente definire parametri o funzioni di filtro.

In JSON, devi definire la lingua usata (en-EN, it-IT per esempio) o le stringhe numeriche sono per definizione con il separatore decimale come PUNTO (corrisponde allo standard Americano che è il default).

Altri modi non ci sono.
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

nomorelogic

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2932
  • Karma: +20/-4
Re:defaultsettings.decimalseparator cambia da solo
« Risposta #9 il: Dicembre 17, 2024, 10:03:14 am »
Cose simili in passato sono successe anche a me.
Ricordo che ero giunto alla conclusione che gli Os Windows installati con setup inglese avevano questo problema, mentre quelli installati con setup italiano no.
Certo che alla fine cambia poco... FormatSettings come parametro credo sia l'unico modo.
Imagination is more important than knowledge (A.Einstein)

tito_livio

  • Full Member
  • ***
  • Post: 184
  • Karma: +4/-0
Re:defaultsettings.decimalseparator cambia da solo
« Risposta #10 il: Dicembre 17, 2024, 12:49:01 pm »
Fai attenzione, ciò che non è definito può sempre generare situazioni non previste. Se non imposti l'uso del "TFormatSetting" nelle funzioni di conversione che interessano le stringhe vuol dire che ti và bene quello che ti arriva:
l'esempio stupido è con i separatori di data e ora ... a seconda della "formazione" del PC questi possono essere  (anzi sono) diversi, anche se tutti sono settati con la lingua Italiana ... Win XP, Win 7, Win 8, Win 10, Win 11 ... aggiornamenti ....
Un momento, forse mi sbaglierò ma io la vedo in questo modo:
Non è che mi va bene quello che arriva, io uso l'istruzione defaultsettings.decimalseparator:='.' e mi aspetto che dentro il programma il punto sia il separatore decimale, a prescindere da cosa ci sia fuori.
E infatti così funziona perfettamente nel 90% delle installazioni.
Se poi devo specificare lo stesso separatore decimale come parametro in ogni istruzione di conversione allora a cosa serve l'istruzione defaultsettings.decimalseparator:='.'?
Quindi secondo me c'è un bug in Lazarus o nel sistema operativo.
Che poi mi devo tenere il bug e modificare il codice, pazienza lo farò, ma vorrei prima scoprire il motivo di quella che credo sia una incopatibilità con qualcosa installato nel PC.

Con le date e gli orari, con formati diversi fra pc e pc, ci sono incappato anch'io, da un po' però non capita più.
In quel caso però ho cambiato i separatori di data e orario dentro Windows del cliente e si è risolto il problema.
Qui impostare il punto decimale dentro Windows mi sembra un po' troppo invasivo.

Potresti valutare anche un "TMaskEdit": gli dici tu direttamente come vuoi che venga scritto quel valore
Si, "TMaskEdit" lo uso per le date, per i numeri uso altri sistemi, ma qui il problema non è solo quello che inserisce l'utente, per esempio mentre il programma preleva i dati da db e li sta visualizzando ad un certo punto gli cambia (da solo) il separatore decimale di default e li visualizza con la virgola, i dati dell'utente invece rimangono col punto, insomma una bella confusione

Ricordo che ero giunto alla conclusione che gli Os Windows installati con setup inglese avevano questo problema, mentre quelli installati con setup italiano no.
Questo potrebbe essere una cosa da approfondire.
Farò un po' d'indagini e se scopro qualcosa ve lo dirò, per adesso grazie a tutti per le risposte.


DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1437
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:defaultsettings.decimalseparator cambia da solo
« Risposta #11 il: Dicembre 17, 2024, 03:02:20 pm »
Un momento, forse mi sbaglierò ma io la vedo in questo modo:
Non è che mi va bene quello che arriva, io uso l'istruzione defaultsettings.decimalseparator:='.' e mi aspetto che dentro il programma il punto sia il separatore decimale, a prescindere da cosa ci sia fuori.
E infatti così funziona perfettamente nel 90% delle installazioni.
Non conosco quella definizione (ossia "defaultsettings"), e bisogna vedere come è implementata nel codice FPC (o Lazarus). Essendo un parametro di default mi aspetto che possa comunque in qualche modo variare una volta modificata in risposta al cambiamento di ambiente o ad altre cause. Non mi fido a priori delle "cose" automatiche che non conosco.

Io uso una variabile globale DEL PROGRAMMA costruita con il TFormatSetting e modificata a mio piacimento per tutto, è la seconda cosa che "istanzio" dopo il mutex. E in ingresso, ove non sia possibile usare TFormatSetting come nella lettura dei file INI, filtro io il dato in modo da equipararlo sempre e comunque.

Per gli altri casi mi adeguo agli standard (vedi JSON).

E non è il problema del 10% o del 1% e neanche dello 0,001% ... se non mi funziona una installazione, anche solo una installazione in ... Cina .... si capisce che anche se perdo un giorno di tempo (ma anche tre) per adeguare tutte le mie funzioni allo standard ... ne vale ben la pena che un viaggio a mie spese in Cina.

Ripeto, non vedo altre soluzioni. Scorciatoie quante se ne vogliono ma soluzioni no.

Non volermene, non voglio essere aggressivo ma ti assicuro che ho esplorato queste situazioni anni fà (tanti anni fà) quando ho avuto a che fare con l'estero (e bada bene che con la Cina và anche ... prova con l'Arabo o il Giapponese e le sue varianti ....).

Certo, non con Lazarus ma con altri ambienti e la concretezza è identica.

Comunque se trovi la causa di tali situazioni postale che penso interessi a tutta la comnità.

Buona giornata e occhio a dove mettete i .... punti.

Ciaooo
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

quack

  • Jr. Member
  • **
  • Post: 89
  • Karma: +7/-0
Re:defaultsettings.decimalseparator cambia da solo
« Risposta #12 il: Dicembre 21, 2024, 12:19:26 pm »
Infatti DefaultFormatSetting (non defaultsettings) è proprio una variabile di tipo TFormatSettings modificabile a runtime e utilizzata di default dalle funzioni FloatToStrF, TryStrToFloat ect... quando non viene passato il parametro FormatSettings. Riporto il codice di una delle funzioni citate:

Codice: [Seleziona]
Function TryStrToFloat(Const S : String; Out Value: Extended): Boolean;
begin
  Result:=TryStrToFloat(S,Value,DefaultFormatSettings);
end;

Function TryStrToFloat(Const S : String; Out Value: Extended; Const FormatSettings: TFormatSettings): Boolean;
Begin
  Result := TextToFloat(PChar(pointer(S)), Value,FormatSettings);
End;

Lo stesso vale per il componente TIniFile, di default i metodi ReadFloat e WriteFloat usano DefaultFormatSetting.

Quindi in modo diverso stiamo dicendo la stessa cosa.

Per quanto riguarda il componente TFloatSpindEdit, nel pacchetto LazControls c'è un'alternativa chiamata TFloatSpindEditEx che ha più opzioni, tipo la possibilità di usare il formato scientifico, un diverso separatore decimale, nascondere i pulsanti ect...

Una cosa che non mi piace di questa tipologia di componenti è che mostrano anche gli zeri non significativi dopo la virgola.
A titolo informativo, ho risolto con poche righe di codice creado un nuovo componente derivato dalla classe TFloatSpindEditEx con una funzione ValueToStr modificata che elimina gli zeri superflui.

Saluti
SO: Fedora\W10
Lazarus: Trunk
FPC: Trunk\3.2.2

 

Recenti

How To

Utenti
  • Utenti in totale: 802
  • Latest: maXim.FI
Stats
  • Post in totale: 19318
  • Topic in totale: 2303
  • Online Today: 97
  • Online Ever: 900
  • (Gennaio 21, 2020, 08:17:49 pm)
Utenti Online
Users: 0
Guests: 72
Total: 72

Disclaimer:

Questo blog non rappresenta una testata giornalistica poiché viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge n. 62/2001.