Версия для печати
Excel ЧаВо часть IV: Chart, Shape, Picture
http://www.delphikingdom.com/asp/viewitem.asp?catalogID=1275Александр Шабля
дата публикации 07-06-2006 08:49Excel ЧаВо часть IV: Chart, Shape, Picture Работа с диаграммой, Shape и изображениями.
- Как добавить Chart в отдельный лист книги? Как внедрить Chart в лист книги?
- Как указать источник данных объекту Chart?
- Как получить доступ к ряду (Series) Chart?
- Как добавить новый ряд (Series) в Chart?
- Как изменить цвет серии в Chart?
- Как изменять заголовки Chart и его осей?
- Как назначить подписи значениям оси Х (ось категорий) из области ячеек?
- Как убрать легенду из Chart?
- Как добавить в лист объект Shape и записать в него текст?
- Как изменить цвет линии и фона Shape?
- Как сгруппировать несколько объектов Shape на листе?
- Как вставить в лист картинку?
- Как изменить размер картинки и вписать ее в размер определенной области ячеек?
- Как изменить яркость или контрастность картинки?
- Как добавить картинке гиперссылку?
Chart, ChartObject, Shape, Picture
Пожалуй, самым популярным использованием Excel является применение его для построения диаграмм (Chart). Это заметно по большому количеству примеров, статей и различных FAQ в Интернете по этой теме.
Shapes Collection Object Model
Как добавить 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.
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);Как получить доступ к ряду (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) в Chart?
with (oChart.SeriesCollection(EmptyParam, lcid) as SeriesCollection).NewSeries do begin Values := oSheet.Range['H2', 'H6']; Name := '="Q4"'; end;Также можно воспользоваться методом Extend, который "расширяет" область данных диаграммы.
Как изменить цвет серии в Chart?
with (oChart.SeriesCollection(1, lcid) as Series).Interior do begin Color := RGB(0, 0, 255); Pattern := xlSolid; end;Как изменять заголовки 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;Как назначить подписи значениям оси Х (ось категорий) из области ячеек?
Для отображения подписей оси X предназначено свойство XValues объекта Series.
// значения по категориям (oChart.SeriesCollection(1, lcid) as Series).XValues := oSheet.Range['C2:C6', EmptyParam];Как убрать легенду из Chart?
Легенду можно просто "спрятать", указав, что ее "нет". Также вы можете изменять любые атрибуты легенды (Font, Interior и другие), получив доступ к свойству Legend объекта Chart.
oChart.HasLegend[lcid] := False;Как добавить в лист объект 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Как изменить цвет линии и фона 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;Как сгруппировать несколько объектов 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, полученного в результате группировки.
Как вставить в лист картинку?
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 листа.
Как изменить размер картинки и вписать ее в размер определенной области ячеек?
Если пытаться изменять размер картинки, то она, по умолчанию, будет менять размер пропорционально. Такую особенность задает свойство 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;Как изменить яркость или контрастность картинки?
(AShape.PictureFormat as PictureFormat).Brightness := 0.25; // 25% яркости (AShape.PictureFormat as PictureFormat).Contrast := 0.75; // 75% контрастностьКак добавить картинке гиперссылку?
Смотрите " Как добавить URL? Как сделать гиперссылку для рисунка?"
Полезные ссылки
Creating Charts in Excel 2003 Using Visual Basic for Applications Code
How To Create Excel Chart w/OLE Automation from Visual Basic
Excel Charts and Graphs Help from Mr Excel
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