我站在我的智慧的边缘,并且已经失去了整整一天试图做一些不应该那么复杂的事情。
我有一个从Sybase查询返回的Recordset。此记录集用于在Excel中构建数据透视表。到现在为止还挺好。我想更改数据透视表中的值,并执行此操作我使用新值来更新记录集中的某些记录。我可以在没有任何问题的情况下在RS中进行更新,并且下次迭代它时将值保存在RS中。
问题是这些值未反映在数据透视表中。我试过了:
pivotTable.Refresh();
pivotTable.PivotCache().Refresh();
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();
有人知道怎么做吗?修改记录集,然后“刷新”数据透视表,以根据记录集重新计算数据透视表。
由于 肖恩
答案 0 :(得分:3)
好吧,我解决了。似乎Recordset
被PivotTable
“消耗”后,您可以随意修改它,它只是不会在Excel中更新。尽管Recordset
包含PivotTable
数据,但刷新会清空Recordset.Clone()
并导致其丢失数据。
解决方法?在将Recordset
提供给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();
。
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;
}
记录集深度复制方法(在Web上不容易在C#中找到...)
{{1}}
希望这会让其他人感到头痛......
肖恩