使用记录集修改 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】:

好吧,我解决了。似乎一旦RecordsetPivotTable“使用”,您就可以随意修改它,只是不会在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 多维数据集数据透视表中获取数据

每次创建新数据透视表并保存文件时,Excel工作簿的文件大小都会增加

需要登录凭据时刷新 OLAP(数据透视表)

Excel 中显示的 OLAP 多维数据集连接

Excel数据透视表怎么刷新数据源

VBA自动刷新数据透视表