0

作为我项目之一的一部分,我需要将单元集转换为数据表。如果此方法的调用者可以指定需要哪些维度作为列以及哪些维度需要用于行,这对于度量也是一样的,那就太好了。任何指针?

4

2 回答 2

3

我最近需要在我的项目中执行 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 方面的经验有限,我只是研究了项目需求所需的内容,因此我对我对概念的“简单”描述表示歉意。

于 2014-05-12T14:24:50.237 回答
0

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

  • 多维数据集:

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

  • 表格行集:

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

于 2012-09-08T09:21:45.000 回答