Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

2006 г.

Excel ЧаВо

Александр Шабля, Королевство Delphi
Все вопросы Excel.Application Worksbooks и Worksheets Cells, Range, Rows и Columns Внешние источники данных

Chart, ChartObject, Shape, Picture


Пожалуй, самым популярным использованием Excel является применение его для построения диаграмм (Chart). Это заметно по большому количеству примеров, статей и различных FAQ в Интернете по этой теме.

Chart Object

ChartObject Object Model

Shapes Collection Object Model

Chart Class


Как добавить Chart в отдельный лист книги? Как внедрить Chart в лист книги?

Chart может существовать как отдельный лист книги, так и как внедренный в лист объект ChartObject. Принципиальная разница только в том, ChartObject — это уже объект Shape, содержащий в себе Chart.

Чтобы добавить Chart как отдельный лист книги, нужно воспользоваться методом Add коллекции Sheets.

var 
  oChart: _Chart;
  oSheet: _Worksheet;
...
  oChart := XL.Sheets.Add(EmptyParam, oSheet, 1, xlChart, lcid) as _Chart;

Внимание! Не пытайтесь добавить Chart, используя коллекцию Charts — вы получите OLE исключение, т.к. Charts — это коллекция-подмножество Sheets, содержащее ссылки на листы Chart.

Чтоб добавить Chart, как внедренный в лист объект, можно воспользоваться методом Add коллекции листа ChartObjects (здесь существует возможность сразу задать координаты и размеры внедряемого Chart, как будто это объект Shape).

        oChart := (oSheet.ChartObjects(EmptyParam, lcid)
        as ChartObjects).Add(
        oSheet.Range['B9', EmptyParam].Left,
        oSheet.Range['B9', EmptyParam].Top + 8,
        oSheet.Range['I9', EmptyParam].Left - oSheet.Range['B9', EmptyParam].Left,
        oSheet.Range['B30', EmptyParam].Top - oSheet.Range['B9', EmptyParam].Top).Chart
        as _Chart;

Внимание! При преобразовании Chart в ChartObject (или наоборот) лист Chart (или объект ChartObject) исчезнет (будет утерян), поэтому необходимо всегда получать ссылку на новый объект Chart, возвращаемый функцией Locate.

Charts

Location Method

How to: Add Chart Controls to Worksheets


Как указать источник данных объекту Chart?

Для указания источника данных, можно воспользоваться методом SetSourceData объекта Chart или (мне кажется, что это даже удобнее) методом ChartWizard.


var oRng: ExcelRange;
...
    oRng := oSheet.Range['E2:H6', EmptyParam];

    // Указываем источник данных методом SetSourceData
    with oChart do begin
      SetSourceData(oRng, xlColumns); // источник данных и PlotBy

      ChartType := xl3dColumn; // тип диаграммы
    end;


    // Указываем источник методом ChartWizard, в котором можно сразу
    // задать многие параметры диаграммы
    oChart.ChartWizard(
      oRng, // Source: OleVariant;
      xl3dColumn, // Gallery: OleVariant;

      EmptyParam, // Format: OleVariant;
      // данные серий - в колонках
      xlColumns, // PlotBy: OleVariant;
      EmptyParam, // CategoryLabels: OleVariant;
      EmptyParam, // SeriesLabels: OleVariant;

      True, // HasLegend: OleVariant;
      'Sales', // Title: OleVariant;
      EmptyParam, // CategoryTitle: OleVariant;
      'у.е.', // ValueTitle: OleVariant;

      EmptyParam, // ExtraTitle: OleVariant;
      lcid);

SetSourceData Method

ChartWizard Method


Как получить доступ к ряду (series) Chart?

Например, в цикле присвоим всем сериям новое имя.

    for i := 1 to (oChart.SeriesCollection(EmptyParam, lcid) as SeriesCollection).Count do
      (oChart.SeriesCollection(i, lcid) as Series).Name := Format('="Q%d"', [i]);

Обратиться к серии (ряду) можно не только по индексу, но и по имени, например

(oChart.SeriesCollection('Q1', lcid) as Series).Interior.Color := RGB(0, 0, 255);

SeriesCollection Collection Object

Series Object


Как добавить новый ряд (Series) в Chart?

    with (oChart.SeriesCollection(EmptyParam, lcid) as SeriesCollection).NewSeries do

    begin
      Values := oSheet.Range['H2', 'H6'];
      Name := '="Q4"';
    end;

Также можно воспользоваться методом Extend, который "расширяет" область данных диаграммы.

NewSeries Method

Extend Method


Как изменить цвет серии в Chart?

    with (oChart.SeriesCollection(1, lcid) as Series).Interior do begin

      Color := RGB(0, 0, 255);
      Pattern := xlSolid;
    end;

Interior Property

Border Property

Fill Property


Как изменять заголовки Chart и его осей?

Например, так:

      // Заголовок диаграммы
      HasTitle[lcid] := True;
      ChartTitle[lcid].Characters[EmptyParam, EmptyParam].Text := 'Sales';

      // Ось Х - заголовка нет
      (Axes(xlCategory, xlPrimary, lcid) as Axis).HasTitle := False;

      // Оси Y - заголовок "у.е."

      (Axes(xlValue, xlPrimary, lcid) as Axis).HasTitle := True;
      (Axes(xlValue, xlPrimary, lcid) as Axis).AxisTitle.
        Characters[EmptyParam, EmptyParam].Text := 'у.е.';
      (Axes(xlValue, xlPrimary, lcid) as Axis).AxisTitle.Orientation := xlUpward;

Axes Method


Как назначить подписи значениям оси Х (ось категорий) из области ячеек?

Для отображения подписей оси X предназначено свойство XValues объекта Series.

    // значения по категориям
    (oChart.SeriesCollection(1, lcid) as Series).XValues :=
      oSheet.Range['C2:C6', EmptyParam];

XValues Property


Как убрать легенду из Chart?

Легенду можно просто "спрятать", указав, что ее "нет". Также вы можете изменять любые атрибуты легенды (Font, Interior и другие), получив доступ к свойству Legend объекта Chart.

oChart.HasLegend[lcid] := False;

Legend Object

HasLegend


Как добавить в лист объект Shape и записать в него текст?

Объект Shape — это контейнер для многих других объектов, таких как TextBox, PolyLine, ChartObject и др. Также и свойство Comment объекта Range, по возможностям и набору свойств, можно отнести к Shape. Все объекты-наследники Shape содержатся в коллекции Shapes листа.

Внимание! Не забудьте явно указать namespace при присвоении типа объекта Shape, т.к. возможен конфликт с объектом Shape namespace Office:

var

  AShape: ExcelXP.Shape;
// или
  AShape: Excel2000.Shape;

Примеры:

    // Rectangle
    AShape := ASheet.Shapes.AddShape(
      msoShapeRectangle,
      ASheet.Range['A1', EmptyParam].Width / 2,
      ASheet.Range['A1', EmptyParam].Height,
      ASheet.Range['D1', EmptyParam].Left - ASheet.Range['A1', EmptyParam].Width / 2,
      ASheet.Range['D9', EmptyParam].Top - ASheet.Range['A1', EmptyParam].Height
    );
    AShape.TextFrame.Characters(EmptyParam, EmptyParam).Text := 'Rectangle';

    // Oval

    AShape := ASheet.Shapes.AddShape(
      msoShapeOval,
      ASheet.Range['E1', EmptyParam].Left,
      ASheet.Range['F2', EmptyParam].Top,
      ASheet.Range['I1', EmptyParam].Left - ASheet.Range['E1', EmptyParam].Left,
      ASheet.Range['F12', EmptyParam].Top - ASheet.Range['F2', EmptyParam].Top
    );
    AShape.TextFrame.Characters(EmptyParam, EmptyParam).Text := 'Oval';
    AShape.TextFrame.HorizontalAlignment := xlCenter;
    AShape.TextFrame.VerticalAlignment := xlCenter;

    // TextBox

    AShape := ASheet.Shapes.AddShape(
      msoTextOrientationVerticalFarEast,
      ASheet.Range['B1', EmptyParam].Left,
      ASheet.Range['B11', EmptyParam].Top,
      ASheet.Range['E1', EmptyParam].Left - ASheet.Range['B1', EmptyParam].Left,
      ASheet.Range['B18', EmptyParam].Top - ASheet.Range['B10', EmptyParam].Top
    );
    AShape.TextFrame.Characters(EmptyParam, EmptyParam).Text := 'Rhombus';
    AShape.TextFrame.HorizontalAlignment := xlCenter;
    AShape.TextFrame.VerticalAlignment := xlCenter;

    // Hedgehog

    AShape := ASheet.Shapes.AddShape(
      msoShape32pointStar,
      ASheet.Range['D1', EmptyParam].Left,
      ASheet.Range['E19', EmptyParam].Top,
      ASheet.Range['G1', EmptyParam].Left - ASheet.Range['D1', EmptyParam].Left,
      ASheet.Range['E30', EmptyParam].Top - ASheet.Range['E19', EmptyParam].Top
    );
    AShape.TextFrame.Characters(EmptyParam, EmptyParam).Text := 'Hedgehog';
    AShape.TextFrame.HorizontalAlignment := xlCenter;
    AShape.TextFrame.VerticalAlignment := xlCenter;
    AShape.TextFrame.Orientation := msoTextOrientationUpward; // 2

Shapes Collection

Shapes

Shape Object

TextFrame Property

ShapeRange Collection


Как изменить цвет линии и фона Shape?

Delphi:

    (AShape.Fill as FillFormat).ForeColor.SchemeColor := 41;
    (AShape.Line as LineFormat).ForeColor.SchemeColor := 62;

C#:

    AShape.Fill.ForeColor.SchemeColor = 43;
    AShape.Line.ForeColor.SchemeColor = 53;

Fill Property

Line Property


Как сгруппировать несколько объектов Shape на листе?

    // Сгруппируем все объекты Shapes на листе

    AShape := (ASheet.DrawingObjects(EmptyParam, lcid)
      as DrawingObjects).ShapeRange.Group;
    AShape.Name := 'MyGroup1';

    // группировка через вариантный массив
    V := VarArrayCreate([1, 2], varVariant); // !!!

    // сгруппируем 2-й и 4-й Shape
    V[1] := 2;
    V[2] := 4;
    AShape := ASheet.Shapes.Range[V].Group;
    AShape.Name := 'MyGroup2';

    // Если заранее известно, какие Shape будут сгруппированы,

    // то можно и так
    AShape := ASheet.Shapes.Range[VarArrayOf([2, 4])].Group;
    AShape.Name := 'MyGroup3';

    // Теперь, на закуску, через Selection
    // Выберем 2-й, 3-й и 4-й Shape
    ASheet.Shapes.Item(2).Select(True);
    ASheet.Shapes.Item(3).Select(False);
    ASheet.Shapes.Item(4).Select(False);
    // сгруппируем выделенные Shape

    AShape := (XL.Selection[lcid] as DrawingObjects).ShapeRange.Group;
    AShape.Name := 'MyGroup4';

    // Разгруппировать
    AShape.Ungroup;

Заметьте, что после того, как объекты Shape были сгруппированы, их количество на листе (Shapes.Count) уменьшится. После "группировки" можно обратиться к отдельному Shape, включенному в группу, используя коллекцию GroupItems объекта Shape, полученного в результате группировки.

Group Method

Regroup Method

Ungroup Method

GroupItems Property


Как вставить в лист картинку?

var
  AShape: Excel_TLB.Shape;
  APic: Picture; // Excel_TLB

  Img: TImage; // ExtCtrls
  MyFormat: Word; // для копирования картинки в БО
  AData: THandle; // для копирования картинки в БО
  APalette: HPALETTE; // для копирования картинки в БО
...
    // Первый метод

    // Вставляем картинку из файла с "нулевым" размером в
    // позицию ячейки B2. "Нулевой" размер потому, что
    // мы не знаем заранее размера картинки
    with ASheet.Range['B2', EmptyParam] do

      AShape := ASheet.Shapes.AddPicture(ExpandFileName('common.gif'),
        msoFalse, msoTrue, Left, Top, 0, 0);
    // После вставки получаем ссылку на объект Shape, содержащий
    // нашу картинку. "Реанимируем" оригинальный размер картинки
    AShape.ScaleHeight(1, msoTrue, EmptyParam);
    AShape.ScaleWidth(1, msoTrue, EmptyParam);
    AShape.Name := 'Picture1';

    // Второй метод - вставляем в выделенную ячейку

    ASheet.Range['C7', EmptyParam].Select;

    APic := (ASheet.Pictures(EmptyParam, lcid) 
      as Pictures).Insert(ExpandFileName('common.gif'), EmptyParam);
    APic.Name := 'Picture2';

    // Третий метод - вставка через буфер обмена
    // Загрузим картинку с диска в TImage
    Img.Picture.LoadFromFile(ExpandFileName('common.bmp'));
    MyFormat := CF_PICTURE;
    AData := Img.Picture.Bitmap.Handle;
    APalette := Img.Picture.Bitmap.Palette;
    // и помещаем в буфер обмена

    Img.Picture.SaveToClipboardFormat(MyFormat, AData, APalette);
    Clipboard.SetAsHandle(MyFormat, AData);
    // из буфера обмена вставим в ячейку D12
    ASheet.Paste(ASheet.Range['D12', EmptyParam], EmptyParam, lcid);

Все добавленные картинки будут включены в коллекцию Shapes листа.

AddPicture Method

Worksheet.Pictures Method

Paste Method


Как изменить размер картинки и вписать ее в размер определенной области ячеек?

Если пытаться изменять размер картинки, то она, по умолчанию, будет менять размер пропорционально. Такую особенность задает свойство LockAspectRatio объекта Shape. Если установить LockAspectRatio равным msoFalse, то картинка будет менять размеры непропорционально.

// Картинка будет вписана в область D12:J18 с сохранением пропорций
    AShape.Width := ASheet.Range['K12', EmptyParam].Left -
      ASheet.Range['D12', EmptyParam].Left;
    AShape.Height := ASheet.Range['D19', EmptyParam].Top -
      ASheet.Range['D12', EmptyParam].Top;


// Картинка будет вписана во всю область D12:J18 без сохранения пропорций
    AShape.LockAspectRatio := msoFalse;
    AShape.Width := ASheet.Range['K12', EmptyParam].Left -
      ASheet.Range['D12', EmptyParam].Left;
    AShape.Height := ASheet.Range['D19', EmptyParam].Top -
      ASheet.Range['D12', EmptyParam].Top;

LockAspectRatio Property


Как изменить яркость или контрастность картинки?

    (AShape.PictureFormat as PictureFormat).Brightness := 0.25; // 25% яркости
    (AShape.PictureFormat as PictureFormat).Contrast := 0.75; // 75% контрастность

PictureFormat Property


Как добавить картинке гиперссылку?

Смотрите " Как добавить URL? Как сделать гиперссылку для рисунка?"

Hyperlink Property

Creating Charts in Excel 2003 Using Visual Basic for Applications Code

How To Create Excel Chart w/OLE Automation from Visual Basic

Microsoft Excel Charting FAQs

Excel Charts and Graphs Help from Mr Excel

Excel Chart Tips

How to automate Microsoft Excel from Microsoft Visual C# .NET

How To Automate Excel from an HTML Web Page Using JScript

VBA Samples for Working with Excel 2003 Worksheets

XL97: How to Create a GIF File from a Microsoft Excel Chart

COM Tips & Tricks


Все вопросы Excel.Application Worksbooks и Worksheets Cells, Range, Rows и Columns Внешние источники данных
Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

VPS в России, Европе и США

Бесплатная поддержка и администрирование

Оплата российскими и международными картами

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...