在使用Excel时,我总是对Excel进行以下两个聚合操作的效果感到惊讶:
Excel如何实现该性能?它们是否存储其他数据结构以用于与枢轴相关的信息和聚合?是否在任何地方或在哪里可以找到更多有关此文档的信息?我已经看过Libreoffice的源代码,但是实际产品在聚合/数据透视性能上甚至不接近Excel。
如果了解Excel的人可以分享更多有关Excel为实现此性能而使用的低级聚合行为或结构的信息,例如,他们是否两次存储了任何标签,都可以在其本机中共享一次案例,并曾经降低以进行汇总?虽然我知道这个问题过于笼统,而不是关于代码答案本身,而是从概念上讲,但我希望答案可以为在excel样式的聚合上优化性能的方法提供良好的参考。
根据ARGeo的一些建议,我注意到了几件事-
(1)有两个与数据透视缓存有关的文件-定义(字段级信息):
(2)和记录(行/单元格级别信息)-
然后有几个问题:
Struct
上是否有任何信息供Excel使用内存用于其ivotCache(而不是作为存储的各种XML文档)?。
<cacheField name="numEmps" numFmtId="0"><sharedItems containsString="0" containsBlank="1" containsNumber="1" containsInteger="1" minValue="0" maxValue="20000"/></cacheField>
答案 0 :(得分:8)
数据透视表的效果基于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
。毕竟,数据透视缓存只是源数据的重复,因此有意义的是文件大小可能会加倍。
此外,您可以阅读Pivot Cache in Excel 101和Excel Pivot Cache 101帖子,以了解其含义和副作用。
以下是一些VB代码段以及如何使用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 Cache
创建一个新的Pivot Table
:
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。。我没有发现内部C / C ++ Struct的任何有用信息,Excel对其透视缓存使用内存。
最后,
3。。这是一个LINK,其中包含有关第三个问题的“帮助者信息”的有用信息。
P.S。
关于大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#代码段,显示了 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;
}
答案 1 :(得分:4)
PivotCache Class PivotCache。将对象序列化为 xml,其合格名称为x:pivotCache。
PivotCache Members (Excel)代表 数据透视表报表。
表示一个基类,该基类包含Office Open XML中的所有元素 文档源自。
OpenXML specification是又大又复杂的野兽。
cacheField (PivotCache Field)代表 PivotCache。此定义包含有关该字段的信息, 例如其来源,数据类型和级别内的位置,或 层次结构。 sharedItems元素存储其他信息 关于此字段中的数据。如果没有共享项目,则 值直接存储在pivotCacheRecords部分中。
定义SharedItems Class。当对象被序列化时 作为xml,其限定名称为x:sharedItems。