link6624 link6625 link6626 link6627 link6628 link6629 link6630 link6631 link6632 link6633 link6634 link6635 link6636 link6637 link6638 link6639 link6640 link6641 link6642 link6643 link6644 link6645 link6646 link6647 link6648 link6649 link6650 link6651 link6652 link6653 link6654 link6655 link6656 link6657 link6658 link6659 link6660 link6661 link6662 link6663 link6664 link6665 link6666 link6667 link6668 link6669 link6670 link6671 link6672 link6673 link6674 link6675 link6676 link6677 link6678 link6679 link6680 link6681 link6682 link6683 link6684 link6685 link6686 link6687 link6688 link6689 link6690 link6691 link6692 link6693 link6694 link6695 link6696 link6697 link6698 link6699 link6700 link6701 link6702 link6703 link6704 link6705 link6706 link6707 link6708 link6709 link6710 link6711 link6712 link6713 link6714 link6715 link6716 link6717 link6718 link6719 link6720 link6721 link6722 link6723 link6724 link6725 link6726 link6727 link6728 link6729 link6730 link6731 link6732 link6733 link6734 link6735 link6736 link6737 link6738 link6739 link6740 link6741 link6742 link6743 link6744 link6745 link6746 link6747 link6748 link6749 link6750 link6751 link6752 link6753 link6754 link6755 link6756 link6757 link6758 link6759 link6760 link6761 link6762 link6763 link6764 link6765 link6766 link6767
Женский интернет журнал "Кокетка"

Работа с Exсel из приложения, написанного на C++Builder (часть 2)

Итак, начинаем второй урок по работе с Excel из C++Builder.

Первый урок был достаточно коротким, после него возникло множество вопросов
и в этом уроке мы попытаемся ответить на многие из них.
Кроме того, на многие вопросы ответили Вы сами,
прислав примеры своих работ с Excel.

Все ответы и примеры построены на программном коде первого урока
(http://cbuilder.ru/WinLesson/bles1.htm)

-----------------------------------------

Список вопросов, ответы на которые приводятся в данном уроке.

1 Как получить из ячейки не только ее значение, но и формулу данной ячейки ?
2 Как нарисовать диаграмму ?
3 Как нарисовать границы у выбранного диапазона ячеек (бордюр) ?
4 Как получить значение какой-либо ячейки ?
5 Как задать формат для ячейки ?
6 Как установить масштаб для документа ?
7 Как выровнять данные в ячейке ?
8 Как установить высоту строки ?
9 Как установить ширину столбца ?
10 Как установить цвет ячеек ?
11 Как задать количество листов в книге ?
12 Как дать название листу ?
13 Как сохранить получившийся документ ?
14 Как установить настройки при печати ?
14 Как распечатать получившийся документ ?
15 Как закрыть документ Excel ?

и множество других...
------------------------------------------

Для того, чтобы лучше понять работу с Excel, рассмотрим иерархию объектов в Excel.


Примерная иерархия вложенных объектов OLE-сервера.

Итак, на вершине — объект Application (у нас в примере Variant App),
Workbooks — книга (не используем), работаем сразу с листом — WorkSheets  — у нас Variant Sh,
группы ячеек Cells — для них используем объект Variant Rang;

"Свойствами объектов Excel могут являться так называемые коллекции объектов.
Например, коллекция Workbooks является свойством объекта Excel.Application, при этом она содержит
набор вложенных объектов — рабочих книг Excel, а те, в свою очередь, обладают свойством Worksheets,
представляющим собой коллекцию рабочих листов, каждый из которых обладает свойством Cells,
являющимся коллекцией ячеек.
Аналогично, коллекция Charts также является свойством рабочей книги"
из статьи "Создание контроллеров автоматизации с помощью C++Builder" Наталия Елманова

Итак, запускаем предыдущий проект и добавляем в него следующий код.

Вопрос. У меня в ячейке есть число, но оно рассчитывается по формуле в этой ячейке.
Как получить из ячейки не только ее значение, но и формулу данной ячейки ?

// получить формулу из ячейки
Variant __fastcall TForm1::fromExcelFormula(int Row, int Column)
{
try{
Variant result,cur;
cur = Sh.OlePropertyGet("Cells",Row,Column);
result = cur.OlePropertyGet("Formula");
return result;
}catch(...) {;}
}
// получаем значение и формулу из ячейки 34,5
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Label3->Caption = fromExcelCell(34,5); // получить значение из ячейки
Label4->Caption = fromExcelFormula(34,5); // получить формулу из ячейки
}
//-----------------------------------------------

Вопрос. Как нарисовать диаграмму ?

void __fastcall TForm1::Button5Click(TObject *Sender)
{
Variant Chart;
Chart=App.OlePropertyGet("Charts").OleFunction("Add"); // добавим объект диаграмму
Chart.OlePropertySet("ChartType",65); // установим один из типов диаграммы

// выберем ячейки для построения диаграммы, это строки 3 — 31 и столбец 3
Chart.OleProcedure("SetSourceData",Sh.OlePropertyGet("Range",Sh.OlePropertyGet("Cells",3,3),
Sh.OlePropertyGet("Cells",31,3)),2);
Chart.OlePropertyGet("SeriesCollection",1).OlePropertySet("XValues",Sh.OlePropertyGet("Range",
Sh.OlePropertyGet("Cells",2,3),Sh.OlePropertyGet("Cells",31,3)));
Chart.OleProcedure("Location",2,Sh.OlePropertyGet("Name"));
// установим место вывода диаграммы
// для этого получим UsedRange — испольуемый диапазон ячеек, и отступим вниз на 25 пикселей
Sh.OlePropertyGet("ChartObjects",1).
OlePropertySet("Top",Sh.OlePropertyGet("UsedRange").OlePropertyGet("Height")+25);
// и слева от края 10 пикселей
Sh.OlePropertyGet("ChartObjects",1).OlePropertySet("left",10);
// встаем на начало
Sh.OlePropertyGet("Cells",1,1).OleProcedure("Select");
}
//-----------------------------------------------------

Вопрос. Как нарисовать границы у выбранного диапазона ячеек (бордюр) ?

// Устанавливаем диапазон ячеек для рисования бордюра A2:E31
int m = 30;
AnsiString s = "A2:E"+IntToStr(m+1);
Variant range = App.OlePropertyGet("Range", s.c_str());
for (int i=1; i<=4; i++)
range.OlePropertyGet("Borders").OlePropertyGet("Item", i).OlePropertySet("LineStyle", 1);

//------------------------------------------------------


Вопрос. Как получить значение какой-либо ячейки ?

Label3->Caption = fromExcelCell(34,5); // получить значение ячейки 34,5

// получить значение ячейки
Variant __fastcall TForm1::fromExcelCell(int Row, int Column)
{
try{
Variant result,cur;
cur = Sh.OlePropertyGet("Cells",Row,Column);
result = cur.OlePropertyGet("Value");
return result;
}catch(...) {;}
}
//-------------------


Вопрос. Как задать формат для ячейки ?

// устанавливаем формат числа для ячейки 1,1
Sh.OlePropertyGet("Cells", 1,1).OlePropertySet("NumberFormat", "0.00");
// устанавливаем формат строка для ячейки 1,2
Sh.OlePropertyGet("Cells", 1,2).OlePropertySet("NumberFormat", "@");
// устанавливаем формат даты для ячейки 1,3
Sh.OlePropertyGet("Cells", 1,3).OlePropertySet("NumberFormat", "ДД.ММ.ГГГГ");

//-------------------

Вопрос. Как установить масштаб для документа ?

// Устанавливаем масштаб = 75%
App.OlePropertyGet("ActiveWindow").OlePropertySet("Zoom", 75);

//-------------------

Вопрос. Как выровнять данные в ячейке ?

// Выравнивам данные в ячейке
Sh.OlePropertyGet("Cells", 1,1).OlePropertySet("HorizontalAlignment", 4);
// где 4 — по левому краю, 2 — по правому, 3 — по центру)

// или по-другому это можно записать так
// Rang = Sh.OlePropertyGet("Cells",1,1);
// Rang.OlePropertySet("HorizontalAlignment",4);
// и для вертикального выравнивания — VerticalAlignment

//-------------------

Вопрос. Как установить высоту строки ?

// устанавливаем высоту 60
Rang.OlePropertySet("RowHeight", 60);

//-------------------

Вопрос. Как установить ширину столбца ?

// устанавливаем ширину столбца 12
Sh.OlePropertyGet("Columns").OlePropertyGet("Item",1).OlePropertySet("ColumnWidth", 12);

//-------------------

Вопрос. Как установить цвет ячеек ?

Rang = Sh.OlePropertyGet("Range", "A1:E1");
Rang.OlePropertyGet("Interior").OlePropertySet("ColorIndex",4);

//-------------------

Вопрос. Как задать количество листов в книге ?

// Определяем количество листов в книге — 1
App.OlePropertySet("SheetsInNewWorkbook", 1);

//-------------------

Вопрос. Как дать название листу ?

// Даем название нашему листу "Наш лист итогов"
Sh = App.OlePropertyGet("Worksheets").OlePropertyGet("Item", 1);
Sh.OlePropertySet("Name", "Наш лист итогов");

//-------------------

Вопрос. Как сохранить получившийся документ ?

// Не спрашивать о замене файла, если он уже есть
App.OlePropertySet("DisplayAlerts", false);

// Сохраняем файл как "Firm.xls"
App.OlePropertyGet("WorkSheets",1).OleProcedure("SaveAs","Firm.xls");

//--------------------

Вопрос. Как установить настройки при печати ?

// Левое и правое поля отступа для печати
Sh.OlePropertyGet("PageSetup").OlePropertySet("LeftMargin", 80);
Sh.OlePropertyGet("PageSetup").OlePropertySet("RightMargin",20);

//--------------------

Вопрос. Как распечатать получившийся документ ?

App.OlePropertyGet("WorkBooks",1).OleProcedure("PrintOut");

//--------------------

Вопрос. Как закрыть документ Excel ?

try{
App.OlePropertyGet("WorkBooks",1).OleProcedure("Close");
}catch(...){
ShowMessage("Не забудьте сами закрыть Excel.");
}
// закрыть сам Excel
App.OleProcedure("Quit");

//-----------------------------
Посмотреть как все это работает и другие возможности
для C++Builder 6 полный проект можно скачать и посмотреть в работе здесь (15 Кб).

Многие спрашивают — как ускорить вывод в Excel больших массивов данных,
слишком медленно все работает.
Наиболее идеальный вариант — воспользоваться компонентами XLSReadWrite2 или аналогичными.
Также, в проекте есть пример, как можно немного ускорить такой вывод,
для этого при выводе данных можно не выводить данные последовательно в каждую ячейку
в цикле, а лучше сформировать вариантный массив, и выполнить присвоение области
(Range)
этого массива, только после этого делая Excel видимым.
Также более быстрая работа происходит при использовании библиотеки типов.

Все замечания и предложения и добавления: support@cbuilder.ru
Если Вы используете Excel или Word в работе с C++Builder,
присылайте примеры, проекты и интересные решения нам,
а также если у вас остались вопросы — спрашивайте.

В следующем уроке:

Для облегчения вывода данных в Excel можно использовать шаблоны.
Мы рассмотрим работу с шаблонами (.xlt) и использование макросов.