修改带有记录集的Excel数据透视表并刷新:异常

修改带有记录集的Excel数据透视表并刷新:异常,excel,vsto,refresh,pivot-table,recordset,Excel,Vsto,Refresh,Pivot Table,Recordset,我在这里已经不知所措,花了整整一天的时间试图做一些本不该如此复杂的事情 我有一个从Sybase查询返回的记录集。此记录集用于在Excel中构建数据透视表。到目前为止,一切顺利。我想更改数据透视表中的一个值,为此我使用新值更新记录集中的某些记录。我可以在RS中进行更新,而不会出现任何问题,下次迭代时,这些值会保存在RS中 问题是这些值没有反映在透视表中。我试过: pivotTable.Refresh() COMException:数据透视表类的RefreshTable方法失败 pivotTa

我在这里已经不知所措,花了整整一天的时间试图做一些本不该如此复杂的事情

我有一个从Sybase查询返回的记录集。此记录集用于在Excel中构建数据透视表。到目前为止,一切顺利。我想更改数据透视表中的一个值,为此我使用新值更新记录集中的某些记录。我可以在RS中进行更新,而不会出现任何问题,下次迭代时,这些值会保存在RS中

问题是这些值没有反映在透视表中。我试过:

  • pivotTable.Refresh()
    
    • COMException:数据透视表类的RefreshTable方法失败
  • pivotTable.PivotCache().Refresh()
    
    • ComException:来自HRESULT的异常:0x800A03EC
  • pivotTable.Update()
    
    • 没有例外,但这些更改不会反映在透视表中
我还尝试过克隆记录集并从中创建一个全新的数据透视表,但尽管
记录集
中有数据,但
数据透视缓存.RecordCount
为0

代码:

有人知道怎么做吗?修改记录集,然后“刷新”数据透视表,以基于该记录集重新计算数据透视表

谢谢
肖恩:嗯,我解决了。似乎一旦
数据透视表“使用”了
记录集
,您就可以随心所欲地对其进行修改,但它不会在Excel中更新。尽管
记录集
包含数据,但刷新将清空
数据透视表
,并导致其丢失数据

解决办法?在将
记录集
交给
数据透视表
之前,先创建
记录集
的深度副本(a
Recordset.Clone()
将不起作用),然后每次要修改其中的值时,都要修改“clean”副本,对其进行新的复制,并将副本传递给
数据透视表
以使用它。然后刷新数据透视表

        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();
以及记录集深度复制方法(在web上的C中不容易找到…)

希望这能为其他人省去一些麻烦

肖恩

        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;
}