ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[Excel 图表] [第102期]堆积柱形和柱形混搭图[已总结]

[复制链接]

TA的精华主题

TA的得分主题

发表于 2014-2-17 23:18 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 delete_007 于 2014-3-26 08:49 编辑



对于会VBA的人来说,你只需要再学一点点图表就。。。,no sweat(小菜一碟);
对于会函数的人来说,我想应该也只需要再学一点点图表就。。。,a piece of cake(一碟小菜);
对于会图表的人呢?那就再学一点VBA和函数吧
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
补充说明:表1数据源区域为:A4:K8,水果、蔬菜的增减也只发生在该区域,且通过覆盖的方式(非插入或删除列)来更新数据源。

截止日期: 2014-2-27至2014-3-25
评分:   完全达到附件要求的得2分



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-2-28 08:49 | 显示全部楼层
本帖最后由 delete_007 于 2014-3-12 09:16 编辑

先交一份答案吧,后面再修改。标签位置未达到题目要求。

函数感觉搞不定了,改写代码吧。摸索了很久,总算达到目的了。
添加了注释,方便阅读。
  1. Option Explicit

  2. Sub AddChart()
  3.     Dim arr, brr, i%, j%, k%, m%, Ser#(15), X$(15), FuZu%(15)
  4.     On Error Resume Next
  5.     Application.ScreenUpdating = False                      '关闭屏幕刷新
  6.     ChartObjects.Delete                                     '删除已有表格
  7.     arr = Range("A4:K8")                                    '作图所需数据源 表1
  8.     brr = Range("A12:B21")                                  '表2
  9.     Charts.Add                                              '添加图表
  10.     ActiveChart.SeriesCollection(1).Delete                  '删除图表中已有的数据系列
  11.     ActiveChart.Location xlLocationAsObject, "题目要求"     '指定图表的位置
  12.     ActiveChart.ChartType = xlColumnStacked                 '设置图表类型为堆积柱形图
  13.    
  14.     '设置横坐标数组
  15.     For k = 0 To 15
  16.         If k Mod 4 = 1 Then
  17.             X(k) = arr(Int(k / 4) + 2, 1)
  18.         Else
  19.             X(k) = ""
  20.         End If
  21.     Next
  22.    
  23.     '从表1的第2列开始循环,为图表插入数据系列
  24.     For i = 2 To UBound(arr, 2)
  25.         If arr(1, i) <> "" Then                             '如果arr(1,i)为空,表明数据系列已添加完毕
  26.             If arr(1, i) = "损益" Then
  27.                 m = 2                                       '将损益列的数据放在余数是2的行
  28.             Else
  29.                 j = 0
  30.                 Do
  31.                     j = j + 1
  32.                 Loop Until brr(j, 1) = arr(1, i)
  33.                 If brr(j, 2) = "水果" Then
  34.                     m = 0                                   '将水果列的数据放在余数是0的行
  35.                 Else
  36.                     m = 1                                   '将蔬菜列的数据放在余数是1的行
  37.                 End If
  38.             End If
  39.             
  40.             '根据arr(1,i)所属类型,重生成作图所需数据
  41.             For k = 0 To 15
  42.                 If k Mod 4 = m Then
  43.                     Ser(k) = arr(Int(k / 4) + 2, i)
  44.                 Else
  45.                     Ser(k) = 0
  46.                 End If
  47.             Next
  48.             
  49.             ActiveChart.SeriesCollection.NewSeries          '为图表添加新数据系列
  50.             
  51.             '为新数据系列设置名称、X轴值、数据值
  52.             With ActiveChart.SeriesCollection(i - 1)
  53.                 .Name = arr(1, i)
  54.                 .XValues = X
  55.                 .Values = Ser
  56.             End With
  57.         End If
  58.     Next
  59.    
  60.     '设置图表格式
  61.     With ActiveChart
  62.         .ChartGroups(1).GapWidth = 0                        '分类间距为0
  63.         .Axes(xlValue).MajorUnit = 50                       'Y轴主要刻度为50
  64.         .Axes(xlValue).MajorTickMark = xlNone               'Y轴主要刻度线 无
  65.         .Axes(xlValue).Border.ColorIndex = xlNone           'Y轴线条颜色 无线条
  66.         .Axes(xlCategory).Crosses = xlMaximum               '纵坐标轴交叉于 最大分类
  67.         .Axes(xlCategory).MajorTickMark = xlNone            '横轴主要刻度线 无
  68.         .Axes(xlValue).Crosses = xlMinimum                  '横坐标轴交叉于 最小值
  69.         .SetElement (msoElementLegendTop)                   '在顶部显示图例
  70.         
  71.         '添加辅助数据系列,模拟标签
  72.         .SeriesCollection.NewSeries
  73.         With .SeriesCollection(.SeriesCollection.Count)
  74.             .Name = "FZ"
  75.             .XValues = X
  76.             .Values = FuZu                                  '添加全是0值的辅助数据系列
  77.             .AxisGroup = 2                                  '系列绘制在次坐标轴上
  78.             .ChartType = xlLine                             '拆线图
  79.             .Border.ColorIndex = xlNone                     '线条颜色 无线条
  80.             
  81.             '根据损益值设置自定义标签
  82.             For i = 0 To 15
  83.                 If Ser(i) = 0 Then
  84.                     .Points(i + 1).HasDataLabel = False
  85.                                                             '0值不显示标签
  86.                 ElseIf Ser(i) > 0 Then                      '正值显示标签于下方
  87.                     .Points(i + 1).HasDataLabel = True
  88.                     .Points(i + 1).DataLabel.Text = Ser(i)
  89.                     .Points(i + 1).DataLabel.Position = 1
  90.                 ElseIf Ser(i) < 0 Then                      '负值显示标签于上方,并设置字体为红色
  91.                     .Points(i + 1).HasDataLabel = True
  92.                     .Points(i + 1).DataLabel.Text = Ser(i)
  93.                     .Points(i + 1).DataLabel.Font.ColorIndex = 3
  94.                     .Points(i + 1).DataLabel.Position = 0
  95.                 End If
  96.             Next
  97.         End With
  98.         
  99.         '设置次坐标轴格式
  100.         With .Axes(xlValue, xlSecondary)
  101.             .MinimumScale = ActiveChart.Axes(xlValue).MinimumScale
  102.                                                             '次坐标轴与主坐标轴最小值相同
  103.             .MaximumScale = ActiveChart.Axes(xlValue).MaximumScale
  104.                                                             '次坐标轴与主坐标轴最大值相同
  105.             .MajorUnit = 50                                 '次坐标轴主要刻度与主坐标轴相同为50
  106.             .MajorTickMark = xlNone                         '主要刻度线 无
  107.             .TickLabelPosition = xlNone                     '不显示坐标轴标签
  108.             .Border.ColorIndex = xlNone                     '不显示坐标轴线条
  109.         End With
  110.         .Legend.LegendEntries(.Legend.LegendEntries.Count).Delete
  111.                                                             '删除辅助数据系列的图例
  112.     End With
  113.    
  114.     Application.ScreenUpdating = True                       '开启屏幕刷新
  115. End Sub
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-2-28 22:16 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 lolmuta 于 2014-2-28 22:20 编辑

这对我来说有满有挑战性的…
说实在的,那个datalabel究竟要怎样才能上标哩…


因为在stack 表里面,column是会叠在一起的,所以标示决不会在column外面


不过勉强做出来了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

TA的精华主题

TA的得分主题

发表于 2014-3-6 20:30 | 显示全部楼层
lolmuta 发表于 2014-2-28 22:16
这对我来说有满有挑战性的…
说实在的,那个datalabel究竟要怎样才能上标哩…

已修正!!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-3-9 15:35 | 显示全部楼层
VBA做的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-3-12 15:23 | 显示全部楼层
本帖最后由 wudixin96 于 2014-3-12 19:43 编辑

请烟老师指点,这多格式的,累死俺了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-3-13 11:12 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
用函数+数据透视图。。。。。准确的说,还没完全一致,所以就只看看图片吧

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

点评

四姐还得加油啊。  发表于 2014-3-26 08:46

TA的精华主题

TA的得分主题

发表于 2014-3-13 17:20 | 显示全部楼层
哎。。。水平就顶到这了。。。图可以动态,但是图例没办法了。。。
在L2写公式,并拖到X28(709字符的9层IF嵌套公式呀,有不少可以简化的,懒得弄了~~):
  1. =IF(ROW()=12,IF(COLUMN()=12,"",IF(COLUMN()>=23,"损益",IF(COLUMN()>COUNTA($4:$4)+11,"",OFFSET($A$4,,COLUMN()-13)))),
  2. IF(COLUMN()=12,IF(MOD(ROW(),4)=2,-50,""),
  3. IF(COLUMN()=13,IF(MOD(ROW(),4)=2,"Q"&INT(ROW()/4)-2,""),
  4. IF(COLUMN()=23,IF(MOD(ROW(),4)=3,OFFSET(INDIRECT(CHAR(64+COUNTA($4:$4))&4),INT(ROW(3:3)/4),),0),
  5. IF(COLUMN()=24,IF(MOD(ROW(),4)=3,-OFFSET(INDIRECT(CHAR(64+COUNTA($4:$4))&4),INT(ROW(3:3)/4),),0),
  6. IF(OR(MOD(ROW(),4)=0,L$12=""),0,IF(L$12="损益",IF(MOD(ROW(),4)=3,OFFSET($A$4,INT(ROW(3:3)/4),COLUMN()-13),0),IF(AND(VLOOKUP(L$12,$A:$B,2,)="水果",MOD(ROW(),4)=1),OFFSET($A$4,INT(ROW(3:3)/4),COLUMN()-13),IF(AND(VLOOKUP(L$12,$A:$B,2,)="蔬菜",MOD(ROW(),4)=2),OFFSET($A$4,INT(ROW(3:3)/4),COLUMN()-13),0)))))))))
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-3-14 09:31 | 显示全部楼层
好长时间未发帖了,参与参与。感谢烟美女的好题!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-3-23 19:19 | 显示全部楼层
本帖最后由 sunya_0529 于 2014-3-23 19:20 编辑

额外写了一个随机生成数据源的代码,再加上“一键制图”的代码,如下——

  1. Option Explicit

  2. Private Sub CommandButton1_Click() '随机生成源数据
  3. Application.ScreenUpdating = False
  4. Dim i%, j%, str$, s$, arr() As String
  5. [B4:K8].ClearContents '清空数据区域
  6. i = Int(Rnd() * 6 + 4) '随机取出若干品种
  7. ReDim arr(i) '重定义数组维度
  8. str = "123456789" '定义随机抽取品种母序列
  9. Do '循环抽取随机品种
  10.   s = Val(Mid(str, Int(Rnd() * Len(str) + 1), 1))
  11.   arr(j) = Range("A" & s + 12)
  12.   str = Replace(str, s, "")
  13.   j = j + 1
  14. Loop While j <= i
  15. arr(i) = "损益"
  16. [B4].Resize(1, i + 1) = arr '写入表头
  17. [B5].Resize(4, i) = "=INT(RAND()*89+10)" '生成10~99之间的随机数
  18. Range(ActiveSheet.Cells(5, i + 2), ActiveSheet.Cells(8, i + 2)) = "=INT(RAND()*98+1)-50" '生成±49~0之间的随机数
  19. [B5].Resize(4, i + 1).Copy
  20. [B5].Resize(4, i + 1).PasteSpecial xlPasteValues
  21. Application.CutCopyMode = False
  22. [B5].Select
  23. Application.ScreenUpdating = True
  24. End Sub

  25. Private Sub CommandButton2_Click() '一键制图
  26. '构建数据源区域
  27. With ActiveSheet
  28.   Dim arr(15, 11), k As Range, i%, j%
  29.   arr(0, 0) = "季度"
  30.   arr(2, 0) = "Q1"
  31.   arr(6, 0) = "Q2"
  32.   arr(10, 0) = "Q3"
  33.   arr(14, 0) = "Q4"
  34.   j = [B4].End(xlToRight).Column - 1
  35.   For Each k In Range([B4], .Cells(4, [B4].End(xlToRight).Column - 1))
  36.     If Application.VLookup(k.Value, [A13:B21], 2, 0) = "水果" Then
  37.       i = i + 1
  38.       arr(0, i) = k
  39.       arr(1, i) = k.Offset(1, 0)
  40.       arr(5, i) = k.Offset(2, 0)
  41.       arr(9, i) = k.Offset(3, 0)
  42.       arr(13, i) = k.Offset(4, 0)
  43.     Else
  44.       j = j - 1
  45.       arr(0, j) = k
  46.       arr(2, j) = k.Offset(1, 0)
  47.       arr(6, j) = k.Offset(2, 0)
  48.       arr(10, j) = k.Offset(3, 0)
  49.       arr(14, j) = k.Offset(4, 0)
  50.     End If
  51.   Next
  52.   j = [B4].End(xlToRight).Column
  53.   arr(0, j - 1) = .Cells(4, j)
  54.   arr(3, j - 1) = .Cells(5, j)
  55.   arr(7, j - 1) = .Cells(6, j)
  56.   arr(11, j - 1) = .Cells(7, j)
  57.   arr(15, j - 1) = .Cells(8, j)
  58.   arr(0, j) = .Cells(4, j)
  59.   arr(3, j) = -Val(.Cells(5, j).Value)
  60.   arr(7, j) = -Val(.Cells(6, j).Value)
  61.   arr(11, j) = -Val(.Cells(7, j).Value)
  62.   arr(15, j) = -Val(.Cells(8, j).Value)
  63.   Sheets(2).Cells.ClearContents
  64.   Sheets(2).[A1].Resize(16, 12) = arr
  65. End With

  66. '生成图表
  67. Dim w As Shape, x As Chart, t%
  68. For Each w In ActiveSheet.Shapes
  69.   If w.Type = msoChart Then w.Delete
  70. Next
  71. t = Sheets(2).[A1].End(xlToRight).Column - 1
  72. Set x = ActiveSheet.Shapes.AddChart.Chart
  73. With x
  74.   .ChartType = xlColumnStacked
  75.   .SetSourceData Source:=Sheets(2).[B1].Resize(16, t) '选择数据源
  76.   .PlotBy = xlColumns
  77.   .ChartGroups(1).GapWidth = 0 '列簇间距为0
  78.   .Legend.Position = xlLegendPositionTop '图例项置顶显示
  79.   .Legend.LegendEntries(t).Delete
  80.   .Axes(xlCategory).MajorTickMark = xlNone '无横坐标刻度线
  81.   .Axes(xlCategory).TickLabelPosition = xlLow '横坐标标签位置置底
  82.   .SeriesCollection(1).XValues = "=Sheet2!$A$2:$A$16" '设置横坐标标签
  83.   .SeriesCollection(t).ApplyDataLabels
  84.   .SeriesCollection(t).DataLabels.Position = xlLabelPositionInsideBase
  85.   .SeriesCollection(t).DataLabels.NumberFormatLocal = "[红色]-0;0;;"
  86.   .SeriesCollection(t).Format.Fill.Visible = msoFalse
  87.   .Axes(xlValue).MajorTickMark = xlNone '无主纵坐标轴刻度线
  88.   .Axes(xlValue).TickLabelPosition = xlTickLabelPositionHigh '主纵坐标轴标签显示在右侧
  89.   .Axes(xlValue).Format.Line.Visible = msoFalse '无主纵坐标轴线
  90. End With
  91. Set x = Nothing
  92. End Sub

复制代码







本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

1

查看全部评分

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-4-17 03:35 , Processed in 0.061840 second(s), 22 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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