2014-02-04 3 views
1

Я использую MySQL и Delphi XE4 для создания приложения. В базе данных есть большие числа, и я использовал функцию FORMAT в своих запросах, чтобы применить Thousand Separator!Thousand Separator в DBGrid

SELECT Field1,FORMAT((Field2 * Coef), 0) AS blabla FROM MyTable WHERE ..... 

Все было нормально, но когда я попытался добавить функцию SUM в FastReprot, произошла логическая ошибка!

Функция FORMAT возвращает результат в виде строки, а функция SUM объединяет строки !!!

SUM(frxDBDataset1."blabla",MasterData1) 

Product1| 123,500,000 
Product2| 1,455,999,100 
________________________________ 
SUM = 123,500,000-1,455,999,100 

Каков наилучший способ отображения тысяч разделителей в DBGrid! Я думаю о применении разделителя тысяч в событии OnGetText. Означает ли этот метод задержку отображения данных в DBGrid при записи> 5000?

Есть ли у вас какие-либо предложения?

+2

Используйте свойство [DisplayFormat] (http://docwiki.embarcadero.com/Libraries/XE4/en/Data.DB.TNumericField.DisplayFormat). –

+0

Спасибо. Работал – Jessica

ответ

3

Это действительно плохая идея отформатировать результаты внутри запроса. Запрос должен использоваться для извлечения информации ... презентация должна обрабатываться в другом месте. В этом случае я бы использовал (фактически использую) DisplayFormat, как это было предложено в комментариях.

Вы также можете написать код для автоматического форматирования, если вы не всегда хотят, чтобы добавить поля в TDataSet на время разработки:

DataSet.Open; 
For I := 0 To DataSet.Fields.Count - 1 Do Begin 
    If DataSet.Fields[I] Is TFloatField Then 
     (DataSet.Fields[I] As TNumericField).DisplayFormat := '###,###,##0.00' 
    Else If DataSet.Fields[I] Is TIntegerField Then 
     (DataSet.Fields[I] As TNumericField).DisplayFormat := '###,###,##0'; 
End; 

Это должно быть адаптировано к вашим реальным потребностям .. вы можете читать метаданные из BD (это зависит от BD), например, для определения точности.

Внутри FastReport вы также можете использовать DisplayFormat, или вы также можете использовать функцию формата внутри своей заметки: [Format('%.2n', [<DataSet."Field">])], где .2 указывает точность, которую следует использовать.

EDIT: для решения проблемы знака минус, появляющегося справа, с помощью BiDiMode = bdRightToLeft (см. this), я считаю, что вам действительно нужно использовать событие OnGetText. Я думаю, что вы уже нашли это обойти себя, но я включаю его, тем не менее для полноты:

procedure TForm1.FieldGetText(Sender: TField; var Text: String; DisplayText: Boolean); 
var 
    FmtStr: string; 
    F: Double; 
begin 
    F := Sender.AsFloat; 
    FmtStr := TNumericField(Sender).DisplayFormat; 
    if Sign(F) = -1 then 
    Text := '-' + FormatFloat(FmtStr, Abs(F)) 
    else 
    Text := FormatFloat(FmtStr, F) 
end; 
+0

Спасибо @GabrielF. Как использовать DisplayFormat внутри FastReport? – Jessica

+1

@Jessica Просто установите для вашего свойства 'Memo.DisplayFormat.FormatStr' некоторую строку формата [так же, как и для функции Format] (http://docwiki.embarcadero.com/Libraries/XE4/en/System.SysUtils. Формат # Format_Strings) (например, '% .2n' для включения тысяч разделителей и 2 десятичных знака) и установите' Memo.DisplayFormat.Kind' в 'fkNumeric'. Вы также должны установить DecimalSeparator на свой локальный. Кроме того, вы можете нажать кнопку '...' на 'DisplayFormat', чтобы визуально построить свойство. – GabrielF

+0

@ GabrielF- Новая проблема: я использовал OnGetText для некоторых полей, и когда я использую DisplayFormat для них, это не сработает! – Jessica

1

С небольшими изменениями она работала очень хорошо. [Текст: = FormatFloat (FmtStr, -F) + '-';]

Особая благодарность GabrielF.

procedure TForm1.FieldGetText(Sender: TField; var Text: String; DisplayText: Boolean); 
var 
    FmtStr: string; 
    F: Double; 
begin 
    F := Sender.AsFloat; 
    FmtStr := TNumericField(Sender).DisplayFormat; 
    if F < 0 then 
    Text := FormatFloat(FmtStr, -F) + '-'; 
    else 
    Text := FormatFloat(FmtStr, F) 
end; 
Смежные вопросы