Формула диаграммы изменений в Excel
-
19-09-2019 - |
Вопрос
В настоящее время я создаю документы Excel, используя объектную модель Office.У меня проблема с редактированием диаграмм.В файле шаблона я получил гистограмму, которая использует следующий источник:
2008 2009 2010
A 10% 25% 15%
B 20% 25% 35%
C 30% 25% 45%
D 40% 25% 5%
Диаграмма имеет следующую формулу:=лист2!$A $1:$D $5
Когда, например, столбец "2009" пуст, я не хочу показывать полосу на диаграмме.Поэтому я хочу изменить формулу на что-то вроде:=лист2!A $ 1:D $ 5; лист2!C $1:C $ 5
Я знаю, что есть метод SetSourceData, но сначала мне нужно получить текущую формулу или диапазон.
Мой вопрос заключается в следующем;Как я могу получить формулу диаграммы?Или, может быть, есть другой способ сделать то, что я хочу?
Я также попробовал что-то с динамическими диапазонами в Excel, но, похоже, это работает только со столбцами, которые добавляются или удаляются из конца диапазона, а не в середине, как столбец "2009".
Решение
Я сделал следующий код, чтобы решить мою проблему.Он перестраивает все существующие формулы рядов.Это не будет работать для всех возможных диаграмм, но работает для тех, которые у меня есть на данный момент.В будущем я, вероятно, пересмотрю его еще раз и постараюсь улучшить.Предложения по приведенному ниже коду приветствуются.
(извините за отсутствие комментариев к коду)
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
Основываясь на вашем примере данных, код выведет следующее
=СЕРИЯ(Лист1!$B$1,Лист1!$A$2: $A $5, Лист1!$B$2:$B$5,1) =СЕРИЯ(Лист1!$C$1, Лист1!$A$2:$A$5, Лист1!$C$2:$C$5,2) =СЕРИЯ(Лист1!$D$1, Лист1!$A$2: $A$5, Лист1!$D$2:$D$5,3)
Тот Самый Серии состоит из четырех аргументов:
(Название серии, XValues, Значения, Порядок построения)