我使用以下代码将所有图表从一个工作簿复制到另一个工作簿:
using Excel = Microsoft.Office.Interop.Excel;
...
private static void CopyCharts(Excel.Workbook wbIn, Excel.Workbook wbOut)
{
Excel.Worksheet wsOutAfter = (Excel.Worksheet)wbOut.Sheets["Last Sheet"];
foreach (Excel.Chart c in wbIn.Charts)
{
c.Copy(Type.Missing, wsOutAfter);
}
}
每个图表引用源工作簿中的工作表上的数据(" wbIn")。这样做的问题是Chart.Copy命令保留了这些链接,因此现在目标工作簿中的图表(" wbOut")包含指向wbIn的外部链接。
为了摆脱外部链接,我想迭代每个目标图表中的所有系列,并更新XValues和值以指向目标数据表。这就是我到目前为止所拥有的:
private static void CopyCharts(Excel.Workbook wbIn, Excel.Workbook wbOut)
{
Excel.Worksheet wsOutAfter = (Excel.Worksheet)wbOut.Sheets["Plot Items"];
foreach (Excel.Chart c in wbIn.Charts)
{
string chartName = c.Name;
c.Copy(Type.Missing, wsOutAfter);
Excel.SeriesCollection sc = (Excel.SeriesCollection)c.SeriesCollection();
foreach (Excel.Series s in sc)
{
Excel.Range r = (Excel.Range)s.XValues;
// get string representing range, modify it and set corresponding
// series in wbOut.Charts.Item[chartName] to something appropriate
}
}
}
但演员抛出异常:
System.InvalidCastException: Unable to cast object of type 'System.Object[*]' to type 'Microsoft.Office.Interop.Excel.Range'.
如何获取和修改Series.XValues和.Values范围?
答案 0 :(得分:0)
我正在看错误的系列成员。我需要更改的成员是Series.Formula,而不是Series.XValues和.Values。这是我最终得到的结果,迭代输出工作簿中的图表,然后迭代他们的系列并使用正则表达式删除外部链接文本:
private static void CopyCharts(Excel.Workbook wbIn, Excel.Workbook wbOut)
{
Excel.Worksheet wsOutAfter = (Excel.Worksheet)wbOut.Sheets["Plot Items"];
foreach (Excel.Chart c in wbIn.Charts)
{
c.Copy(Type.Missing, wsOutAfter);
}
// break external links in new charts
Regex externalLink = new Regex(@"\[" + wbIn.Name + @"\]");
foreach (Excel.Chart cOut in wbOut.Charts)
{
Excel.SeriesCollection scOut = (Excel.SeriesCollection)cOut.SeriesCollection();
foreach (Excel.Series sOut in scOut)
{
string formula = sOut.Formula;
formula = externalLink.Replace(formula, "");
sOut.Formula = formula;
}
}
}
编辑:但是有更好的方法可以摆脱所有外部链接。它的很多更快更全面。我只是在复制完所有的图表和图表后调用它:
private static void BreakAllExternalLinks(Excel.Workbook wbIn, Excel.Workbook wbOut)
{
Array links = (Array)wbOut.LinkSources(Excel.XlLink.xlExcelLinks);
foreach (object o in links)
{
string link = o as string;
if (link == wbIn.FullName)
wbOut.ChangeLink(link, wbOut.FullName, Excel.XlLinkType.xlLinkTypeExcelLinks);
}
}
答案 1 :(得分:0)
我尝试使用建议的方法,但有一个例外:
无法转换类型' System.Object [*]'输入' System.Object []'
在C#4.0中,您需要先转换为对象。我的诗句很适合我:
private static void BreakAllExternalLinks(Excel.Workbook wbFrom, Excel.Workbook wbTo)
{
Array links = (Array)((object)wbTo.LinkSources(Excel.XlLink.xlExcelLinks));
if (links != null)
{
foreach (object o in links)
{
string link = o as string;
if (link == wbFrom.FullName)
{
wbTo.ChangeLink(link, wbTo.FullName, Excel.XlLinkType.xlLinkTypeExcelLinks);
}
}
}
}