在我的尽职调查过程中,我设法解决了这个问题。我发布它是因为它可能对其他人有所帮助,也可以提供可能的替代解决方案。
chartData
对象(工作表)在ListObject
表中包含嵌入图表的数据。
我可以成功操作此ListObject
,但我很难获得生成的图表以正确反映数据。我期望在第1行中有类别标签,在A列中有系列名称,例如:
A B C
1 | Cat1 | Cat2 |
2 srs1| 75% | 25% |
3 srs2| 68% | 32% |
对于大多数图表,我可以这样做:
Sub Main()
Dim c as Chart
Set c = ActivePresentation.Slides(1).Shapes("Chart 1")
UpdateChart c
End Sub
Sub UpdateChart(cht As Chart)
Dim chtFormula$
Dim chtSheet As Worksheet
Dim lTable As ListObject
Set chtSheet = cht.chartData.Workbook.Sheets(1)
Set lTable = chtSheet.ListObjects(1)
chtFormula = "='" & chtSheet.name & "'!" & lTable.Range.Address
cht.ApplyDataLabels
cht.SetSourceData chtFormula, xlRows
End Sub
产生示例图表,如:
然而,当A列中的“系列”名称是数字字符串时出现问题,例如,如果系列名称是“2012”和“2011”,那么该函数会返回这种可憎的行为:
手动打开“选择数据”对话框确认:
如果我手动编辑系列,我可以达到预期的效果:
但到目前为止,我无法在VBA中这样做。调试语句产生一系列.Formula
,如我所料:
=SERIES(,Sheet1!$A$1:$C$1,Sheet1!$A$2:$C$2,1)
但是,如果我尝试操纵公式字符串,然后分配给.Formula
属性,我会得到'方法'.Formula'对象'系列'失败':
我仔细阅读文档,看到PowerPoint图表中提供了Formula is indeed a property。但它不起作用。
有什么想法吗?
答案 0 :(得分:1)
想要崩溃PowerPoint 2013吗?运行此代码。它执行正常,直到End Sub。
之前的最后一行Sub CrashPowerPoint()
Dim sl As Slide
Dim sh As Shape
Dim ch As Chart
Dim srs As Series
Dim sFmla As String
Set sl = ActiveWindow.View.Slide
Set sh = sl.Shapes(sl.Shapes.Count)
Set ch = sh.Chart
Set srs = ch.SeriesCollection(1)
sFmla = srs.Formula
End Sub
我一直在尝试转换一些Excel图表VBA,以便它在PowerPoint中运行。根据MSDN文档,系列公式是一个东西,但它无法访问。
我开始使用.Values和.XValues取得了一些小小的成功,但与Excel中的相比,它仍然感觉有点不自然。
答案 1 :(得分:0)
当我在发布问题之前测试各种方法时,我突然意识到我可能会公式性地直接引用系列“.Name
和.Values
以及.XValues
。” / p>
以前我一直在从字符串文字和数组数据中分配这些属性,例如.Name = str$
和.Values = Array(0,3,5,7)
。
这是权力的最初意图 - 当然已经改变了 - 因为从用户/客户的角度来看,他们无法与之交互的图表存在问题(例如,轻松添加新系列或重新安排他们等。)
所以这就是我提出的:
Sub TestUpdate()
Dim cht As Chart
Dim chtSheet As Worksheet
Dim lTable As ListObject
Dim chtRange As Range
Dim srs As Series
Dim SC As SeriesCollection
Dim srsRow As Long
Set cht = ActivePresentation.Slides(2).Shapes(2).Chart
cht.chartData.Activate
Set chtSheet = cht.chartData.Workbook.Sheets(1)
Set lTable = chtSheet.ListObjects(1)
'## Define a range object to represent the part of the table containing the
' Headers (category labels) and the series data (but omitting the Series Labels)
Set chtRange = lTable.Range.Offset(, 1).Resize(, lTable.ListColumns.count - 1)
Set SC = cht.SeriesCollection
'## Get rid of any previous series data,
' A previous routine has assigned new data
' and a subsequent routine will custom format the data labels, etc.
' So it is best to start with a clean slate.
Do Until SC.count = 0
cht.SeriesCollection(1).Delete
Loop
'## Add new series from each row in the Table, ignoring the header
For srsRow = 2 To chtRange.Rows.count
Set srs = cht.SeriesCollection.NewSeries
With srs
.name = "=" & chtSheet.name & "!" & lTable.DataBodyRange.Cells(srsRow - 1, 1).Address
.Values = "=" & chtSheet.name & "!" & chtRange.Rows(srsRow).Address
.XValues = "=" & chtSheet.name & "!" & chtRange.Rows(1).Address
End With
Next
cht.chartData.Workbook.Application.WindowState = -4140
End Sub
所以它的长短是因为它似乎无法分配给.Formula
属性,但是如果你细分公式的各个组成部分,你可以单独分配它们。
答案 2 :(得分:0)
由于问题的关键在于数字XValues会产生问题,因此有一种解决方法。只需追加"'"到每个XValue的字符串的开头,这将导致它被视为文本。
这使您可以执行chart.SetSourceData("Sheet1!$A$1:$C$4")
并且一切都按预期工作,而无需为每行创建单独的系列。