UiPath中使用VB.NET LINQ按多列分组:同名董事归组问题
UiPath中VB.NET LINQ实现跨行跨列的董事分组
需求说明
需按Group Name和5个董事列(Director1Name至Director5Name)分组:只要不同行的任意董事列出现相同姓名,这些行就归为同一组,分组后需显示该关联董事姓名。
示例数据
| Group Name | Director1Name | Director2Name | Director3Name | Director4Name |
|---|---|---|---|---|
| Group A | Sam k | John D | Ben W | Reddy P |
| Group A | Matt R | Katt D | Sam k | Catty P |
示例中两行因共同包含Sam k,需归为同一组,分组后显示Sam k作为关联董事。
原代码问题
你写的LINQ仅在单行内判断董事重复,无法识别跨行跨列的相同董事关联,导致符合条件的行无法归为同一组。
解决方案
以下是适配需求的VB.NET实现,可直接在UiPath的Assign活动中使用:
' 第一步:建立(Group Name, 董事姓名)到对应行的映射,同一行的每个董事都关联到该行 Dim directorRowMap = ( From row In dt_MasterListFiltered Let groupName = row("Group Name").ToString().Trim() Let directors = New List(Of String) From { row("Director1Name").ToString().Trim(), row("Director2Name").ToString().Trim(), row("Director3Name").ToString().Trim(), row("Director4Name").ToString().Trim(), row("Director5Name").ToString().Trim() }.Where(Function(d) Not String.IsNullOrWhiteSpace(d)) ' 过滤空董事姓名 From director In directors Select New With {.GroupName = groupName, .Director = director, .Row = row} ).GroupBy(Function(x) New With {x.GroupName, x.Director}) .ToDictionary(Function(g) g.Key, Function(g) g.Select(Function(x) x.Row).ToList()) ' 第二步:遍历映射,聚合所有关联行(通过董事关联的所有行归为一组) Dim processedRows = New HashSet(Of DataRow)() Dim groupedResults = New List(Of Object)() For Each kvp In directorRowMap Dim groupKey = kvp.Key Dim initialRows = kvp.Value ' 跳过已处理过的行组 If initialRows.All(Function(r) processedRows.Contains(r)) Then Continue For ' 收集当前组所有关联的行 Dim allAssociatedRows = New HashSet(Of DataRow)(initialRows) Dim tempRows = New List(Of DataRow)(initialRows) Do While tempRows.Count > 0 Dim currentRow = tempRows(0) tempRows.RemoveAt(0) ' 找到当前行所有董事对应的行,加入关联集合 Dim currentDirectors = New List(Of String) From { currentRow("Director1Name").ToString().Trim(), currentRow("Director2Name").ToString().Trim(), currentRow("Director3Name").ToString().Trim(), currentRow("Director4Name").ToString().Trim(), currentRow("Director5Name").ToString().Trim() }.Where(Function(d) Not String.IsNullOrWhiteSpace(d)) For Each dir In currentDirectors Dim key = New With {.GroupName = groupKey.GroupName, .Director = dir} If directorRowMap.ContainsKey(key) Then For Each r In directorRowMap(key) If allAssociatedRows.Add(r) Then tempRows.Add(r) End If Next End If Next Loop ' 标记这些行为已处理,避免重复分组 processedRows.UnionWith(allAssociatedRows) ' 提取当前组所有去重后的董事姓名 Dim allDirectors = allAssociatedRows.SelectMany(Function(r) New List(Of String) From { r("Director1Name").ToString().Trim(), r("Director2Name").ToString().Trim(), r("Director3Name").ToString().Trim(), r("Director4Name").ToString().Trim(), r("Director5Name").ToString().Trim() }).Where(Function(d) Not String.IsNullOrWhiteSpace(d)).Distinct() ' 按需求构造结果行并添加到列表 For Each director In allDirectors groupedResults.Add({ groupKey.GroupName, director, String.Join(", ", allAssociatedRows.Select(Function(r) String.Join("-", r.ItemArray))) }) Next Next ' 将结果填充到目标数据表 dt_GroupedMasterlist.Rows.Clear() For Each item In groupedResults dt_GroupedMasterlist.Rows.Add(item) Next
代码逻辑说明
- directorRowMap:快速定位某Group下某董事对应的所有行,为跨行关联查找做准备。
- 关联行聚合:通过循环遍历,把所有通过董事关联的行聚合到同一组,确保不会遗漏任何跨行关联的情况。
- 结果整理:对每个关联组提取去重后的董事姓名,按需求构造目标行,确保每个关联董事都对应完整的行集合。
注意事项
- 代码过滤了空的董事姓名,避免空值干扰分组逻辑。
- 使用
HashSet处理行的去重,确保同一行不会被重复处理。 - 需提前确保目标数据表
dt_GroupedMasterlist已创建对应列(Group Name、Director Name、关联行数据)。
内容的提问来源于stack exchange,提问作者zamceaser
相关产品推荐
相关产品推荐

