2014-07-03 16 views
5

Sto provando a convertire un doppio e/o valuta in una stringa per l'utilizzo in una chiamata SQL. Ciò significa che sono sempre interessato a ThousandSeparator che non è nulla e che DecimalSeparator è ".".Perché FloatToStr ignora ThousandSeparator?

Ovviamente, poiché le impostazioni internazionali della mia macchina sono configurate su Danese, Windows restituirà '.' per ThousandSeparator e "," per DecimalSeparator. In quanto tale, ho bisogno di compensare il caso molto probabile che il locale sia sbagliato.

Inoltre, il mio codice deve funzionare sia in D2007 (per motivi legacy) che XE3. Come tale il codice si presentava così:

{$IF CompilerVersion>=19} 
fms := TFormatSettings.Create(LOCALE_SYSTEM_DEFAULT); 
{$ELSE} 
GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, fms); 
{$IFEND} 
fms.ThousandSeparator := '?'; 
fms.DecimalSeparator := '.'; 
Result := FloatToStr(Val, fms); 
Result := StringReplace(Result, '?', '', [rfReplaceAll]); 

Certo, si potrebbe sostenere che, poiché si presume FloatToStr per sempre e solo fare uso di TFormatSettings 'ThousandSeparator e DecimalSeparator creare con qualsiasi locale sarebbe inutile in quanto li stiamo sovrascrivendo Comunque.

Ancora, ho pensato che questo era un sacco di codice per un'operazione molto semplice. Inoltre, non ero un fan di ThousandSeparator "?" e quindi rimosso da StringReplace(). Ma dal momento che ThousandSeparator è un char, non può essere effettivamente vuoto.

Ho eseguito qualche test su FloatToStr e FloatToStrF per essere sicuri, a quel punto ho notato che TFormatSettings.ThousandSeparator stato completamente ignorato:

fms := TFormatSettings.Create; 
fms.ThousandSeparator := 'W'; 
fms.DecimalSeparator := '.'; 
Writeln(FloatToStr(1234567.8901, fms)); 
Writeln(FloatToStrF(1234567.8901, ffFixed, 18, 4, fms)); 

mi aspetterei ogni risultato di essere '1W234W567.8901', ma invece era solo '1234567.8901'. Quindi mi chiedo se questo è un comportamento previsto o una stranezza.

Perché anche se non posso evitare TFormatSettings, se posso almeno ignorare lo ThousandSeparator, suppongo che avrei salvato due righe di codice (non che importi così tanto, suppongo), ma sarebbe sicuro fare così? Posso sempre aspettarmi che FloatToStr ignori lo ThousandSeparator?

+3

Dalla guida: Un valore di # 0 indica che non devono essere presenti mille caratteri separatori, anche se la stringa di formato lo specifica. Quindi se lo assegni con # 0, ottieni sempre il numero senza il separatore delle migliaia. –

+3

"... per l'utilizzo in una chiamata SQL ..." è necessario utilizzare un comando SQL parametrizzato e passare il valore in virgola mobile come parametro. – pf1957

+0

@ pf1957: Questo è tecnicamente quello che succede. Ma abbiamo scritto la nostra funzione FormatSQL. Quindi questo è il codice per * questa * funzione. Naturalmente, se ci sono alcune dichiarazioni preparate per SQL in Delphi, sarei felice di sentir parlare di loro. – Svip

risposta

8

Solo alcuni dei formati in virgola mobile prendono nota dei mille separatori. FloatToStr è una funzione che non funziona perché utilizza il valore ffGeneral dello TFloatFormat enumerated type.

Posso sempre aspettarsi che FloatToStr ignori il ThousandSeparator?

Sì, il separatore delle migliaia viene sempre ignorato da FloatToStr.


Se si desidera visualizzare il separatore delle migliaia, utilizzare ffNumber. Ad esempio il %nnumber format string.

Writeln(Format('%n', [1234567.8901])); 
Problemi correlati