题
目前,我正在生成使用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'/ P>
当例如列“2009”是空的,我不想显示图表中的栏。所以,我想要将公式更改为类似: = Sheet 2中A $ 1:!d $ 5; Sheet2的C $ 1:C $ 5'/ P>
我知道有一种方法setSourceData,但我需要得到当前式或第一范围。
我的问题是;我怎样才能得到图表公式?或者,也许有另一种方式做我想要什么?
我也试图与在Excel动态范围的东西,但这似乎仅与添加或删除从范围的端部,而不是在柱状“2009”的中间列工作。
解决方案
我提出了以下代码来解决我的问题。它重新建立所有existings系列公式。这不会对所有可能的图表工作,但它确实为那些我现在有。将来我可能会看它再次,努力提高它。建议下面的代码是受欢迎的。
(抱歉缺少代码注释)
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
根据你的示例性数据,代码将输出此
= SERIES(Sheet 1中$ B $ 1,工作表Sheet $ A $ 2:!$ A $ 5中,工作表Sheet $ B $ 2:$ B $ 5,1) = SERIES(Sheet 1中$ C $ 1,工作表Sheet $ A $ 2:!$ A $ 5中,工作表Sheet $ C $ 2:$ C $ 5,2) = SERIES(Sheet 1中$ d $ 1,工作表Sheet $ A $ 2:!$ A $ 5 $表Sheet 1 $ d 2:!$ d $ 5,3)
的系列强>由四个参数组成:
(系列名称,XValues,值叠加顺序)