在 SSRS 2016 中按字符串定界的递归层次结构分组?

Recursive hierarchy grouping by string delimiting in SSRS 2016?

我有一个 SQL 服务器数据库作为我的数据源,我的行包含一个由 \

分隔的路径

例如:

"\Foo\Bar"

是一个包含

的文件夹

"\Foo\Bar\Baz".

我的数据库包含一个存储绝对路径的列,我想要一个基于文件夹到子文件夹的所有权的递归层次结构table。

我的数据是这样存储的:

+--------------+
| PATH         |
+--------------+
| \Foo         |
+--------------+
| \Foo\Bar     |
+--------------+
| \Foo\Bar\Baz |
+--------------+
| \Foo\Bar\Qux |
+--------------+
| \Foo2        |
+--------------+

我想这样表示

+----------+
| PATH     |
+----------+
| \Foo     |
+----------+
|   \Bar   |
+----------+
|     \Baz |
+----------+
|     \Qux |
+----------+
| \Foo2    |
+----------+

我已经为这个过程编写了一些有用的 CLR 存储过程:

一个允许我获取给定父路径的子路径(例如传入“\Foo\Bar”returns行“\Foo\Bar\Baz”和“\Foo\Bar \Qux")

另一个允许我提取路径的最底层名称(例如,从“\Foo\Bar\Baz”中提取“\Baz”)。

是否可以使用 SSRS Recursive Hierarchy Grouping Structure 以及我的数据存储方式以这种方式生成 table?或者此任务是否需要修改我的数据库模式?

我想通了。对于处于我位置的任何人,这就是你要做的:

使用您想要的值创建 table。

在您的路径字段上添加一个行组(或带有层次分隔符的等效字符串)。

右键单击新的行组并选择组属性。

在分层字段上添加新的组表达式组。

转到高级选项卡。

单击递归父项的表达式 (fx) 按钮。

在这里您将使用正则表达式来表示什么是父项。比如我的表达式是:

=System.Text.RegularExpressions.Regex.Match(Fields!Qualifier.Value, ".*(?=\\)").Value

其中"Qualifier"是字段名,我的分隔符是\字符。

为了适应您的使用,请将粗体字段名称更改为您的姓名,并将正则表达式父匹配模式更改为适合您的架构的模式。

=System.Text.RegularExpressions.Regex.Match(字段!限定符.值,“.*(?=\\)”)。值

我的正则表达式的演示是 here,它基本上获取了完整路径 减去 最后一个元素和分隔符。

如果有人对此有任何疑问,请随时提问。这是一个巨大的痛苦,因为没有这样的记录。

为了能够使用递归分组功能,您将需要一个 parent-child 层次结构,该层次结构可用于将父级与其子级连接起来。例如,您可以使用这样的查询,基于您的 table,它还将检索最后一个文件夹名称和父文件夹的路径(flen 是文件夹名称的长度):

SELECT [PATH]
  , RIGHT([PATH], p.flen) AS FOLDER
  , LEFT([PATH], LEN([PATH]) - p.flen) AS [PARENT]
FROM FolderTable
  CROSS APPLY (VALUES(CHARINDEX('\',REVERSE([PATH])))) p (flen);

返回的数据将如下所示:

然后您可以创建一个报告,根据上面的查询添加数据源和数据集。然后你可以在报告中添加一个table,它只需要有一列。在该列中显示数据集的字段 FOLDER

完成后,更改 Details 组(在行组下)的属性:

  • General 属性下,添加 PATH 字段作为 Group 表达式
  • Advanced 属性下,添加 PARENT 字段作为 Recursive parent

如果我们看一下结果,它看起来还不太好:

为了让子项稍微缩进一点,我们可以在表达式中使用 Level 函数来实现 Padding Left 属性 FOLDER TextBox (取自微软的例子):

=CStr(2 + (Level()*10)) + "pt"

现在,我想我们到达了我们想去的地方: