Delphi форматы ячеек excel

Для работы с Excel в Delphi, первым делом нужно в Uses указать модуль ComObj.

procedure TForm1.Button1Click(Sender: TObject);

var

XL: Variant;

begin

XL := CreateOLEObject(‘Excel.Application’); // Создание OLE объекта

XL.WorkBooks.add; // Создание новой рабочей книги

XL.visible := true;

end;

Как обратиться к отдельным ячейкам листа Excel в Delphi

XL.WorkBooks[1].WorkSheets[1].Cells[1,1].Value:=’30’;

//Результатом является присвоение ячейке [1,1] первого листа значения 30. Также к ячейке

//текущего листа можно обратиться следующим образом:

XL.Cells[1, 1]:=’30’;

Как добавить формулу в ячейку листа Excel в Delphi

XL.WorkBooks[1].WorkSheets[1].Cells[3,3].Value := ‘=SUM(B1:B2)’;

Форматирование текста в ячейках Excel, производится с помощью свойств Font и Interior объекта Cell:

// Цвет заливки

XL.WorkBooks[1].WorkSheets[1].Cells[1,1].Interior.Color := clYellow;

// Цвет шрифта

XL.WorkBooks[1].WorkSheets[1].Cells[1,1].Font.Color := clRed;

XL.WorkBooks[1].WorkSheets[1].Cells[1,1].Font.Name := ‘Courier’;

XL.WorkBooks[1].WorkSheets[1].Cells[1,1].Font.Size := 16;

XL.WorkBooks[1].WorkSheets[1].Cells[1,1].Font.Bold := True;

Работа с прямоугольными областями ячеек, с помощью объекта Range:

XL.WorkBooks[1].WorkSheets[1].Range[‘A1:C5’].Value := ‘Blue text’;

XL.WorkBooks[1].WorkSheets[1].Range[‘A1:C5’].Font.Color := clBlue;

//В результате в области A1:C5 все ячейки заполняются текстом ‘Blue text’.

Как выделить группу (область) ячеек Excel в Delphi

XL.Range[‘A1:C10’].Select;

Как установить объединение ячеек, перенос по словам, и горизонтальное или вертикальное выравнивание Excel в Delphi

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

//Выделяем группу (область) ячеек

XL.Range[‘A1:C10’].Select;

// объединение ячеек

XL.Selection.MergeCells:=True;

// перенос по словам

XL.Selection.WrapText:=True;

// горизонтальное выравнивание

XL.Selection.HorizontalAlignment:=3;

//вериткальное выравнивание

XL.Selection.VerticalAlignment:=1;

//Возможны следующие значения:

//1 — выравнивание по умолчанию,

//2 — выравнивание слева,

//3 — выравнивание по центру,

//4 — выравнивание справа.

Как задать границы ячеек Excel в Delphi

XL.Selection.Borders.LineStyle:=1;

// значение может быть установлено от 1 до 10

Как выровнять столбцы Excel по ширине, в зависимости от содержания

XL.selection.Columns.AutoFit;

Как удалить столбец Excel в Delphi

Как задать формат ячеек Excel в Delphi

XL.columns[1].NumberFormat := ‘@’; // текстовый формат

XL.columns[1].NumberFormat := ‘m/d/yyyy’; //  формат дата

XL.columns[1].NumberFormat = ‘0.00%’ // формат процентный

XL.columns[1].NumberFormat = ‘h:mm;@’// формат время


I’m exporting data from a CxDBGrid to an Excel file.
I’m able to create the file and copy data in it, but I’m having real trouble with the column formatting. Since I’m pulling the data from a DB I’d like the spreadsheet to reflect the type: NUMBER, VARCHAR2,DATE and so on.
I visually created a macro, went to look for the VBA code, and replicated it in the Delphi project:

sheet.Columns[K+2].NumberFormat := '0,000'; //Number
sheet.Columns[K+2].NumberFormat := '@'; //Text
sheet.Columns[K+2].NumberFormat := 'm/d/yyyy'; //Date

Number formatting works ok most of the times, but the other two don’t.
When I open the generated file, the text columns show up as type «Custom» and every cell displays «-64». If I go to edit a cell, the correct value is actually there.
Date is another issue: the DB’s format is dd/mm/yyyy and if I feed it to Excel as-is, it gets all messed up. I tried setting the correct format, but then Excel doesn’t recognize it.

Any clues?

I’m also setting column width. That works flawlessly.

useruser

165 / 89 / 38

Регистрация: 29.06.2015

Сообщений: 1,089

1

06.03.2017, 14:32. Показов 6021. Ответов 18

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Delphi 7.
Есть документ Excel. Я читаю этот документ средствами Delphi и передаю все данные в массив.
Когда в ячейках Excel документа данные «отформатированы» как текст все читается и передается корректно.
Но вот когда как число, то в Excel (открыв Microsoft Excel) я вижу 6677160879000690, а в программе 6,67716087900069E+15.

Часть кода

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Ap:Variant; //Переменная excel файла
TABLE_list_1 : array of array [1..50] of string; //Текстовый массив
 
begin
Ap:=CreateOleObject('Excel.Application'); //Создаем объект
Ap.Workbooks.Open(input_file_path,0,True); //Открываем файл для чтения
Ap.DisplayAlerts:=False; //Отключаем любые сообщения excel
 
SetLength(TABLE_list_1, 1000000); //Указываем размер массива 
//Он не динамический т.к. в Delphi 7 есть ошибка при больших динамических массивах
 
//Передаем содержимое ячейки Excel в элемент массива
for i:=1 to 50 do
begin
for j:=1 to 50 do
begin
TABLE_list_1[TABLE_list_1_records_count,j]:=Ap.Cells[i,TABLE_list_1_column_number[j]];
end;
end;
Ap.Application.Quit; //Закрываем excel файл

Как изменить формат данных передаваемых из Excel?



0



Джоуи

1073 / 635 / 240

Регистрация: 05.05.2015

Сообщений: 3,546

Записей в блоге: 2

06.03.2017, 21:43

2

useruser, у ячеек (вернее, у объекта Range) есть свойство NumberFormat, которое определяет, какого формата данные записаны в ячейку. Попробуйте поменять (временно, если не хотите изменять документ) формат нужной ячейки на текстовый и потом считывать.

Если не получится, то скидывайте или весь проект, или Ваш документ Excel (желательно оба).



0



useruser

165 / 89 / 38

Регистрация: 29.06.2015

Сообщений: 1,089

07.03.2017, 10:55

 [ТС]

3

Цитата
Сообщение от Joey
Посмотреть сообщение

useruser, у ячеек (вернее, у объекта Range) есть свойство NumberFormat, которое определяет, какого формата данные записаны в ячейку. Попробуйте поменять (временно, если не хотите изменять документ) формат нужной ячейки на текстовый и потом считывать.

C Delphi работаю давно. перегуглил всё. Не меняет формат.

Текстовый формат в столбце AV, начиная с ячейки AV8 и заканчивая AV20.

Delphi
1
2
3
//Ap.ActiveSheet.Range['AV8:AV20'].NumberFormat:='@';
//Ap.ActiveSheet.Range['AV8:AV20'].NumberFormat:='Текст';
//Ap.ActiveSheet.Range['AV8:AV20'].NumberFormat:='Основной';



0



droider

Эксперт Pascal/Delphi

4884 / 2756 / 849

Регистрация: 04.10.2012

Сообщений: 10,054

07.03.2017, 11:38

4

Цитата
Сообщение от useruser
Посмотреть сообщение

Не меняет формат

Delphi
1
2
 Ap.ActiveSheet.Range['AV8:AV20'].Select; //нужно выделить диапазон
 Ap.Selection.NumberFormat  := '@';



0



165 / 89 / 38

Регистрация: 29.06.2015

Сообщений: 1,089

07.03.2017, 12:03

 [ТС]

5

Цитата
Сообщение от droider
Посмотреть сообщение

Ap.ActiveSheet.Range[‘AV8:AV20’].Select; //нужно выделить диапазон Ap.Selection.NumberFormat := ‘@’;

И так не работает (
Я пробовал уже многие варианты.

Вот документ если что



0



Эксперт Pascal/Delphi

4884 / 2756 / 849

Регистрация: 04.10.2012

Сообщений: 10,054

07.03.2017, 14:08

6

Цитата
Сообщение от useruser
Посмотреть сообщение

так не работает

у меня работает



0



Джоуи

1073 / 635 / 240

Регистрация: 05.05.2015

Сообщений: 3,546

Записей в блоге: 2

07.03.2017, 19:15

7

useruser, какой word версии? У нас работает, а у Вас одного — нет. Подозрительно



0



Эксперт Pascal/Delphi

4884 / 2756 / 849

Регистрация: 04.10.2012

Сообщений: 10,054

08.03.2017, 16:14

8

Цитата
Сообщение от Joey
Посмотреть сообщение

какой word версии?

точнее Excel, но это непринципиально, если делать правильно.

useruser, мануальчик



1



useruser

165 / 89 / 38

Регистрация: 29.06.2015

Сообщений: 1,089

09.03.2017, 06:53

 [ТС]

9

Цитата
Сообщение от Joey
Посмотреть сообщение

useruser, какой word версии? У нас работает, а у Вас одного — нет. Подозрительно

Вот и я тоже так думаю. Excel 2007.

Код

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//Сделать лист Excel активным
function Excel_SetListActive(Excel : variant; NumList : integer) :variant;
begin
Result:=UnAssigned;
if not VarIsEmpty(Excel) then begin
if NumList>0 then begin
if NumList<=Excel.WorkSheets.Count then begin
Result:=Excel.ActiveWorkBook.WorkSheets[NumList];
Result.Select;
end;
end;
end;
end;
 
...
 
var
Ap:Variant; //Переменная excel файла
ARRAY_TABLE_list_1 : array of array [1..120] of string; //Массив, содержащий информацию первого листа
....
 
 
//СОЗДАНИЕ МАССИВА ИЗ ДАННЫХ ЛИСТА 1
SetLength(ARRAY_TABLE_list_1,0); SetLength(ARRAY_TABLE_list_1,1000000); //Отчищаем и указываем размер массива
ARRAY_TABLE_list_1_records_count:=0; //Просто счетчик
 
//Открываем excel файл
Ap:=CreateOleObject('Excel.Application'); //Создаем объект
Ap.Workbooks.Open(ARRAY_input_file_path,0,True); //Открываем файл для чтения
Ap.DisplayAlerts:=False; //Отключаем любые сообщения excel
 
//Активируем лист 1 (в файле всего 2 листа)
Excel_SetListActive(Ap,1);
//Узнаем количество заполненных строк на этом листе
excel_rows:=Ap.ActiveSheet.UsedRange.Rows.Count;
 
 
Ap.ActiveSheet.Range['AV8:AV20'].Select; //Нужно выделить диапазон (по идее чесь столбец AV но пока хотя бы и так)
Ap.Selection.NumberFormat  := '@';
 
for i:=data_begin_row to excel_rows do
begin
//Заполняем массив значениями 
ARRAY_TABLE_list_1_records_count:=ARRAY_TABLE_list_1_records_count+1;
for j:=1 to 120 do
begin
//В каждую запись, состоящую из 120 элементов массива передаем значение ячейки Excel
//ARRAY_TABLE_list_1_column_number - массив содержащий номер столбца
//Все корректно работает, за исключением больших чисел которые передаются в виде 6,67716087900069E+15
ARRAY_TABLE_list_1[ARRAY_TABLE_list_1_records_count,j]:=Ap.Cells[i,ARRAY_TABLE_list_1_column_number[j]];
end;
end;
 
Ap.Application.Quit; //Закрываем excel файл
SetLength(ARRAY_TABLE_list_1,ARRAY_TABLE_list_1_records_count+1); //Указываем размер массива
//КОНЕЦ СОЗДАНИЯ МАССИВА ИЗ ДАННЫХ ЛИСТА 1



0



Джоуи

1073 / 635 / 240

Регистрация: 05.05.2015

Сообщений: 3,546

Записей в блоге: 2

09.03.2017, 23:51

10

useruser, установлю ворд 2007 и отпишусь

Добавлено через 1 минуту
тьфу ты, excel…

Добавлено через 14 секунд
вернее, офис 2007

Добавлено через 18 секунд
Короче, I’ll be back

Добавлено через 2 часа 36 минут
useruser, разбираюсь с Вашим кодом, если надумаете выложить побольше кода, то смелее, никто его не украдет

Добавлено через 27 минут
useruser, короче, задолбался подставлять переменные, выкладывайте больше кода, хотя бы раздел var



0



Эксперт Pascal/Delphi

4884 / 2756 / 849

Регистрация: 04.10.2012

Сообщений: 10,054

10.03.2017, 09:23

11

Цитата
Сообщение от Joey
Посмотреть сообщение

выкладывайте больше кода

там у него явно каша. Сам диапазон тоже странноват.



0



useruser

165 / 89 / 38

Регистрация: 29.06.2015

Сообщений: 1,089

10.03.2017, 12:23

 [ТС]

12

Цитата
Сообщение от Joey
Посмотреть сообщение

никто его не украдет

Да я не боюсь кражи. )) Никому это не надо и не будет надо.. Я не хочу вас грузить кодом.

Написал отдельно тестовую программу. тот же результат.
В Excel я вижу 6677160879000690, а в программе 6,67716087900069E+15.
(Delphi 7. Excel 2007.)

Вот программа, исходники и excel файл. Убедитесь сами.
Тестовая программа.zip

Вот отдельно код, если лень качать.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, StrUtils, ShellApi, ComObj, ActiveX;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
function Excel_SetListActive(Excel : variant; NumList : integer) :variant;
begin
Result:=UnAssigned;
if not VarIsEmpty(Excel) then begin
if NumList>0 then begin
if NumList<=Excel.WorkSheets.Count then begin
Result:=Excel.ActiveWorkBook.WorkSheets[NumList];
Result.Select;
end;
end;
end;
end;
 
 
procedure TForm1.Button1Click(Sender: TObject);
var
i,j,k:integer;
Ap:Variant;
MyRange: OLEVariant;
current_string:string;
begin
Ap:=CreateOleObject('Excel.Application');
Ap.Workbooks.Open(ExtractFilePath(Application.ExeName)+'file.xls',0,True);
Ap.DisplayAlerts:=False;
 
Ap.ActiveSheet.Range['B8:B20'].Select; //нужно выделить диапазон
Ap.Selection.NumberFormat  := '@';
 
Excel_SetListActive(Ap,1);
current_string:=Ap.Cells[8,2]; //B8 
memo1.Lines.Add(current_string); //6,67716087900069E+15. ???
Ap.Application.Quit;
end;
 
end.



0



D1973

11.03.2017, 10:34

 Комментарий модератора 
useruser, Вы в момент регистрации принимали правила форума, так будьте любезны их исполнять… Все вложения выкладываются на форум, а не на какую-то там файлопомойку! Предупреждение!



0



Джоуи

1073 / 635 / 240

Регистрация: 05.05.2015

Сообщений: 3,546

Записей в блоге: 2

11.03.2017, 10:50

14

useruser, проблема не в программе, а в документе Excel. Скопируйте содержимое проблемной ячейки в какую-нибудь свободную ячейку. Затем оттуда скопируйте обратно в исходную. Сохраните документ. Все работает прекрасно:

Как изменить формат данных передаваемых из Excel?

Почему Excel так делает — спросите в разделе Excel



0



1177 / 419 / 106

Регистрация: 31.03.2012

Сообщений: 1,138

11.03.2017, 13:12

15

попробуй это код (использовать formula, вместо values и т.д.)



0



165 / 89 / 38

Регистрация: 29.06.2015

Сообщений: 1,089

12.03.2017, 11:40

 [ТС]

16

Цитата
Сообщение от Joey
Посмотреть сообщение

useruser, проблема не в программе, а в документе Excel. Скопируйте содержимое проблемной ячейки в какую-нибудь свободную ячейку. Затем оттуда скопируйте обратно в исходную.

Сие есть извращение. )
Неужели никак нормально не достать это значение в числовом виде?

Цитата
Сообщение от Joeymax
Посмотреть сообщение

попробуй это код (использовать formula, вместо values и т.д.)

Архив битый (



0



Модератор

8379 / 5580 / 2275

Регистрация: 21.01.2014

Сообщений: 23,954

Записей в блоге: 3

12.03.2017, 11:45

17

Лучший ответ Сообщение было отмечено useruser как решение

Решение

Цитата
Сообщение от useruser
Посмотреть сообщение

Архив битый (

только что проверил — архив абсолютно нормальный.
вот то же самое, только другим архиватором перепаковал



1



Эксперт Pascal/Delphi

4884 / 2756 / 849

Регистрация: 04.10.2012

Сообщений: 10,054

12.03.2017, 11:52

18

Цитата
Сообщение от useruser
Посмотреть сообщение

Неужели никак нормально не достать это значение в числовом виде?

я Вам привел пример как, и Вы не поверите, но у меня есть проект, в котором подобное форматирование работает без проблем в любой версии ms офиса 2007-2016 (2003 давно в глаза не видел) и еще см.

Цитата
Сообщение от Joey
Посмотреть сообщение

проблема не в программе, а в документе Excel



1



165 / 89 / 38

Регистрация: 29.06.2015

Сообщений: 1,089

12.03.2017, 13:30

 [ТС]

19

Цитата
Сообщение от droider
Посмотреть сообщение

я Вам привел пример как, и Вы не поверите, но у меня есть проект, в котором подобное форматирование работает без проблем

И у меня тоже есть проекты, где это работает, а тут…не сработало. ( Вот я и написал.

Цитата
Сообщение от D1973
Посмотреть сообщение

только что проверил — архив абсолютно нормальный.

Спасибо, этот архив нормально распаковался.
Возможно это и будет решением — использовать formula. Ваш проект выводит числа, а это и надо.
Теперь осталось адаптировать этот код под основной проект, по типу если столбец 8 то формула иначе валюэс…



0



2004 г.

Особенности работы с «русским» Excel’ем

Александр Шабля, Королевствo Delphi

Написанное приложение, прекрасно работающие с Excel’ем на собственном компьютере, часто, после переноса приложения на другой компьютер, оказывается неработоспособным! Отчего так происходит?
В этой статья я собираюсь описать разницу в работе русской версии Excel’я из VBA и через COM интерфейс (библиотеку типов, TLB) из Delphi. Почему возникли расхождения? Ответа на эти вопросы у Microsoft я не нашел…

Примечание:

сравнивались только русская и английская (American English) версии Excel с номером версии 9.0 (MS Office 2000) и выше. Другие версии не рассматривались.

Описание типов объектов, применяемых в примерах:

XL: TExcelApplication;
WB: TExcelWorkbook;
ASheet: TExcelWorksheet;
R: Range; 

Используемые в примерах «дополнительные» модули:

OleServer, Excel2000, Office2000 из стандартной поставки Delphi Enterprise версии 6 и выше.

У вас русская версия Excel?

Определить наличие русской версии Excel возможно так:

if XL.LanguageSettings.LanguageID[msoLanguageIDUI] = 1049 
  then ;

Английская версия Excel (English United States) вернет 1033 (или $0409), немецкая (German Standard) — $0407. Значения соответствуют LCID, описанным в MS SDK Help «Language Identifiers». LCID интерфейса пользователя и файла Excel.exe файла может быть неодинаковым (например, после установки MUI). Константа msoLanguageIDUI находится в модуле Office2000.pas и описана так:

const
  msoLanguageIDUI = $00000002;

Примечание:

в Office97 свойство LanguageSettings отсутствует

Далее мы рассмотрим приемы работы с «русским» Excel’ем.

Работа со свойством объекта Range NumberFormat

NumberFormat и NumberFormatLocal четко работают в VBA и полностью соответствуют своему содержанию в названиях, но только не при работе из Delphi.
В Excel2000.pas (D7) они описаны как

ExcelRange = dispinterface
    ['{00020846-0000-0000-C000-000000000046}']
    ...
    property NumberFormat: OleVariant dispid 193;
    property NumberFormatLocal: OleVariant dispid 1097;

Но, при попытке записи форматов из Delphi, выясняется, что NumberFormat и NumberFormatLocal ведут себя идентично, причем NumberFormat соответствует NumberFormatLocal (лучше было бы наоборот :). Т.е. в русской версии все форматы нужно писать «по-русски» (можно прямо в NumberFormat, в VBA — нельзя).

Формат даты

Код на VBA (эталон):

Sub Test1()
  Dim R As Range
  Set R = Range("a1")
  R.Clear ' очистим формулы и форматы
  R.Value2 = Date ' запишем текущую дату
  R.NumberFormat = "d/mm/yy"   ' работает
  R.NumberFormatLocal = "ДД.ММ.ГГ" ' работает
  ' дальше не работает
  R.NumberFormat = "ДД.ММ.ГГ"  ' не работает
  R.NumberFormatLocal = "d/mm/yy" ' ОШИБКА!
  Set R = Nothing
End Sub

Код на Delphi:

R := ASheet.Range['A1', EmptyParam];
R.Value2 := Date;
R.NumberFormat := 'd/mm/yy'; 
R.NumberFormat := 'ДД.ММ.ГГ'; 
R.NumberFormatLocal := 'ДД.ММ.ГГ'; 
R.NumberFormatLocal := 'd/mm/yy'; 

Формат чисел. Разделители. (DecimalSeparator, ThousendSeparator)

Почитайте «диалог» на Круглом столе http://www.delphikingdom.com/asp/answer.asp?IDAnswer=15340 — вроде бы все понятно («а все и делов то в запятой»)! А нет, не все! В «International» (в русском «Язык и стандарты») можно установить любые DecimalSeparator и ThousandsSeparator, отличные от принятых по-умолчанию фирмой Microsoft для русской версии Windows. Я, например, всегда меняю принятые по-умолчанию десятичную точку «,» на «.» и разделитель тысяч с » « (пробел) на «‘» (апостроф, как в калькуляторе). Так формат «# ##0,00» у меня работать не будет…

И это еще не все! Заходим в настройки Excel’я «Сервис/Параметры» переходим на закладку «Международные» и видим опять «Разделитель целой и дробной части», «Разделитель разрядов» и чекбокс «Использовать системные разделители». Т.е. использование системных разделителей не может гарантировать правильного применения при форматировании чисел в Excel’е. Решение: использовать свойство ExcelApplication.International (о нем дальше). Причем, даже при установленном свойстве ExcelApplication.UseSystemSeparators = False и отличных от системных ExcelApplication.DecimalSeparator и ExcelApplication.ThousandsSeparator, ExcelApplication.International отработает корректно.

Далее рассмотрим примеры работы (или не работы), приняв «стандартные» настройки для русских Windows:

Код на VBA (эталон):

Sub Test2()
  Dim R As Range
  Set R = Range("a1")
  R.Clear
  R.Value = 1234567.89
  R.NumberFormat = "#,##0.00" ' работает
  R.NumberFormatLocal = "# ##0,00" '
работает для стандартных настроек
R.NumberFormat = "# ##0,00" ' не работает R.NumberFormatLocal = "#,##0.00" ' не работает Set R = Nothing End Sub

Код на Delphi:

R := ASheet.Range['A1', EmptyParam];
R.Value2 := 1234567.89;
R.NumberFormat := '#,##0.00'; 
R.NumberFormatLocal := '# ##0,00'; 
R.NumberFormat := '# ##0,00'; 

Примечание:

в примерах значения записываются в Value2 для предотвращения форматирования «на лету» самим Excel’ем. Так число 123.45, записанное в Value будет автоматически отформатировано Excel’ем в формат валюты, а присвоение Value = Date будет автоматически переведено в формат даты. Запись в Value2 «воспринимает» значение как Double. Подробнее смотрите в справке VBA для Excel’я.

Решения (с использованием ExcelApplication.International):

Для получения формата даты можно написать функцию:

function XL_GetShortDateFormat(XLApp: ExcelApplication): String;
var d, m, y: Integer;
begin
  if XLApp.International[xlDayLeadingZero, lcid]
    then d := 2 else d := 1;
  if XLApp.International[xlMonthLeadingZero, lcid]
    then m := 2 else m := 1;
  if XLApp.International[xl4DigitYears, lcid]
    then y := 4 else y := 2;
  Result := Format('%1:s%0:s%2:s%0:s%3:s', [
    DateSeparator,
    StringOfChar(VarToStr(XLApp.International
[xlDayCode, lcid])[1], d), StringOfChar(VarToStr(XLApp.International
[xlMonthCode, lcid])[1], m), StringOfChar(VarToStr(XLApp.International
[xlYearCode, lcid])[1], y) ]); end;

Для формата чисел:

function XL_GetNumberFormat
(XLApp: ExcelApplication): String; begin Result := Format('#%s##0%s%s', [ XLApp.International[xlThousandsSeparator, lcid], XLApp.International[xlDecimalSeparator, lcid], StringOfChar('0', Integer
(XLApp.International[xlCurrencyDigits, lcid])) ]); end;

Для формата валюты:

function XL_GetCurrencyFormat(XLApp: ExcelApplication): String;
begin
  Result := Format('%s "%s"', [
    XL_GetNumberFormat(XLApp),
    XLApp.International[xlCurrencyCode, lcid]
  ]);
end;

Тот же принцип можно применить к времени и другим типам. Также смотрите другие индексы для свойства International (их там много) в справке VBA. Например, получить «основной» (general) формат можно так:

GenFmt := XL.International[xlGeneralFormatName, lcid];

Примечание:

установить основной формат еще можно установить, записав в NumberFormat «пустую» строку, т.е. указать, что нет форматирования для чисел (даты):

Range.NumberFormat := »;

Цвет в формате

К сожалению, не лучше обстоит дело и с цветом в форматах. Т.е. цвет в Delphi можно задавать только по-русски:

R.NumberFormat := 'Основной;[красный]-Основной';

Перечень цветов по-русски, которые можно задавать в формате: черный, красный, зеленый, синий, фиолетовый, желтый, белый. Список небогатый.

Формулы на листе

К счастью, работа со свойствами Formula и FormulaLocal в VBA и Delphi идентична и соответствуют своим названиям. Хочется отметить только один нюанс (это, кстати, действительно и для VBA) — при написании «русских» формул нужно учитывать системную переменную ListSeparator. Так, если на другом компьютере пользователь изменит его со стандартного для русской версии Windows символа «;» на «,» (например, как это делаю я :), то присвоение Range.FormulaLocal := ‘=округл(A1*B1; 2)’; вызовет ошибку! Поэтому, с учетом «разделителя элементов списка» нужно писать так:

Range.FormulaLocal := Format('=округл(A1*B1%s 2)', 
[ListSeparator]); или Range.Formula := '=round(A1*B1, 2)';

Здесь приятней и проще пользоваться английскими формулами. Но, иногда, существует необходимость писать формулы из вариантного массива…

Примечание:
системные переменные ListSeparator, DateSeparator описаны в модуле System.

Запись формул из Variant-ного массива

Запись в свойство Formula, FormulaLocal, Value, Value2 из Variant-ного массива идентична в русском Excel’е и при работе из Delphi. Но, если мы хотим вставлять формулы прямо из массива, все они должны быть только русскими!
Вот здесь то и всплывает необходимость определения наличия русской версии Excel’я (впрочем, это уже касалось задания цвета в свойстве NumberFormat).

Код на VBA:

Sub TestVariant()

  Dim MyVar(2, 2) As Variant ' 3 строки, 3 колонки
  Dim R As Long, C As Byte

  ' первая строка
  MyVar(0, 0) = 10.72
  MyVar(0, 1) = 3.05
'  MyVar(0, 2) = "=round(RC[-1]*RC[-2], 2)" ' ошибка #ИМЯ?
  MyVar(0, 2) = "=округл(RC[-1]*RC[-2]; 2)" '
работает для стандартных настроек ' вторая строка MyVar(1, 0) = 4.57 MyVar(1, 1) = 7.23 ' MyVar(1, 2) = "=round(A2*B2, 2)" ' ошибка #ИМЯ? MyVar(1, 2) = "=округл(A2*B2; 2)" '
работает для стандартных настроек ' итог ' MyVar(2, 2) = "=sum(C1:C2)" ' ошибка #ИМЯ? ' MyVar(2, 2) = "=сумм(C1:C2)" ' работает MyVar(2, 2) = "=сумм(R[-2]C:R[-1]C)" ' работает With Range("A1:C3") .Clear ' чистим область ячеек
от формул и форматов .Value = MyVar ' работает ' .Value2 = MyVar ' работает ' .Formula = MyVar ' работает ' .FormulaLocal = MyVar ' работает End With

Код на Delphi (тут мы применим знание написания русских формул, описанный выше, а именно ListSeparator):

var
  MyVar: Variant;
  IsRusXL: Boolean;
begin
...
  MyVar := VarArrayCreate([0, 2, 0, 2], varVariant); 
  
  IsRusXL := XL.LanguageSettings.LanguageID[msoLanguageIDUI]
= $0419; MyVar[0, 0] := 10.72; MyVar[0, 1] := 3.05; if IsRusXL then MyVar[0, 2] := Format('=округл(RC[-1]*RC[-2]%s 2)',
[ListSeparator]) else MyVar[0, 2] := '=round(RC[-1]*RC[-2], 2)'; MyVar[1, 0] := 4.57; MyVar[1, 1] := 7.23; if IsRusXL then MyVar[1, 2] := Format('=округл(A2*B2%s 2)',
[ListSeparator]) else MyVar[1, 2] := '=round(A2*B2, 2)'; if IsRusXL then MyVar[2, 2] := '=сумм(C1:C2)' else MyVar[2, 2] := '=sum(C1:C2)'; with ASheet.Range['A1:C3', EmptyParam] do begin Clear; Value2 := MyVar; end; ...

Примечание:

из примера видно, что при записи из Variant-ного массива в Formula, FormulaLocal, Value, Value2 не имеет значения, какой стиль ссылок используется: A1 и R1C1 работают идентично. Но это не относится к свойствам FormulaR1C1 и FormulaR1C1Local, которые принимают формулы ТОЛЬКО в стиле R1C1.

Создание колонтитулов

Давайте запустим запись макроса создания колонтитула (меню в Excel «Сервис/Макрос/Начать запись…»). Теперь откроем параметры страницы (меню «Файл/Параметры страницы…»). Создадим центральный нижний колонтитул «Лист &[Страница] из &[Страниц]» шрифтом «Arial», «полужирный» и размером 8pt. Слова «Лист» и «из» с начертанием «обычный». После «сокращения» макроса получим:

Sub Макрос1()
'
  ActiveSheet.PageSetup.CenterFooter = _
    "&""Arial""&8Лист &""Arial,полужирный""&P" & _
    "&""Arial,обычный"" из &""Arial,полужирный""&N"
End Sub

Т.е. при выводе на печать мы хотим, чтоб в нижний колонтитул по центру выводился текст, к примеру «Лист 1 из 5».

Примечание:

если вы хотите увидеть работу вашего макроса в действии (чтоб работал PrintPreview), обязательно внесите на лист хоть какие-нибудь данные.

Внимание! Суммарная длина текста в нижнем или верхнем (левый + по_центру + правый) колонтитулах не должна превышать 250 символов (как и в ячейке).

Вроде бы все ясно, осталось только переписать его под Delphi:

ASheet.PageSetup.CenterFooter :=
  '&"Arial"&8Лист &"Arial,полужирный"&P' +
  '&"Arial,обычный" из &"Arial,полужирный"&N';

Проверяем в Excel’е «Предварительный просмотр» — оба, и не работает! А как же должно работать?

Припоминая русификацию еще Excel’я 4-й версии, напишем русские эквиваленты:

ASheet.PageSetup.CenterFooter :=
    '&"Arial"&8Лист &"Arial,полужирный"&С' + 
   '&"Arial,обычный" из &"Arial,полужирный"&К'; 

Сработало! Ну, и теперь добавим распознавание русской версии:

if XL.LanguageSettings.LanguageID[msoLanguageIDUI] = $0419
  then ASheet.PageSetup.CenterFooter := 
    '&"Arial"&8Лист &"Arial,полужирный"&С' +
    '&"Arial,обычный" из &"Arial,полужирный"&К'
  else ASheet.PageSetup.CenterFooter := 
    '&"Arial"&8Лист &"Arial,bold"&P' +
    '&"Arial,normal" из &"Arial,bold"&N';

Вывод: при вставке кодов форматирования из Delphi в русский Excel должны вставляться только русские коды форматирования. А где их взять? Вот список кодов форматирования, полученных методом пробы:

Format code Русский код форматирования Описание
&L Выравнивает последующие символы влево.
&C -«- по центру.
&R -«- вправо.
&E Двойное подчеркивание (double-underline) вкл. или выкл.
&X Верхний индекс (superscript) вкл. или выкл.
&Y Нижний индекс (subscript) вкл. или выкл.
&B Жирный (bold) вкл. или выкл.
&I Наклонный (italic) вкл. или выкл.
&U Подчеркнутый (underline) вкл. или выкл.
&S Зачеркнутый (strikethrough) вкл. или выкл.
&D Текущая дата.
&T Текущее время.
&F Имя документа (книги).
&A Имя листа.
&P Номер страницы.
&P+number &С+число Номер страницы + указанное число.
&P-number &С-число Номер страницы — указанное число.
&& && Одиночный ampersand.
& «fontname» &»ИмяШрифта[,начертание]» Печать указанным шрифтом [и начертанием] (не обязательно). Обязательно указывать в двойных кавычках.
&nn &nn Печать шрифтом указанного размера.
&N Общее количество страниц.

И еще один опыт:

ASheet.PageSetup.CenterFooter :=
      '&"Arial"&8Лист &"Arial,bold"&С&"Arial,normal"
из &"Arial,bold"&К'
;

Работает! Т.е. начертания (Style у класса TFont в Delphi) шрифтов можно уверенно писать по-английски. Или заменить на коды форматирования:

ASheet.PageSetup.CenterFooter := 
'&"Arial"&8Лист &Ж&С&Ж из &Ж&К'
;

Примечание:

для перевода строки в колонтитуле или ячейке используйте симол LF, ASCI код 10 (
#10
):

ASheet.PageSetup.CenterFooter := 'Первая строка'
#10
'Вторая строка'; ASheet.Range['A1', EmptyParam].Value := 'Первая строка'
#10
'Вторая строка';

Выводы

При работе с русским Excel’ем из Delphi необходимо соблюдать следующие правила:

  • при задании форматов использовать только русские форматы чисел и даты;
  • при цветном форматировании чисел указывать цвета только на русском языке;
  • при записи формул из вариантного массива использовать только русские формулы;
  • при создании колонтитулов использовать только русские коды форматирования;
  • для совместимости с английской версий необходимо проверять LCID интрефейса пользователя Excel’я и действовать соответственно.

Мне не удалось найти документацию, касающуюся моментов описанных выше. Весь материал построен чисто на собственном опыте. И еще: не было возможности проверить на полностью английских версиях Windows и Office.

Скачать проект: RusExcel.zip (4,6К)

Все примеры тестировались на Delphi 6, Delphi 7, на русских версиях WindowsXP + OfficeXP, Windows98SE + Office2000 SR?1.

Как програмно произвести форматирование ячеек в excel (например сделать ячейку в текстовом формате, изменить ширину столбца и т.д.)

Когда-то давно занималась этой проблемой, вот кусочек кода,

наверное можно делать и как-то по-другому, это просто как вариант

ответа на твой вопрос.

procedure TFMenu21.RadioButton5Click(Sender: TObject);

const

xlCenter=-4108;

XLWBatWorksheet=-4167;// для создания книги с одной страницей

Var

xl : OleVariant;

x,i,first : integer; // first для переименования страницы с именем «Лист1»

x1,y1 : integer; // для выделения диапазона в Excel

begin

try

// Excel уже запущен?

xl:=GetActiveOleObject(«Excel.Application»);

ShowMessage(«У Вас уже загружен Excel.Завершите его работу, а затем повторите вывод»);

xl.Application.WindowState:=-4137;

//xl.Visible:=True;

xl.Quit;

xl:=Unassigned;

Exit;

except

// Hет, еще нет…

xl:=CreateOleObject(«Excel.Application»);

end;

xl.Workbooks.Add[XLWBatWorksheet];

// xl.Visible:=True;

first:=1;

x1:=0;

Y1:=0;

For i:=3 downto 1 do begin

x:=2;

if first=0 then xl.Workbooks[1].Worksheets.Add else first:=0;

If i=1 then

begin

xl.Range[xl.Cells[x,2],xl.Cells[x+1,14]].MergeCells:=True; // объединение ячеек

xl.Range[xl.Cells[x,2],xl.Cells[x+1,14]].WrapText:=True; // перенос текста

xl.Workbooks[1].Worksheets[1].Name:=»имя страницы»;

// Вывожу какую-то шапку таблицы

x:=x+1;

xl.Range[xl.Cells[x,2],xl.Cells[x+2,2]].MergeCells:=True; // объединение ячеек

xl.Cells[x,2]:=»столбик 1″;

xl.Range[xl.Cells[x,3],xl.Cells[x+1,4]].MergeCells:=True; // объединение ячеек

xl.Cells[x,3]:=»столбик 2″;

// Вывожу данные из Ttable (DM.TsvodD1) в Excel

DM.TSvodD1.Open;

DM.TSvodD1.First;

x1:=x; // запоминаю начальную строку

While not DM.TSvodD1.Eof do

begin

xl.Workbooks[1].WorkSheets[1].Activate;

xl.ActiveWindow.DisplayZeros:=False; // не показывать нули

xl.ActiveWindow.DisplayGridlines:=False; // не показывать сетку

// жирный шрифт xl.Range[xl.Cells[x,2],xl.Cells[x,2]].Font.Bold:=True;

xl.Cells[x,2]:=DM.TSvodD1F.Value;

if DM.TSvodD1T.Value=1 then xl.Cells[x,3]:=»< 0.2″;

if DM.TSvodD1T.Value=2 then xl.Cells[x,3]:=»0.2-0.3″;

// if DM.TSvodD1T.Value=3 then xl.Cells[x,3]:=»> 0.3″;

if DM.TSvodD1T.Value=3 then xl.Cells[x,3]:=» 0.5 «;

xl.Cells[x,4]:=DM.TSvodD1M.Value;

xl.Range[xl.Cells[x,7],xl.Cells[x,7]].NumberFormat:=»@»; // установка текстового формата для ячейки

xl.Cells[x,14]:=DM.TSvodD1Proc.Value;

x:=x+1;

DM.TSvodD1.Next;

end; // while not TSvodD1.Eof

y1:=x-1; // запоминаю конечную строку

// вывожу итоги

xl.Workbooks[1].WorkSheets[1].Rows.Rows[x].RowHeight:=44.25; // высота строки

xl.Range[xl.Cells[x,2],xl.Cells[x,14]].WrapText:=True;

// Форматирую

xl.Workbooks[1].worksheets[1].Range[xl.Cells[1,2],xl.Cells[x,14]].VerticalAlignment:=2;

xl.Workbooks[1].worksheets[1].Range[xl.Cells[x-3,2],xl.Cells[x,14]].HorizontalAlignment:=xlCenter; // выводить в центре ячейки

xl.Workbooks[1].worksheets[1].Range[xl.Cells[x-3,2],xl.Cells[x,14]].Font.Bold:=True;

xl.Workbooks[1].worksheets[1].Range[xl.Cells[x-3,3],xl.Cells[x-3,14]].Borders.Weight := 2;

// устанавливаю ширину колонок

xl.Workbooks[1].worksheets[1].Columns.Columns[1].ColumnWidth:=2.43;

// границы ячейки

xl.Workbooks[1].worksheets[1].Range[xl.Cells[x1,2],xl.Cells[y1,2]].NumberFormat:=»0,0″;

xl.Range[xl.Cells[x1,4],xl.Cells[y1,4]].NumberFormat:=»0,0″;

xl.Visible:=True;

Можно сделать проще, запусти Excel, запусти запись макроса и делай что тебе нужно, то как ворматирование текста, установка ширины ячейки, да всё что угодно, а потом смотри что он там на генерировал в Visual Basice …..

Спасибо Татьяна, попробую.

Понравилась статья? Поделить с друзьями:
  • Delphi компонент как excel
  • Delphi как узнать excel или нет
  • Delphi как удалить листы в excel
  • Delphi как сохранить программно excel
  • Delphi как создать таблицу в excel