首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自连接在Access 2010中创建组织层次结构

自连接在Access 2010中创建组织层次结构
EN

Stack Overflow用户
提问于 2013-08-27 18:47:26
回答 1查看 3.9K关注 0票数 1

我正在尝试使用Access 2010创建一个雇员组织层次结构。我的基本表包含有关员工的信息,包括他们的直接经理。理想情况下,我希望创建一个包含每个级别报告的表。此查询的净输出将是一个表,其中包含所有者、所有者和所有者之间关系的深度。

我的数据表可以归纳为:

自有EE ID

直接所有者ID

我想要创建的净输出是这样一个表:

代码语言:javascript
复制
Owner | Owned | Levels between Owner and Owned

举个例子,假设约翰向乔报告,而乔向简报告。我的结构是:

代码语言:javascript
复制
Joe  | John | 1
Jane | Joe  | 1
Jane | John | 2

我知道,在我的树顶(首席执行官)和我的树底(每小时工作人员)之间,我不会超过11个层次。

在Access SQL中可以这样做吗?理想情况下,我宁愿不写宏,但如果有必要,我会写的。我可以自下而上或自上而下地构建,我真的不在乎,但是我从上到下构建了我的Excel测试文件,而且自上而下地开始更容易,因为我会从没有直接经理( CEO)的EE开始。

我是一个相对的n00b访问,如果这是重要的。谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-29 15:38:24

Access SQL不支持递归(如Server中的递归CTE),但下面的VBA代码将接受一个名为Employees的输入表.

代码语言:javascript
复制
ID  EmployeeName    ReportsTo
--  ------------    ---------
1   Jane    
2   Joe             1
3   John            2
4   Julia           2
5   Jack            4
6   Jimbo           2
7   Jill            5

...and填充一个名为EmployeeHierarchy的表..。

代码语言:javascript
复制
Superior    Subordinate LevelDifference
--------    ----------- ---------------
Jane        Joe         1
Joe         John        1
Jane        John        2
Joe         Julia       1
Jane        Julia       2
Julia       Jack        1
Joe         Jack        2
Jane        Jack        3
Jack        Jill        1
Julia       Jill        2
Joe         Jill        3
Jane        Jill        4
Joe         Jimbo       1
Jane        Jimbo       2

...like so:

代码语言:javascript
复制
Option Compare Database
Option Explicit

Sub OrgTree()
    Dim cdb As DAO.Database, rstTop As DAO.Recordset
    Set cdb = CurrentDb
    cdb.Execute "DELETE FROM EmployeeHierarchy", dbFailOnError
    Set rstTop = cdb.OpenRecordset( _
            "SELECT ID, EmployeeName " & _
            "FROM Employees " & _
            "WHERE ReportsTo IS NULL", _
            dbOpenSnapshot)
    ' process each top-level entity
    Do While Not rstTop.EOF
        ProcessSubordinates rstTop!ID, rstTop!EmployeeName, 0
        rstTop.MoveNext
    Loop
    rstTop.Close
    Set rstTop = Nothing
    Set cdb = Nothing
End Sub

Sub ProcessSubordinates(BaseID As Long, BaseName As String, RecursionLevel As Long)
    Dim rstSubs As DAO.Recordset
    Dim i As Long, CurrentID As Long, SuperiorID As Long, SuperiorName As String
    Set rstSubs = CurrentDb.OpenRecordset( _
            "SELECT ID, EmployeeName " & _
            "FROM Employees " & _
            "WHERE ReportsTo = " & BaseID, _
            dbOpenSnapshot)
    ' loop through immediate subordinates for the "base" employee
    Do While Not rstSubs.EOF
        AddToEmployeeHierarchy BaseName, rstSubs!EmployeeName, 1

        ' traverse back up the tree to list all other superiors
        CurrentID = BaseID
        For i = 1 To RecursionLevel
            SuperiorID = DLookup("ReportsTo", "Employees", "ID = " & CurrentID)
            SuperiorName = DLookup("EmployeeName", "Employees", "ID = " & SuperiorID)
            AddToEmployeeHierarchy SuperiorName, rstSubs!EmployeeName, i + 1
            CurrentID = SuperiorID
        Next

        ' and recurse to process down the tree for the current subordinate
        ProcessSubordinates rstSubs!ID, rstSubs!EmployeeName, RecursionLevel + 1
        rstSubs.MoveNext
    Loop
    rstSubs.Close
    Set rstSubs = Nothing
End Sub

Sub AddToEmployeeHierarchy(SuperiorName As String, SubordinateName As String, LevelDifference As Long)
    Dim rst As DAO.Recordset
    Set rst = CurrentDb.OpenRecordset("EmployeeHierarchy", dbOpenTable)
    rst.AddNew
    rst!Superior = SuperiorName
    rst!Subordinate = SubordinateName
    rst!LevelDifference = LevelDifference
    rst.Update
    rst.Close
    Set rst = Nothing
End Sub
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18473211

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档