|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Вывод дробного числа из Delphi в Excel
Здравствуйте. Целый день убил на проблему, истоки которой не могу понять. Есть код, который выводит данные из массива в диапазон ячеек Excel. Так же в коде Delphi я задаю форматирование ячеек. В одном из рядов мне необходимо использовать дробное значение вроде x.xx... Точка или запятая разделяет разряды, мне не важно. В общем, проблема типичная казалось бы, но решение мне в голову не пришло... на моей машине работает всё нормально, у меня Win7 и Excel 2007, но когда дело доходит до Win 2003 Server с его 2003 Excel, происходит что-то невероятное: разделитель дроби игнорируется, и число становится целым... Например, значение 1.83 становится при выводе в Excel числом 183 и так далее. Что я только не пробовал, менял региональные стандарты, ставил и точку и запятую в качестве разделителя, и в самом Excel международные настройки пытался использовать, ничего не помогает, с любым форматом ячеек, кроме текстового разделитель исчезает, текст использовать не могу, так как нужно считать потом данные... Под отладчиком видно, что в массив исходный пишу число с запятой (берётся из базы данных), но установка запятой в качестве разделителя не даёт результатов. Кто может помочь разобраться?
Вот несколько кусков кода моего: 1. Так я заполняю вариантный массив Код:
begin Result.EmptyFlag := false; Result.arrCommonData := VarArrayCreate([0, 47 , 0, Params.OraQuery.FieldCount - 4], varVariant); for i := 0 to VarArrayHighBound(Result.arrCommonData, 1) do begin for j := 0 to VarArrayHighBound(Result.arrCommonData, 2) do if ((j = 43) and (Params.OraQuery.FieldCount = 50 )) or ((j = 33) and (Params.OraQuery.FieldCount = 37)) then Result.arrCommonData[i,j] := Params.OraQuery.Fields.Fields[j + 3].AsFloat //[j+3] - èñêëþ÷àåì ïîëÿ 'sp.kod, sp_n1, sv.DAY_IN else Result.arrCommonData[i,j] := Params.OraQuery.Fields.Fields[j + 3].AsInteger; Params.OraQuery.Next; end; Params.OraQuery.Close; Код:
try CoInitialize(nil); Excel := CreateOleObject('Excel.Application'); Excel.DisplayAlerts := false; Excel.Visible := False; //Excel.UseSystemSeparators := False; //Excel.DecimalSeparator := ','; except //ShowMessage ('Ïðîáëåìà ïðè çàïóñêå Microsoft Excel: ïðîâåðüòå íàëè÷èå ïðîãðàììû'); end; if Type_47 then begin Excel.workbooks.add(GetCurrentDir() + '\sv_47.xls'); Sheet := Excel.WorkBooks[1].WorkSheets[1]; Sheet.Range['B8:AV55'].Value2 := arrOut; Sheet.Range['B7:AV55'].NumberFormat :='0;-0;;'; Sheet.Range['AS7:AS55'].NumberFormat :='#,##0;;;'; |
#2
|
||||
|
||||
ПЧПВГ, вгонять данные в Excel как текст через FloatToStr, a получать обратно через StrToFloat
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#3
|
|||
|
|||
Цитата:
а обратно мне вроде как ничего получать не надо... и у меня данные в массиве Variant, FloatToStr тут не катит Пробовал делать так: Код:
for j := 0 to VarArrayHighBound(Result.arrCommonData, 2) do if ((j = 43) and (Params.OraQuery.FieldCount = 50 )) or ((j = 33) and (Params.OraQuery.FieldCount = 37)) then Result.arrCommonData[i,j] := Params.OraQuery.Fields.Fields[j + 3].AsString else Result.arrCommonData[i,j] := Params.OraQuery.Fields.Fields[j + 3].AsInteger; Последний раз редактировалось M.A.D.M.A.N., 09.02.2015 в 18:59. |
#4
|
||||
|
||||
Вот кстати вывод данных вариантного массива на примере из drkb
Код:
var ExcelApp, Workbook, Range, Cell1, Cell2, ArrayData : Variant; TemplateFile : String; BeginCol, BeginRow, i, j : integer; RowCount, ColCount : integer; begin // Координаты левого верхнего угла области, в которую будем выводить данные BeginCol := 1; BeginRow := 5; // Размеры выводимого массива данных RowCount := 100; ColCount := 50; // Создание Excel ExcelApp := CreateOleObject('Excel.Application'); // Отключаем реакцию Excel на события, чтобы ускорить вывод информации ExcelApp.Application.EnableEvents := false; // Создаем Книгу (Workbook) // Если заполняем шаблон, то Workbook := ExcelApp.WorkBooks.Add('C:\MyTemplate.xls'); Workbook := ExcelApp.WorkBooks.Add; // Создаем Вариантный Массив, который заполним выходными данными ArrayData := VarArrayCreate([1, RowCount, 1, ColCount], varVariant); // Заполняем массив for I := 1 to RowCount do for J := 1 to ColCount do ArrayData[I, J] := J * 10 + I; // Левая верхняя ячейка области, в которую будем выводить данные Cell1 := WorkBook.WorkSheets[1].Cells[BeginRow, BeginCol]; // Правая нижняя ячейка области, в которую будем выводить данные Cell2 := WorkBook.WorkSheets[1].Cells[BeginRow + RowCount - 1, BeginCol + ColCount - 1]; // Область, в которую будем выводить данные Range := WorkBook.WorkSheets[1].Range[Cell1, Cell2]; // А вот и сам вывод данных // Намного быстрее поячеечного присвоения Range.Value := ArrayData; // Делаем Excel видимым ExcelApp.Visible := true; Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#5
|
|||
|
|||
Хех =) спасибо, конечно, но как вывести вариантный массив в Excel я знаю, собственно, у меня так же и есть. Вопрос-то не в этом, вопрос в том, что у меня неправильно на одной (а возможно и не на одной) машине выводятся данные... причём сильно неправильно, это даже погрешностью назвать нельзя, когда 1.83 становится 183, а общая сумма из 43.5 превращается в 1000... Дело не в форматах, все форматы я перепробовал, пробовал вообще без форматов, результат один и тот же
|
#6
|
||||
|
||||
Оффтоп: Только что проверил этот код с дробным массивом - в 2003 Excel данные выводит правильно
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#7
|
|||
|
|||
Цитата:
Везёт)... А я со своей стороны в VBA в ячейки под разными форматами записывал дробные числа и с запятой и с точкой, тоже всё нормально, хотя я встречал в интернете инфу о том, что как раз VBA с Excel работает идеально, а вот дельфи подтупливает... Прихожу к выводу, что 2003 Excel здесь ни причём, дело скорее всего в том, как представляет дробные числа Win2003... хотя это конечно бред... т. е., проблема в связке моей программы и винды... но вот как понять, в чём именно... |
#8
|
||||
|
||||
Больше похоже на "косяки" БД-провайдера, - а точно ли массив заполняется нужными числами, хорошо бы под наладкой это проверить. Я пробовал и дроби и текст загонять в Excel: загоняются, дроби правда сразу в денежный формат перетекают, а вот текст нормально отображается, см. наполнение массива
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
childeroland (09.02.2015)
|
#9
|
|||
|
|||
Цитата:
Проверить тяжело, ибо, по непонятным мне причинам, вариантные массивы в Delphi7 под отладчиком просмотреть нельзя (по крайней мере я не знаю как)... точно могу посмотреть, какие числа возвращает SQL, там всё в порядке... Да и потом, на других машинах всё нормально, значит в массиве то, что нужно... Конкретно проблема проявилась на Excel 2003 и Windows2003 Server, на том же офисе (скорее всего на том же, но точно до версии сказать не могу), но на WinXP отображение правильное... Не знаю, попробовать что ли поставить делфю на сервер и там запустить отладчик... Хотя нет, туплю, проще лог сделать на предмет того, что из базы возвращается на той машине... Про БД-провайдер совет дельный, работаю на Oracle, и версии клиента скорее всего разные... Вот какая на XP стоит, я не уверен, покопаюсь в этой теме |
#10
|
|||
|
|||
Цитата:
Вот спасибо!!! Дело действительно в провайдере, или, может быть, в клиенте Oracle, это мне ещё предстоит выяснить более подробно и придумать красивые пути решения, ибо я извращенец и люблю доводить такие вещи до почти совершенства... На данном этапе смог получить нужного результата путём добавления параметра NLS_NUMERIC_CHARACTERS, равного ".," (точка и запятая) в ветку реестра HKLM\Software\Oracle\HOMEx, где HOMEx - номер дома Oracle. (мало ли, вдруг кому пригодится). Снизу ссылка на форум, где я это нашёл. http://www.sql.ru/forum/305991/probl...er-prilozhenii Но наверняка это можно настроить в дельфовом провайдере (использую dbExpress)... А тебе огромное спасибо! |