إكسل تغيير الرسم البياني
-
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! $ $ 1: $ D $ 5
عندما يكون على سبيل المثال العمود "2009" فارغ، لا أريد إظهار الشريط في المخطط. لذلك أريد تغيير الصيغة إلى شيء مثل: = Sheet2! $ 1: D $ 5؛ Sheet2! 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
بناء على بيانات المثال الخاص بك، سوف يخرج الرمز هذا
= Series (ورقة 1! $ B $ 1، Sheet1! $ 2 $ 2: $ $ 5، ورقة $ B $ 2: $ B $ 5،1) = Series (Sheet1! $ C $ 1، Sheet1! $ $ 2: $ $ 5 Sheet1! $ C $ 2: $ C 5،2 $ CO $ 5) = Series (ورقة 1! $ D $ 1، Sheet1! $ $ 2: $ $ 5، ورقة 1 $ D $ 2: $ D $ 5،3
ال مسلسل يتكون من أربع حجج:
(اسم السلسلة، Xvalues، القيم، ترتيب المؤامرة)