将CellSet转换为DataTable

时间:2012-09-07 01:18:10

标签: datatable mdx

作为我项目的一部分,我需要将cellset转换为数据表。如果此方法的调用者可以指定哪些维度作为列以及哪些行是行所需的,那么这将是非常好的,对于度量也是如此。有什么指针吗?

2 个答案:

答案 0 :(得分:3)

我最近需要在我的项目中执行MDX查询,该查询严重依赖于ADO数据集和数据表。实际上,要求是在执行MDX查询时能够看到我在SSMS中看到的更多或更少。

例如,当在AdventureWorks数据库中执行此mdx时

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

对于此结果,将创建包含两个列的数据表,其中包含单个数据行。 "法国"第二列中的值是其标题,而不是列名。

我使用此函数将单元格转换为数据表。未提供函数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

此步骤中的列标题用于存储所有级别值。例如 [附件]。[法国]。[互联网订单计数]变为[附件] / [法国] / [互联网订单计数]。 最后一步是将数据导入数据表。这两种情况都在这里处理:是否"分组"列存在与否。

该功能不处理存在两个以上轴的情况。

我在分析服务和MDX方面的经验是有限的,我刚刚研究了项目要求所需的内容,所以我为我的"简单化"而道歉。关于概念的描述。

答案 1 :(得分:0)

如果在您的项目中使用XMLA,您可以选择2种格式:多维数据集表格行集

  • 多维数据集:

    这种格式会给你一个单元格(你已经知道了)。

  • 表格行集:

    这个应该更容易转换为数据表。