Подписка

добавить на Яндекс

Наши проекты

Delphi+Google

Google API

Google API в Delphi - проект с открытым исходным кодом.

Chrono

Chrono

Хронометр - программа для ведения списка задач.

ODFProc

ODFProc

ODFProc - работа с документами OpenOffice в Lazarus и FreePascal.

Поддержка блога

А тут я коплю на лицензию Delphi XE на iPad =).
Сумма пожертвования не фиксирована.

Публикации

Год назад

Случайный пост

Последние

Сообщения форума

Комментарии

Социальные сети

Google

Facebook

Twitter

Опрос

Вы сейчас или в ближайшем обозримом будущем планируете разрабатывать кроссплатформенное приложение с использованием Firemonkey?



Loading ... Loading ...

Блоги и сообщества

Статьи по Delphi DelphiFeeds.ru - Все Delphi-блоги Рунета Сообщество умных людей VR-Online.RU Бесплатный журнал для программистов и всех, кто интересуется IT Статьи и уроки по Delphi Новостной блог о высоких технологиях
Система Orphus
Опубликовал Vlad 11 сентября 2009 в 06:21.
Категории: Моя работа, Основы Delphi.


Сегодня мы рассмотрим один из наиболее интересных, на мой взгляд, моментов работы с Excel в Delphi - построение диаграмм.

Забегая немного вперед, скажу, что есть несколько способов добавления диаграммы в рабочую книгу Excel.  Чтобы все статьи по вопросам автоматизации Excel в блоге были как-то логически связаны, я решил сегодня рассмотреть способ добавления диаграммы через объект ChartObjects, с которым мы встречались, когда разбирали методы объекта WorkSheet.

Итак, поставим перед собой цель - построить простой линейный график на основании данных таблицы (StringGrid) нашего приложения. При этом, чтобы продолжить предыдущую тему, постараемся скопировать таблицу на лист один-к-одному.

1. Копируем данные из таблицы и оформление StringGrid.

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

procedure WriteTable(FirstCol, FirstRow:integer; Grid: TStringGrid);
var col,row:integer;
begin
try
for col := 0 to Grid.ColCount - 1 do
for row := 0 to Grid.RowCount - 1 do
MyExcel.ActiveWorkBook.ActiveSheet.Cells[FirstRow+row, FirstCol+col]:=Grid.Cells[col, row];
except
raise Exception.Create('Запись таблицы завершилась ошибкой')
end;
end;

Теперь начнем копировать оформление. Во-первых, необходимо определить свойство BorderStyle у StringGrid - оно может быть либо bsSingle либо bsNone. В первом случае внешние границы таблицы будут выделяться. Отсюда следует, что и наша таблица в Excel должна иметь окантовку. Делается это просто:

...

if Grid.BorderStyle=bsSingle then
begin

//отрисовываем внешние границы сплошной линией
Range1.Borders[xlEdgeBottom].LineStyle:=xlSolid;
Range1.Borders[xlEdgeTop].LineStyle:=xlSolid;
Range1.Borders[xlEdgeLeft].LineStyle:=xlSolid;
Range1.Borders[xlEdgeRight].LineStyle:=xlSolid;
end;

...

Во-вторых, StringGrid может быть с отрисованными внутренними линиями и без них. За отрисовку внутренних линий отвечают два параметра из свойства Options у StringGrid: goFixedVertLineStringGrid (прорисовка вертикальных линий в ) и goFixedHorzLine (прорисовка горизонтальных линий в StringGrid).

Проверяем наш StringGrid и, в случае необходимости, прорисовываем внутренние границы ячеек:

if goFixedVertLine in Grid.Options then
Range1.Borders[xlInsideVertical].LineStyle:=xlSolid;
if goFixedHorzLine in Grid.Options then
Range1.Borders[xlInsideHorizontal].LineStyle:=xlContinuous;

А теперь самое интересное - определение цветов StringGrid и перенос их в таблицу Excel.  Для того, чтобы перевести цвет в Delphi в цвет, приемлемый для Excel, напишем небольшую подпрограмму:

R := GetRValue(ColorToRGB(Color));
G := GetGValue(ColorToRGB(Color));
B := GetBValue(ColorToRGB(Color));

где Color - это любой из цветов в Delphi, например clRed или clBtnFace. В итоге мы получим три составляющих для RGB, который допускается использовать при заливке ячеек в Excel.

Теперь можно копировать цвета фиксированных ячеек StringGrid:

Cell1:=MyExcel.ActiveWorkBook.ActiveSheet.Cells[FirstRow, FirstCol];
Cell2:=MyExcel.ActiveWorkBook.ActiveSheet.Cells[FirstRow+Grid.RowCount-1, FirstCol+Grid.ColCount-1];
//выделяем занятую таблицей область листа
Range1:=MyExcel.ActiveWorkBook.ActiveSheet.Range[Cell1, Cell2];

if Grid.FixedCols>0 then //есть фиксированные колонки
for I:=1 to Grid.FixedCols do
Range1.Columns[i].Interior.Color:=RGB(r,g,b);
if Grid.FixedRows>0 then //есть фиксированные строки
for I:=1 to Grid.FixedRows do
Range1.Rows[i].Interior.Color:=RGB(r,g,b);

Таким образом мы скопировали наш StringGrid на лист Excel. Конечно, здесь есть свои недостатки, например StringGrid может быть раскрашен как новогодняя ёлка или иметь совершенно иное оформление, чем стандартное и тогда, следуя вышеперечисленным операциям Вы не добьетесь копирования оформления один-к-одному. Но, при небольшом дополнении исходного кода этого можно легко добиться - суть вопроса остается той же, как и набор операций работы Delphi с Excel.

2. Добавление и редактирование диаграммы Excel

Теперь, имея в своем распоряжении данные, можно приступать к построению диаграммы Excel с помощью Delphi.

Для того, чтобы добавить в коллекцию ChartObjects новый объект необходимо выполнить метод Add:

ChartObjects.Add(Left, Top, Width, Height)

где:

Left и Top - начальные координаты нового объекта (в пикселях), относительно левого верхнего угла ячейки A1 на листе или в левом верхнем углу графика.

Width и Height - соответственно ширина и высота новой диаграммы.

В результате выполнения метода в коллекцию ChartObjects добавляется новый объект. Пока никаких данных объект не использует. По сути в добавляется пустой холст диаграмм Excel.

Для того, чтобы построить диаграмму, необходимо:

  • получить ссылку на объект Chart из коллекции ChartObjects;
  • воспользоваться методом ChartWizard

Чтобы получить ссылку на вновь добавленый объект необходимо выполнить следующую операцию:

var Chart: OLEVariant;

ChartCount: integer;

begin

...

ChartCount:=MyExcel.ActiveWorkBook.ActiveSheet.ChartObjects.Count;

Chart:=MyExcel.ActiveWorkBook.ActiveSheet.ChartObjects[ChartCount].Chart;

...

end;

Метод ChartWizard содержит следующие параметры:

ChartWizard(Source, Gallery, Format, PlotBy, CategoryLabels, SeriesLabels, HasLegend, Title, CategoryTitle, ValueTitle, ExtraTitle)

Source : Variant - диапазон, который содержит исходные данные для нового графика.

Gallery: integer (Enumerations xlChartType) - тип диаграммы. Для метода ChartWizard может принимать следующие значения: xlArea, xlBar, xlColumn, xlLine, xlPie, xlRadar, xlXYScatter, xlCombination, xl3DArea, xl3DBar, xl3DColumn, xl3DLine, xl3DPie, xl3DSurface, xlDoughnut, xlDefaultAutoFormat. (Мы воспользуемся пока значением xlLine = 4)

Format : integer (1..10) - может быть числом от 1 до 10, в зависимости от типов галерея. Если этот аргумент опущен, Microsoft Excel выбирает значение по умолчанию в зависимости от типа диаграммы и источника данных. Например Format = 5 для нашего случая заставит Excel прорисовать на диаграмме линии сетки.

PlotBy - определяет каким образом данные располагаются в Source. Может принимать два значения xlColumns =  2 (данные расположены в столбцах)  xlRows = 1 (данные расположены в строках);

CategoryLabel: integer - определяет номер строки или столбца в пределах источника, содержащим метку категории. Допустимые значения от 0 (ноль) до предпоследнего номера столбца или строки источника.

SeriesLabels : integer - определяет номер строки или столбца в пределах источника, содержащим метку набора данных.

HasLegend: boolean - определяет будет ли на диаграмме Excel отражена легенда.

Title: string - заголовок диаграммы Excel.

CategoryTitle : string - подпись оси категорий.

ValueTitle: string - подпись оси значений.

ExtraTitle: string - дополнительная подпись оси при построении трехмерных графиков.

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

Теперь построим наш график. Для этого я написал небольшую процедуру:

procedure AddLineChartFromTable(X, Y, Height, Width, Format: integer; Title, XLabel,YLabel: string; DataGrid: TStringGrid; DataPosition: byte; ChartType:integer);
var Chart: OLEVariant;
DataRange: OLEVariant;
begin
//Вставляем данные из таблицы
WriteTable(1, 1, DataGrid);
//выбираем данные для дигаграммы
DataRange:=MyExcel.ActiveWorkBook.ActiveSheet.UsedRange;
//добавляем новыю диаграмму на активный лист
MyExcel.ActiveWorkBook.ActiveSheet.ChartObjects.Add(x,y,width,height);
//выбираем последнюю добавленную диаграмму
Chart:=MyExcel.ActiveWorkBook.ActiveSheet.ChartObjects[MyExcel.ActiveWorkBook.ActiveSheet.ChartObjects.Count];
Chart.Chart.ChartWizard(Source:=DataRange,
Gallery:=xlLine,
Format:=Format,
PlotBy:=DataPosition,
CategoryLabels:=1,
SeriesLabels:=1,
HasLegend:=true,
Title:=Title,
CategoryTitle:=XLabel,
ValueTitle:=YLabel);
end;

Как видите, все достаточно просто. Берется таблица StringGrid, данные из неё переносятся в Excel на активный лист и, затем, эти данные используются для построения графика. Причём первая ячейка таблицы используется для подписи рядов данных. В результате выполнения процедуры я получил следующую диаграмму Excel:

excel_diagramm
Ну, и наконец, для того, чтобы представить этот же график в объемном виде, воспользуемся одним из многочисленных свойств объекта Chart - ChartType:

Chart.ChartType:=xl3DLine;

в итоге получим следующий вид диаграммы:

excel_diagramm_3D

На сегодня все :) В следующий раз займемся свойствами объекта Chart, научимся строить различные типы диаграмм и изменять область построения диаграммы. А пока можете поэкспериментировать с параметрами у ChartWizard  и посмотреть какие ещё виды диаграмм Excel Вы сможете построить в Delphi.

Вопрос к девушкам-читательницам (если таковые есть). Стоит ли дарить на день рождения даме своего сердца помады мэри кей или другую хорошую косметику?

Мой блог находят по следующим фразам

Понравилась статья? Тогда:
Делись! Загружай! Плюсуй!
   Отправить PDF на   
Читай ещё статьи на WebDelphi.ru

Комментарии (11)

WP_Cloudy
  • Kanti пишет:

    Спасибо за статью. Доходчиво, понятно… но! — данная тема, в принципе, широко рассмотрена в Интернете…
    А вот тема намного интереснее: как «добраться» до диаграммы Excel внедрённой в документ Word и работать с ней? Вот это действительно нетривиально… Надеюсь когда-нибудь увидеть у Вас такую статью! :)
     

  • Vlad пишет:

    Действительно задачка не из стандартных :) Даже никогда о таком не задумывался. Дело в том, что я сейчас очень плотно занимаюсь работой с Excel, т.к. возникла острая необходимость по работе. Думаю, что Word тоже рассмотрю в блоге, но немного позже…А задачку попробую порешать на досуге. Спасибо за идею :)

  • Vlad пишет:

    Ну во, общий ход мыслей рассмотрел, небольшой примерчик привел :)

  • Фотограф Краснодар пишет:

    Статья хорошая. Но некоторые моменты не понял

  • пепелаЦо пишет:

    объясните теперь мне, что может быть проще редактирования таблицы эксель внедренной в ворд, нубы?

  • Vlad пишет:

    ТоварищЪ пепелаЦо, Вы либо беспросветно слеп, либо настолько же беспросветно нуб :) Что собственно не меняет ситуации. Специально для вас привожу алгоритм чтения. В русском языке текст читается сверху вниз и слева на право. Понимаете? Теперь внимательно вчитайтесь в большие буквы вверху страницы — там написано Диаграммы Excel в Delphi. На мысль не наводит? Delphi, язык программирования, программа, работа с OLE. Знакомые слова? Если нет то лес там —>
    Если всё-таки так случилось, что одно из словосочетаний знакомо опять включите головной мозг (голова — это то, что в вашем теле торчит сверху, округлая обычно такая штука) и подумайте очень ли просто не видя нихрена абсолютно перед собой, манипулируя только тем, что дает язык программирования отредактировать диаграмму Excel, встроенную в документ Word. Повторю жирно — не видя ничего — только язык программирования, никаких кликов мышкой и т.д.

  • igor` пишет:

    Выдает ошибку «Член группы не найден» ошибку выдает на строку
    Chart:=MyExcel.ActiveWorkBook.ActiveSheet.ChartObjects[MyExcel.ActiveWorkBook.ActiveSheet.ChartObjects.Count];

  • Vlad пишет:

    Так это ошибка от OLE-сервера. Тут не Delphi, а состав документа надо смотреть.

  • Begeot пишет:

    у меня та же проблема «Член группы не найден» что и у igor`. не подскажите как решить проблему? офис 2007

  • Mark пишет:

    Vlad, столкнулся с проблемой, как поменять толщину построенной линии? (Программа должна строить графики. Строит но линии толстые) Изменить параметры маркера могу.
    Делаю это вот так
    var
    Aseries: Series;

    Begin
    ASeries := Chart1.SeriesCollection(Index, 0) as Series;
    Aseries.MarkerBackgroundColorIndex:=2;
    Aseries.MarkerForegroundColorIndex:=1;
    Aseries.MarkerSize:=4;
    ….
    Думаю, что изменение толщины должно тоже происходить похоже

  • Vlad пишет:

    Mark, я с компонентами для офиса никогда и не работал =) Поэтому сказать какое свойство отвечает за толщину линии диаграммы не могу. Но зато могу посмотреть Help для разработчиков в самом Excel и могу сказать, что судя по хэлпу за внешний вид диаграммы могут отвечать такие свойства: Type, MarkerSize и, наверное, Format, но это свойство только для чтения. ПРо толщину линии диаграммы что-то ничего и нет..

Ваш ответ

Внимание: Все комментарии модерируются, и это может вызвать задержку их публикации. Отправлять комментарий заново не требуется.

Пожалуйста, заключайте исходный код в тэги [code][/code].
Если код большой, то воспользуйтесь Вставкой кода на отдельной странице и оставьте в комментарии ссылку на исходник

   


электроинструмент купить недорого --|--. графики в excel