数据透视表性能基于Pivot Cache。虽然关于这个主题的信息很少(我的意思是缺乏官方文档),但我发现了一些有趣的帖子和 MS 文档。
定义:
Pivot Cache 是保存数据透视表记录的特殊内存区域。
创建Pivot Table 时,Excel 会获取源数据的副本并将其存储在Pivot Cache 中。 Pivot Cache 保存在 Excel 的内存中。您看不到它,但这是您构建数据透视表时数据透视表引用的数据。
This enables Excel to be very responsive to changes in the Pivot Table but it can also double the size of your file。毕竟,数据透视缓存只是源数据的副本,因此文件大小可能会翻倍是有道理的。
请将此link 和link 用作起始参考点以获取更多信息。
此外,您还可以阅读 Pivot Cache in Excel 101 和 Excel Pivot Cache 101 的帖子,了解它是什么以及它有什么副作用。
这里有一些VB代码sn-ps和如何使用PivotCache object的例子。
这是一个用 C# 编写的代码,它允许您创建一个带有一些 Pivot Tables 的 Excel 工作簿,当然,使用 Pivot Cache:
System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;
using System.IO;
using System.Diagnostics;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
Excel.Application objApp;
Excel.Workbook objBook;
Excel.Sheets objSheets;
Excel.Workbooks objBooks;
string command = (@"SELECT * FROM dbo.Client");
using (SqlConnection connection = new SqlConnection(GetConnectionStringByName("CubsPlus"))) {
DataTable data = new DataTable();
try {
connection.Open();
}
catch (Exception e) {
StackTrace st = new StackTrace(new StackFrame(true));
StackFrame sf = st.GetFrame(0);
Console.WriteLine (e.Message + "\n" + "Method" + sf.GetMethod().ToString() + "\n" + "Line" + sf.GetFileLineNumber().ToString());
}
try {
data = DataTools.SQLQueries.getDataTableFromQuery(connection, command);
if (data == null) {
throw new ArgumentNullException();
}
}
catch (Exception e) {
StackTrace st = new StackTrace(new StackFrame(true));
StackFrame sf = st.GetFrame(0);
Console.WriteLine (e.Message + "\n" + "Method" + sf.GetMethod().ToString() + "\n" + "Line" + sf.GetFileLineNumber().ToString());
}
objApp = new Excel.Application();
try {
objBooks = objApp.Workbooks;
objBook = objApp.Workbooks.Add(Missing.Value);
objSheets = objBook.Worksheets;
Excel.Worksheet sheet1 = (Excel.Worksheet)objSheets[1];
sheet1.Name = "ACCOUNTS";
string message = DataTools.Excel.copyDataTableToExcelSheet(data, sheet1);
if (message != null) {
Console.WriteLine("Problem importing the data to Excel");
Console.WriteLine(message);
Console.ReadLine();
}
//CREATE A PIVOT CACHE BASED ON THE EXPORTED DATA
Excel.PivotCache pivotCache = objBook.PivotCaches().Add(Excel.XlPivotTableSourceType.xlDatabase,sheet1.UsedRange);
Console.WriteLine(pivotCache.SourceData.ToString());
Console.ReadLine();
//WORKSHEET FOR NEW PIVOT TABLE
Excel.Worksheet sheet2 = (Excel.Worksheet)objSheets[2];
sheet2.Name = "PIVOT1";
//PIVOT TABLE BASED ON THE PIVOT CACHE OF EXPORTED DATA
Excel.PivotTables pivotTables = (Excel.PivotTables)sheet2.PivotTables(Missing.Value);
Excel.PivotTable pivotTable = pivotTables.Add(pivotCache, objApp.ActiveCell, "PivotTable1", Missing.Value, Missing.Value);
pivotTable.SmallGrid = false;
pivotTable.TableStyle = "PivotStyleLight1";
//ADDING PAGE FIELD
Excel.PivotField pageField = (Excel.PivotField)pivotTable.PivotFields("ParentName");
pageField.Orientation = Excel.XlPivotFieldOrientation.xlPageField;
//ADDING ROW FIELD
Excel.PivotField rowField = (Excel.PivotField)pivotTable.PivotFields("State");
rowField.Orientation = Excel.XlPivotFieldOrientation.xlRowField;
//ADDING DATA FIELD
pivotTable.AddDataField(pivotTable.PivotFields("SetupDate"), "average setup date", Excel.XlConsolidationFunction.xlAverage);
ExcelSaveAs(objApp, objBook, @"J:\WBK");
objApp.Quit();
}
catch (Exception e) {
objApp.Quit();
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
}
static string ExcelSaveAs(Excel.Application objApp, Excel.Workbook objBook, string path) {
try {
objApp.DisplayAlerts = false;
objBook.SaveAs(path, Excel.XlFileFormat.xlExcel7, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Excel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
objApp.DisplayAlerts = true;
return null;
}
catch (Exception e) {
StackTrace st = new StackTrace(new StackFrame(true));
StackFrame sf = st.GetFrame(0);
return (e.Message + "\n" + "Method" + sf.GetMethod().ToString() + "\n" + "Line" + sf.GetFileLineNumber().ToString());
}
}
static string GetConnectionStringByName(string name) {
//ASSUME FAILURE
string returnValue = null;
//Look for the name in the connectionStrings section
ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings[name];
// If found, return the connection string
if (settings != null) {
returnValue = settings.ConnectionString;
}
return returnValue;
}
}
}
这是一个用 VB 编写的代码,它允许我们为选定的Pivot Table 创建一个新的Pivot Cache:
Sub SelPTNewCache()
Dim wsTemp As Worksheet
Dim pt As PivotTable
On Error Resume Next
Set pt = ActiveCell.PivotTable
If pt Is Nothing Then
MsgBox "Active cell is not in a pivot table"
Else
Set wsTemp = Worksheets.Add
ActiveWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, _
SourceData:=pt.SourceData).CreatePivotTable _
TableDestination:=wsTemp.Range("A3"), _
TableName:="PivotTableTemp"
pt.CacheIndex = wsTemp.PivotTables(1).CacheIndex
Application.DisplayAlerts = False
wsTemp.Delete
Application.DisplayAlerts = True
End If
exitHandler:
Set pt = Nothing
End Sub
1.在您的asd.js 文件中有以下元素:
–s代表一个字符串值
– n 代表数值
– d 代表日期值
–x代表一个索引值
– v 表示一个值本身
那么,让我们用人类语言翻译此表的F2 单元格中包含的数据:
<x v="0"/>
0 的值是存储美国各州缩写的字符串数组中的 zero index。该数组中的第一个索引为我们检索Arizona。我不知道为什么下一行的单元格包含小写的az 而其他所有的单元格都包含大写的AZ,但我确定这与Shared Record 无关。
2.我没有找到任何关于 Excel 在内存中用于其 pivotCache 的内部 C/C++ 结构的有用信息。
最后:
3.这是一个LINK,在第三个额外问题中包含有关“帮助信息”的有用信息。
附言
关于大 O 表示法。
Big O notation 在计算机科学中用于描述算法的性能或复杂性。 Big O 专门描述了最坏的情况,可用于描述算法所需的执行时间或使用的空间(在内存中或磁盘上)。 Big O notation 是根据输入大小衡量程序复杂性的指标。
-
O(1) 表示无论输入数据集大小如何,始终同时执行的算法。
-
O(N) 表示性能线性增长且与输入数据集大小成正比的算法。
-
O(N*N) 表示其性能与输入数据集大小的平方成正比的算法。
-
T(N) = O(log N) 表示性能取决于对数时间的算法。取对数时间的算法常见于binary trees 的操作或使用二分搜索时。
但是好的排序算法是苛刻的O(N log N)。具有这种效率的算法示例可以是合并排序,它将一个数组分成两半,通过递归调用它们对这两半进行排序,然后将结果合并回来到单个数组中。
这是一个抽象的 C# 代码的 sn-p,展示了 O(N log N) 算法的工作原理(大致相同的方法可用于创建数据透视表):
public static int[] MergeSort(int[] inputItems, int lowerBound, int upperBound) {
if (lowerBound < upperBound) {
int middle = (lowerBound + upperBound) / 2;
MergeSort(inputItems, lowerBound, middle);
MergeSort(inputItems, middle + 1, upperBound);
int[] leftArray = new int[middle - lowerBound + 1];
int[] rightArray = new int[upperBound - middle];
Array.Copy(inputItems, lowerBound, leftArray, 0, middle - lowerBound + 1);
Array.Copy(inputItems, middle + 1, rightArray, 0, upperBound - middle);
int i = 0;
int j = 0;
for (int count = lowerBound; count < upperBound + 1; count++) {
if (i == leftArray.Length) {
inputItems[count] = rightArray[j];
j++;
}
else if (j == rightArray.Length) {
inputItems[count] = leftArray[i];
i++;
}
else if (leftArray[i] <= rightArray[j]) {
inputItems[count] = leftArray[i];
i++;
}
else {
inputItems[count] = rightArray[j];
j++;
}
}
}
return inputItems;
}