使用记录集修改 Excel 数据透视表并刷新:异常
Posted
技术标签:
【中文标题】使用记录集修改 Excel 数据透视表并刷新:异常【英文标题】:Modify an Excel PivotTable with a Recordset and Refresh: Exception 【发布时间】:2012-09-30 00:35:03 【问题描述】:在这里,我正处于我的智慧边缘,花了一整天的时间来尝试做一些不应该如此复杂的事情。
我有一个从 Sybase 查询返回的 Recordset。此记录集用于在 Excel 中构建数据透视表。到目前为止,一切都很好。我想更改数据透视表中的一个值,为此我使用新值来更新记录集中的某些记录。我可以毫无问题地在 RS 中进行更新,并且下次迭代时将值保存在 RS 中。
问题是这些值没有反映在数据透视表中。我试过了:
pivotTable.Refresh();
COMException:数据透视表类的 RefreshTable 方法失败
pivotTable.PivotCache().Refresh();
ComException:HRESULT 异常:0x800A03EC
pivotTable.Update();
没有例外,但更改不会反映在数据透视表中
我也尝试克隆记录集并从中创建一个全新的数据透视表,但尽管Recordset
中有数据,PivotCache.RecordCount
是 0
代码:
var app = ExcelAppHelper.GetExcelApp();
if (app.ActiveCell == null || app.ActiveCell.PivotTable == null)
return;
PivotTable pivotTable = app.ActiveCell.PivotTable;
var rs = (Recordset)pivotTable.PivotCache().Recordset;
rs.MoveFirst();
s_lastSelectedPivotTree = new PivotFilterTree();
RecalculateSelectedValues(vmMain);
while (!rs.EOF)
if (s_lastSelectedPivotTree.Contains(rs.Fields))
foreach (var dataFieldName in s_lastSelectedDataFields)
// update the values in the RS
rs.Fields[dataFieldName].Value = newValue;
// commit the modifications into the RS
rs.Update(Type.Missing, Type.Missing);
rs.MoveNext();
rs.MoveFirst();
// here is the magic line that will show me the updated pivot table
pivotTable.Update();
有人知道怎么做吗?修改记录集,然后“刷新”数据透视表以根据记录集重新计算数据透视表。
谢谢 肖恩
【问题讨论】:
【参考方案1】:好吧,我解决了。似乎一旦Recordset
被PivotTable
“使用”,您就可以随意修改它,只是不会在Excel 中更新。尽管Recordset
包含数据,但刷新将清空PivotTable
并导致其丢失数据。
解决方法?创建Recordset
的深层副本(Recordset.Clone()
不起作用),然后将其提供给PivotTable
,然后每次要修改其中的值时,修改“干净”副本,创建一个新的它的副本并将副本传递给PivotTable
以使用它。然后刷新PivotTable
。
var newRS = RecordsetDeepCopy(oldRS);
newRS.MoveFirst();
oldRS.MoveFirst();
while (!newRS.EOF)
if (s_lastSelectedPivotTree.Contains(newRS.Fields))
// set the new value in the selected data fields
foreach (var dataFieldName in s_lastSelectedDataFields)
oldRS.Fields[dataFieldName].Value = val;
newRS.Fields[dataFieldName].Value = val;
newRS.Update(Type.Missing, Type.Missing);
oldRS.Update(Type.Missing, Type.Missing);
newRS.MoveNext();
oldRS.MoveNext();
newRS.MoveFirst();
oldRS.MoveFirst();
pivotCache.Recordset = newRS;
pivotCache.Refresh();
还有recordset深拷贝的方法(网上C#不好找……)
private static Recordset RecordsetDeepCopy(Recordset src)
var clone = new Recordset();
int count = src.Fields.Count;
var names = new object[count];
int i = 0;
foreach (ADODB.Field field in src.Fields)
names[i++] = field.Name;
var attr = (FieldAttributeEnum)field.Attributes;
clone.Fields._Append(field.Name, field.Type, field.DefinedSize, attr);
clone.Open(Missing.Value, Missing.Value, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, 0);
src.MoveFirst();
while (!src.EOF)
var values = new object[count];
i = 0;
foreach (ADODB.Field field in src.Fields)
values[i++] = field.Value;
clone.AddNew(names, values);
src.MoveNext();
clone.Update(Missing.Value, Missing.Value);
return clone;
希望这可以避免其他人头疼...
肖恩
【讨论】:
以上是关于使用记录集修改 Excel 数据透视表并刷新:异常的主要内容,如果未能解决你的问题,请参考以下文章
如何使用或过滤器从 Excel 中的 OLAP 多维数据集数据透视表中获取数据