1

我目前正在使用 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 中使用动态范围的方法,但这似乎只适用于从范围末尾添加或删除的列,而不是像列“2009”这样的中间列。

4

2 回答 2

1

我制作了以下代码来解决我的问题。它重建了所有现有的系列公式。这不适用于所有可能的图表,但它适用于我目前拥有的图表。将来我可能会再次查看它并尝试改进它。欢迎对以下代码提出建议。

(抱歉缺少代码注释)

        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++;
                }

            }

        }
于 2009-10-09T08:50:42.897 回答
0

没有一个属性可以保存图表的完整数据范围。但是,每个系列都包含有关其范围的信息。

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

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) =SERIES(Sheet1!$C$1,Sheet1!$A$2:$A$5, Sheet1!$C$2:$C$5,2) =SERIES(Sheet1!$D$1,Sheet1!$A$2:$A$5,Sheet1!$D$2:$D$5,3)

系列由四个参数组成:

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

于 2009-10-06T13:38:23.150 回答