作为我项目之一的一部分,我需要将单元集转换为数据表。如果此方法的调用者可以指定需要哪些维度作为列以及哪些维度需要用于行,这对于度量也是一样的,那就太好了。任何指针?
2 回答
我最近需要在我的项目中执行 MDX 查询,这严重依赖于 ADO 数据集和数据表。实际上,要求是能够在执行 MDX 查询时或多或少地看到我在 SSMS 中看到的内容。
例如,当这个 mdx 在 AdventureWorks 数据库中执行时
select
{[Sales Territory].[Sales Territory].[Country].&[France]} on columns,
[Product].[Category].[All Products] on Rows
from
[Adventure Works]
我们得到的结果集是:
| France
=====================================
All Products | $4,607,537.94
对于此结果,将创建一个包含单个数据行的两列数据表。第二列中的“France”值是其标题,而不是列名。
我使用此函数将单元集转换为数据表。未提供函数 GetColumnName(num) 根据传递的 num 整数值返回列的名称。
Function Cellset2Datatable(ByVal cs As CellSet) As DataTable
Dim dt As New DataTable
Dim dc As DataColumn
Dim dr As DataRow
Dim i, j As Integer
Dim num As Integer = 0
Dim nNumberOfGroupingColumns As Integer = 0
If cs.Axes.Count > 1 Then
For Each m As Member In cs.Axes(1).Positions(0).Members
num += 1
dc = New DataColumn
dc.ColumnName = GetColumnName(num)
dt.Columns.Add(dc)
nNumberOfGroupingColumns += 1
Next
End If
Dim sCaption As String
For Each p As Position In cs.Axes(0).Positions
sCaption = ""
For Each m As Member In p.Members
If sCaption.Equals("") Then
sCaption = String.Format("[{0}]", m.Caption.Trim)
Else
sCaption = String.Format("{0} / [{1}]", sCaption, m.Caption.Trim)
End If
Next
num += 1
dc = New DataColumn
dc.ColumnName = GetColumnName(num)
dc.Caption = sCaption
dt.Columns.Add(dc)
Next
'import data
Dim x As Integer, y As Integer
Dim py As Position
If nNumberOfGroupingColumns > 0 Then
For y = 0 To cs.Axes(1).Positions.Count - 1
py = cs.Axes(1).Positions(y)
i = 0
dr = dt.NewRow
For Each m As Member In py.Members
dr.Item(i) = m.Caption
i += 1
Next
For x = 0 To cs.Axes(0).Positions.Count - 1
dr.Item(i) = cs(x, y).Value
i += 1
Next
dt.Rows.Add(dr)
Next
Else
dr = dt.NewRow
For i = 0 To cs.Axes(0).Positions.Count - 1
dr.Item(i) = cs(i).Value
Next
dt.Rows.Add(dr)
End If
Return dt
End Function
首先,添加列。进行检查以查看垂直轴上是否存在任何“分组”列,在这种情况下添加相应的列:
If cs.Axes.Count > 1 Then
For Each m As Member In cs.Axes(1).Positions(0).Members
num += 1
dc = New DataColumn
dc.ColumnName = GetColumnName(num)
dt.Columns.Add(dc)
nNumberOfGroupingColumns += 1
Next
End If
下一步是添加对应于水平轴的列
For Each p As Position In cs.Axes(0).Positions
sCaption = ""
For Each m As Member In p.Members
If sCaption.Equals("") Then
sCaption = String.Format("[{0}]", m.Caption.Trim)
Else
sCaption = String.Format("{0} / [{1}]", sCaption, m.Caption.Trim)
End If
Next
num += 1
dc = New DataColumn
dc.ColumnName = GetColumnName(num)
dc.Caption = sCaption
dt.Columns.Add(dc)
Next
此步骤中的列标题用于存储所有级别值。例如 [Accessories].[France].[Internet Order Count] 变为 [Accessories] / [France] / [Internet Order Count]。最后一步是将数据导入数据表。这两种情况都在这里处理:“分组”列是否存在。
该函数不处理存在两个以上轴的情况。
我在分析服务和 MDX 方面的经验有限,我只是研究了项目需求所需的内容,因此我对我对概念的“简单”描述表示歉意。
如果在您的项目中使用XMLA,您可以在 2 种格式之间进行选择:多维数据集或表格行集。
多维数据集:
这种格式会给你一个cellset(你已经知道了)。
表格行集:
这个应该更容易转换成数据表。