Excel更改图表公式

我目前正在使用Office对象模型生成Excel文档。 我在编辑图表时遇到问题。 在一个模板文件中,我得到了一个使用以下源代码的条形图:

2008 2009 2010 A 10% 25% 15% B 20% 25% 35% C 30% 25% 45% D 40% 25% 5% 

图表有以下公式:= sheet2!$ A $ 1:$ D $ 5

例如,当“2009”列是空的,我不想在图表中显示栏。 所以我想把公式改成:= sheet2!A $ 1:D $ 5; sheet2!C $ 1:C $ 5

我知道有一个方法setSourceData,但我需要先获得当前的公式或范围。

我的问题是 我怎样才能得到图表公式? 或者也许还有另一种方法来做我想要的?

我也在Excel中尝试过使用dynamic范围,但是这似乎只适用于从范围末尾添加或删除的列,而不是像列“2009”中的那样。

我做了下面的代码来解决我的问题。 它重build所有现有的系列公式。 这将不适用于所有可能的图表,但它为我目前所拥有的图表。 将来我可能会再看一遍,并试图改进它。 以下代码的build议是受欢迎的。

(对于缺less代码的评论感到抱歉)

  foreach (Excel.ChartObject chart in (Excel.ChartObjects)sheet.ChartObjects(Type.Missing)) { IDictionary<int, Boolean> colHasValues = new Dictionary<int, Boolean>(); ArrayList seriesFormulas = new ArrayList(); foreach (Excel.Series series in (Excel.SeriesCollection)chart.Chart.SeriesCollection(Type.Missing)) { seriesFormulas.Add(series.Formula); Array sValues = (Array)series.Values; int i = 1; foreach (Object o in sValues) { if(!colHasValues.Keys.Contains(i)) colHasValues.Add(i, false); if (o != null) { colHasValues[i] = true; } i++; } } if (!colHasValues.Values.Contains(true)) { chart.Delete(); } else if (colHasValues.Values.Contains(false) && seriesFormulas.Count > 1) { ArrayList newSeriesFormulas = new ArrayList(); foreach (String formula in seriesFormulas) { String[] formulaBits = formula.Split(";".ToCharArray()); if (formulaBits.Length == 4) { for (int arrNr = 1; arrNr <= 2; arrNr++) { //1 = XValues, 2 = Values int indexFirstChar = formulaBits[arrNr].IndexOf(':'); int indexLastChar = formulaBits[arrNr].LastIndexOf('$', indexFirstChar) + 1; String firstRow = formulaBits[arrNr].Substring(indexLastChar, indexFirstChar - indexLastChar); String firstColumn = formulaBits[arrNr].Substring(indexLastChar - 2, 1); formulaBits[arrNr] = ""; foreach (KeyValuePair<int, Boolean> cat in colHasValues) { if (cat.Value == true) { formulaBits[arrNr] += "overzichten!$" + getExcelColumnName((getExcelColumnNumber(firstColumn) + cat.Key - 1)) + "$" + firstRow + ":$" + getExcelColumnName((getExcelColumnNumber(firstColumn) + cat.Key - 1)) + "$" + firstRow + ";"; } } formulaBits[arrNr] = formulaBits[arrNr].TrimEnd(";".ToCharArray()); if (formulaBits[arrNr].Contains(';')) { formulaBits[arrNr] = "(" + formulaBits[arrNr] + ")"; } } newSeriesFormulas.Add(String.Join(";", formulaBits)); } } int seriesid = 0; foreach (Excel.Series series in (Excel.SeriesCollection)chart.Chart.SeriesCollection(Type.Missing)) { series.Formula = newSeriesFormulas[seriesid].ToString(); seriesid++; } } } 

没有一个属性可以保存图表的全部数据范围。 然而,每个系列都有关于范围的信息。

下面的代码将列出所有系列,然后删除第二个。

 Sub ChartRanges() Dim lngSeries As Long ActiveSheet.ChartObjects("Chart 1").Select For lngSeries = 1 To ActiveChart.SeriesCollection.Count Debug.Print ActiveChart.SeriesCollection(lngSeries).Formula Next lngSeries 'List out series in chart ActiveChart.SeriesCollection(2).Delete 'Delete a series from the chart End Sub 

根据您的示例数据,代码将输出这个

=系列(Sheet1!$ B $ 1,Sheet1!$ A $ 2:$ A $ 5,Sheet1!$ B $ 2:$ B $ 5,1)=系列(Sheet1!$ C $ 1,Sheet1!$ A $ 2:$ A $ 5, Sheet1!$ C $ 2:$ C $ 5,2)=系列(Sheet1!$ D $ 1,Sheet1!$ A $ 2:$ A $ 5,Sheet1!$ D $ 2:$ D $ 5,3)

系列由四个参数组成:

(系列名称,XValues,值,绘图顺序)