ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 64543|回复: 106

[分享] VBA图表基础教程

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2018-6-4 23:07 | 显示全部楼层 |阅读模式
本帖最后由 ivccav 于 2018-6-4 23:10 编辑

Excel图表能直观地呈现数字的规律,是分析数据的利器。

本教程是使用VBA程序来绘制Excel嵌入式图表。
如果你还不知道什么是图表,没关系,下图就是所谓的图表(嵌入式):

1-什么是Excel图表.png

它的数据来源是如下的表格:

2-图表来源数据区域.png

要想使用VBA绘制图表,那首先得了解它的结构。图表对象由图表区、图表标题、绘图区、
垂直(值)轴、水平(分类)轴、图例、网格线、系列等区域,每个区域都可以单独设置
外观、颜色、填充、字体等等属性,只有熟悉这些区域才能用VBA设计出符合自己需求的
图表。下图是对图表对象各区域的分解图,其中次坐标轴只在性质不同的系列之间比较时
才可能用到:

3-Excel图表解剖图.png

绘图区在上图中未指出,请看下图:


我们直接以实例来讲解。



补充内容 (2019-1-22 16:39):
在窗体上绘制图表,则相对容易,因为数据源是数组,已出教程,可参考:

http://club.excelhome.net/thread-1458245-1-1.html
4-Excel图表解剖图-绘图区.png

评分

21

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-4 23:14 | 显示全部楼层


一、创建图表容器

    Dim ch As ChartObject, ws As Worksheet
    Dim lastrow&
    Application.ScreenUpdating = False
    Set ws = Worksheets("Risk")
    If ws.ChartObjects.Count > 0 Thenws.ChartObjects.Delete
    lastrow = ws.Range("a" &Rows.Count).End(xlUp).Row
    Set ch = ws.ChartObjects.Add(ws.[f5].Left,ws.[f5].Top, 360, 215) '
    ch.Name = ws.[b1]

我们先定义一个ChartObject对象ch,,接着删除Risk工作表中所有的图表(嵌入式图表,下同,以后不再指明),并计算A列最后一个非空行,最后用Add方法新增一个图表。

Add方法的语法为:工作表对象表达式.ChartObjects.Add(Left, Top, Width, Height),图表绘制在指定的工作表中,数据和图表可以不在同一个工作表。Left和Top表示图表的左上角坐标位置,以磅为单位,该坐标是相对于工作表上单元格 A1的左上角顶点的位置,我们也可以指定指定在某个单元格位置,比如示例的F5单元格。Width和Heigh是图表的宽度和高度,单位也是磅。1磅约=0.03527厘米,1厘米=28.35磅。

新增了图表,我们需要给它起一个名字,名字的值为B1单元格中的“中信银行”。名字不是必须的,你不指定,程序会默认给一个图表1这样的名字。我建议指定名字,这样方便引用,如ws.ChartObjects(“中信银行”)就能引用到这个图表,并可以做进一步操作。
创建了图表,其实是一个空的方框,什么也没有,空空如也,如下图:

5-图表对象.png

其实ChartObject对象只是 Chart对象的容器,ChartObject对象的属性和方法只能控制图表的外观(边框、填充、背景等等)和大小,真正的图表是Chart对象。我们在绘制窗体时,文本框、标签、命令按钮、Listview等控件才是我们需要的,窗体只是一个容器,它的存在只是为了容纳控件,ChartObject对象其实类似窗体的作用。

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-4 23:28 | 显示全部楼层


二、绘制系列线

1.基本系列线

我们以日期为横坐标,市盈率和市净率为两个系列,绘制图表。
    With ch.Chart
        .ChartType = xlLineMarkers
        .SeriesCollection.NewSeries
        .SeriesCollection(1).Values =ws.Range("b3:b" & lastrow)
        .SeriesCollection(1).XValues =ws.Range("a3:a" & lastrow)
        .SeriesCollection(1).Name = "市盈率"
        .SeriesCollection(1).AxisGroup = 1
        .SeriesCollection.NewSeries
        .SeriesCollection(2).Values =ws.Range("c3:c" & lastrow)
        .SeriesCollection(2).XValues =ws.Range("a3:a" & lastrow)
        .SeriesCollection(2).Name = "市净率"
        .SeriesCollection(2).AxisGroup = 2
    End With

刚才说过,ChartObject只是一个容器,真正的图表是Chart对象。ChartType= xlLineMarkers指定图表类型为数据点折线图。其值可以为下表中的任何类型,我们可以根据需要选择合适的图表类型(文字版可下载后边的附件):

13-图表类型.png

接着用SeriesCollection.NewSeries方法绘制系列,X轴是日期范围(Range(“A3:A23”),Y轴是市盈率(Range(“B3:B23”)。如果不指定X轴,系统默认按自然数系列(1,2,3……)产生X轴。
SeriesCollection(1).Name= "市盈率",该系列的名称为“市盈率”,用Name属性指定。系列的引用序号按添加系列的顺序确定,第一个系列是SeriesCollection(1),第二个系列是SeriesCollection(2)。
SeriesCollection(1).AxisGroup= 1指定指定系列的组类型。通俗地讲,就是这个系列的Y轴是哪一个,只可以选择主坐标轴组(其值为1)和次坐标轴组(其值为2)。我们这里指定市盈率系列是主坐标轴组。
接着产生第二个系列,名称为“市净率”,属于次坐标轴组。为什么要指定2个坐标轴呢?因为市盈率和市净率是不一样的内容,如果不指定次坐标轴,那么市盈率和市净率共用主坐标轴,组合起来是不是莫名其妙?其效果图如下:

6-绘制两个系列无次坐标轴.png

从上图中可见,市净率也使用市盈率的Y轴数值。因为市盈率和市净率数值相差甚大,导致市净率的系列线几乎看不到任何起伏,这显然不是我们想要的效果。我们给市净率单独的一个Y轴,就能解决这个问题。SeriesCollection(2).AxisGroup = 2是让市净率系列用它自己的Y轴(次坐标轴),加了这句话之后,图表变成下图,显然效果杠杠的:


7-绘制两个系列有次坐标轴.png

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-4 23:32 | 显示全部楼层


2.系列线进阶
         除了使用默认设置,系列线还可以设置丰富的属性。系列线的分解图如下:

10-系列线的分解图.png

    Withch.Chart
       With .SeriesCollection.NewSeries
           .Values = ws.Range("b3:b" & lastrow)
           .XValues = ws.Range("a3:a" & lastrow)
           .ChartType = xlArea
           .Interior.Color = RGB(127, 255, 212)
       End With
       With .SeriesCollection.NewSeries
           .Values = ws.Range("b3:b" & lastrow)
           .XValues = ws.Range("a3:a" & lastrow)
           .ChartType = xlLineMarkers
           .MarkerSize = 5 '数据标记大小
           .MarkerStyle = xlMarkerStyleCircle '数据标记类型
           .MarkerBackgroundColor = RGB(255, 106, 106)
           .MarkerForegroundColor = RGB(90, 178, 238)
           .HasDataLabels = True '有数据标签
           .DataLabels.NumberFormat = "0.00"
            .HasLeaderLines = True
           .LeaderLines.Border.ColorIndex = 5
           .Trendlines.Add Type:=xlPolynomial '趋势线
           .Trendlines(1).Border.LineStyle = xlDash
           .Trendlines(1).Border.Color = vbRed
       End With
       .HasLegend = False
End With

我们不指定Chart的图表类型,而直接指定系列的类型,且一个图表中不同趋势线可以使用不同的类型。第一条系列的类型是面积图(xlArea),而第二天系列是折线图(xlLineMarkers)。

在折线图中,我们还指定了数据标记的形状和大小,其形状可为如下的选项:

  
xlMarkerStyleAutomatic
  
自动设置标记
xlMarkerStyleCircle
圆形标记
xlMarkerStyleDash
长条形标记
xlMarkerStyleDiamond
菱形标记
xlMarkerStyleDot
短条形标记
xlMarkerStyleNone
无标记
xlMarkerStylePicture
图片标记
xlMarkerStylePlus
带加号的方形标记
xlMarkerStyleSquare
方形标记
xlMarkerStyleStar
带星号的方形标记
xlMarkerStyleTriangle
三角形标记
xlMarkerStyleX
带 X 记号的方形标记

HasDataLabels =True 指定有数据标签,就是系列线上得到那些数字。HasLeaderLines = True设置引导线。这些设置基本没有多少用途,反而让图表显得更复杂。Pass吧!

.Trendlines.AddType:=xlPolynomial,添加一条趋势线,代表数据的运动规律。类型有如下选项,这个需要非常丰富的经验,不然无法选择准确的类型。

  
名称
  
描述
xlExponential
5
使用公式(如 y=ab^x)计算数据点的最小平方拟合值。
xlLinear
-4132
使用线性公式 y = mx + b 计算数据点的最小平方拟合值。
xlLogarithmic
-4133
使用公式 y = c ln x + b 计算数据点的最小平方拟合值。
xlMovingAvg
6
使用通过数据系列中某些部分计算出的一系列平均值。数据点个数等于数据系列中数据点的总数减去为周期指定的数值。
xlPolynomial
3
使用公式(如 y = ax^6 + bx^5 + cx^4 + dx^3 +  ex^2 + fx + g)计算数据点的最小平方拟合值。
xlPower
4
使用公式(如 y = ax^b)计算数据点的最小平方拟合值。

最后绘制出来的图表如下:

11-系列进阶.png


评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-4 23:35 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助


三、坐标轴的设定

    With ch.Chart.Axes(xlValue, xlPrimary)
        .CrossesAt = .MinimumScale
        .TickLabels.Font.Size = 8
        .MajorGridlines.Border.ColorIndex = 20
        .HasTitle = True
        .AxisTitle.Text = "市盈率"
        .AxisTitle.Orientation = xlVertical
    End With
    With ch.Chart.Axes(xlValue, xlSecondary)
        .CrossesAt = .MinimumScale
        .TickLabels.Font.Size = 8
        .HasTitle = True
        .AxisTitle.Text = "市净率"
        .AxisTitle.Orientation = xlVertical
    End With
    With ch.Chart.Axes(xlCategory)
        .TickLabels.Font.Size = 8
        .TickLabels.NumberFormatLocal ="yyyy/m/d"
        .HasTitle = True
        .AxisTitle.Text = "日期"
        .AxisTitle.Characters.Font.Size = 8
        .AxisTitle.Characters.Font.Color =vbRed
    End With
用Chart.Axes方法返回一个代表图表上坐标轴的对象。语法为:Chart.Axes(Type, AxisGroup),Type指定要返回的坐标轴的类型,为以下常量之一:xlValue、xlCategory 或 xlSeriesAxis(xlSeriesAxis 仅对三维图表有效)。Excel图表把X轴叫做水平(分类)轴,Y轴叫垂直(值)轴。

  
名称
  
描述
xlCategory
1
坐标轴显示类别。
xlSeriesAxis
3
坐标轴显示数据系列。
xlValue
2
坐标轴显示值。

AxisGroup指定坐标轴组类型。如果省略该参数,则使用主坐标轴组(三维图表仅有一个坐标轴组)。其可取值已经在第二节讲过了,这里重复一遍:

  
名称
  
描述
xlPrimary
1
主坐标轴组。
xlSecondary
2
次坐标轴组。

Chart.Axes(xlValue,xlPrimary)返回主坐标轴对象,主坐标轴就是图表左边的Y轴。Chart.Axes(xlValue, xlSecondary)返回次坐标轴对象,次坐标轴就是图表右边的Y轴。Chart.Axes(xlCategory)返回的是X轴对象。坐标轴对象的方法只有Delete和SELECT两个,代表删除和选择,这个容易理解,其属性有几十种,像坐标轴的大小、位置、是否有箭头等等,Excel自动设置的已经足够好,我们基本上都不需要自行设置。

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-4 23:40 | 显示全部楼层


1. 设置坐标轴的标题区

HasTitle = True表示有标题。必须设置为True才能设置坐标轴标题的其他属性。
AxisTitle.Text和AxisTitle.Caption效果一样,设置坐标标题的显示文本。
AxisTitle.Left设置从坐标轴标题框左边缘到图表区左边缘的距离,AxisTitle.Top设置从坐标轴标题框上边缘到图表区顶部的距离,都以磅为单位。
AxisTitle.Orientation设置文本方向。此属性的值可设为–90 到90度之间的整数旋转值或以下常量之一:

  
名称
  
说明
xlDownward
-4170
文字向下排列。
xlHorizontal
-4128
文字水平排列。
xlUpward
-4171
文字向上排列。
xlVertical
-4166
向下居中排列。

上表的说明是我搜索微软官网的,貌似不太符合,我只好逐一试验,对应下边四种格式,第三种格式是Y轴的默认文字方向:

12-文字方向.png   

       AxisTitle.Characters.Font.Size = 8设置坐标轴标题文字的大小为8.
AxisTitle.Characters.Font.Color= vbRed设置坐标轴标题文字的颜色为红色。
坐标轴标题默认是没有的,可以不设置,大家看自己的需求自行设置即可。效果图如下:

8-坐标轴标题区.png


2.坐标轴的刻度线标签文本

    什么是刻度线标签?X轴的2017/12/1、2017/12/29,Y轴的6.9、7.1这些就是刻度线标签,我们可以设置其属性,比如TickLabels.Font.Size = 8设置字体大小(字体、颜色也如此设置,这里不全部举例了,都是很简单的设置),可以设置其数字格式,如X轴是日期,我们可以这样设置TickLabels.NumberFormatLocal = "yyyy/m/d",如果是数字,我们可以设置小数点位数,跟平时我们按Ctrl+1设置单元格格式没有任何区别。
TickLabels.Orientation设置刻度线标签的文字方向,此属性值可设为 -90 到 90 度之间的整数旋转值或以下常量之一:

  
名称
  
描述
xlTickLabelOrientationAutomatic
-4105
由 Excel 设置文本方向。
xlTickLabelOrientationDownward
-4170
向下排列文本。
xlTickLabelOrientationHorizontal
-4128
水平排列字符。
xlTickLabelOrientationUpward
-4171
向上排列文本。

3. 设置坐标轴的取值范围和刻度单位

坐标轴的最大值、最小值、主要刻度单位、次要刻度单位默认都是自动设置,Excel根据数据源区域的值自动合理设置。我们在需要的时候可以自行设置。刻度线标签的显示文本是由坐标轴的最大值、最小值、主要刻度单位、次要刻度单位确定的。

.MinimumScale 属性返回或设置数值轴上的最小值,.MaximumScale 属性返回或设置数值轴上的最大值。上图Y轴最小值自动设置为6.9,你可以设置为.MinimumScale =6.8,最大值也是一样的设置。

上图中可以看出,主要刻度单位为0.1,因为刻度线标签从6.9、7.0、7.1顺序排列下去,我们可以设置为主要刻度单位.MajorUnit = 0.05,这样Y轴就是6.95、7.00、7.05……,次要刻度单位.MinorUnit =0.01;X轴的主要刻度为2天,因为12/1、12/3这种序列,我们可以.MajorUnit =1,这样就可以把每天的日期都列出(如果有必要的话)。
4.设置X轴与Y轴的交点

CrossesAt 属性设置数值轴中与分类坐标轴的交点。CrossesAt = .MinimumScale是设置Y轴的最小值与X轴相交。因为市盈率最小值是6.9,所以前面的图表中Y轴的6.9与X轴相交。如果我们想要X轴与Y轴的交点位于Y轴上数值7.3 的位置,怎么设置呢?我们设置CrossesAt = 7.3,得到的图如下:

9-X与Y轴相交点设置.png

5.设置网格线

    .MajorGridlines属性指定坐标轴的主要网格线。只有主要坐标轴组中的坐标轴才能有网格线。可以设置网格线的样式和颜色。
    .HasMajorGridlines = True  ’Excel图表默认有网格线,可省略该句
    .MajorGridlines.Border.ColorIndex = 20  ’设置网格线颜色
    .MajorGridlines.Border.LineStyle = xlDash  ’可使用默认线型,省略该句

设置次要网格线用HasMinorGridlinesMinorGridlines,参数跟主要网格线相同。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-4 23:42 | 显示全部楼层


四、设置图表的标题区
        Withch.Chart
            .HasTitle = True
            .ChartTitle.Text = ch.Name
            .ChartTitle.Font.Size = 18
            .ChartTitle.Left = 137
            .ChartTitle.Top = 2
End With

HasTitle = True,设置图表有标题。HasTitle必须为True才能设置标题区的属性。ChartTitle.Left= 137ChartTitle.Top = 2是标题框相对于图表边框左边缘和上边缘的距离,单位为磅。这个比较简单易懂,不再讲解。
五、设置图表的绘图区

   With ch.Chart
       .PlotArea.Width = 347
       .PlotArea.Left = 0
       .PlotArea.Top = 20
       .PlotArea.Height = 181
   End With
         必须添加了系列和设置了坐标轴之后,才能设置图表的绘图区的大小、位置和外观,否则报错。可以用PlotArea.Border.LineStyle给绘图区设置点线边框。PlotArea.WidthPlotArea.Height指定了绘图区的宽度和高度,而PlotArea.LeftPlotArea.Top指定绘图区相对于图表区边缘的距离。
六、设置图表的图例区

   With ch.Chart
       .HasLegend = True
       .Legend.Font.Size = 8
        .Legend.Font.ColorIndex = 5
       .Legend.Position = xlLegendPositionRight
End With

可以用Left和Top属性设置图例的位置,Height和Width设置图例区域的大小,也可以用 Legend.Position指定图例在图表中的位置,可为如下值之一:
  
名称
  
描述
xlLegendPositionBottom
-4107
位于图表下方。
xlLegendPositionCorner
2
位于图表边框的右上角。
xlLegendPositionCustom
-4161
位于自定义的位置上。
xlLegendPositionLeft
-4131
位于图表的左侧。
xlLegendPositionRight
-4152
位于图表的右侧。
xlLegendPositionTop
-4160
位于图表的上方。
图表可以用Export方法以图形格式导出图表到文件。语法为:
表达式.Export(Filename,FilterName, Interactive),其中表达式是代表一个Chart对象的变量。Filename为被导出的文件的名称,后两个参数可选。可以导出的格式为PNG、GIF等图片格式,如ch.Chart.Export "g:\test.png",将该图表保存到G盘,文件名为test.png.图表可以导出为文件,然后用LoadPicture加载到窗体的图片控件中,也可以使用ChartSpace直接在窗体上绘制图表。ChartSpace是微软Office Web Components(简称OWC)中的控件,主要提供 Spreadsheet, Chart, PivotTable等组件。OWC能将部分Office的功能扩展到Web上,是一款优秀的服务器端图表引擎。使用前需要安装OWC11,。官方下载地址:https://www.microsoft.com/zh-cn/download/details.aspx?id=22276。安装好之后,在窗体上添加控件,引用:Microsoft Office Chart  11.0就可以了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-5 10:34 | 显示全部楼层
据说office2010开始已经不支持OWC组件了。ChartSpace还是不讲解了。
不过ChartSpace的确很强大,功能媲美Excel图表,的确有点遗憾。

只演示一个在窗体中显示图表export方法导出的图表,也算是曲线救国吧!

QQ图片20180605103027.png

演示代码附件: 在窗体中显示图表.zip (14.89 KB, 下载次数: 783)


补充内容 (2019-6-12 20:41):
在窗体上绘制图表可使用MSChart控件:http://club.excelhome.net/thread-1458245-1-1.html

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-5 17:39 | 显示全部楼层


貌似大家只对数组、字典这种非常简单的内容感兴趣,这些内容只要几句话就能讲完全部内容。

而图表这种Excel高级应用,要全面涉及到,一本书都讲不完,最基础的内容也要十几页内容。

以下附件为本帖的Word文档和示例完整代码。

VBA图表 基础教程.zip (292.46 KB, 下载次数: 2276)
VBA图表 基础教程完整代码.zip (50.26 KB, 下载次数: 1641)

评分

18

查看全部评分

TA的精华主题

TA的得分主题

发表于 2018-6-6 13:10 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-5 16:33 , Processed in 0.062678 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表