简体   繁体   English

自动加入以在Access 2010中创建组织层次结构

[英]Self join to create org hierarchy in Access 2010

I am trying to create an employee org hierarchy using Access 2010. My basic table contains information about the employee, including their direct manager. 我正在尝试使用Access 2010创建员工组织层次结构。我的基本表包含有关员工的信息,包括他们的直接经理。 Ideally, I'd like to create a single table that contains every level of reporting. 理想情况下,我想创建一个包含每个报告级别的表。 The net output of this query would be a table that contains the owner, the owned, and the depth of the relationship between the owner and the owned. 该查询的净输出将是一个包含所有者,所有者和所有者与所有者之间关系深度的表。

My data table can be summarized down to: 我的数据表可以归纳为:

Owned EE ID 拥有的EE ID
Direct Owner ID 直接所有者ID

The net output I'd like to create is a table like this: 我要创建的净输出是这样的表:

Owner | Owned | Levels between Owner and Owned

As an example, suppose John reports into Joe who reports into Jane. 例如,假设约翰向乔报告,乔向简报告。 My structure would then be: 我的结构将是:

Joe  | John | 1
Jane | Joe  | 1
Jane | John | 2

I know that I will not go more than 11 levels deep between the top of my tree (the CEO) and the bottom of my tree (hourly worker peon). 我知道在树的顶部(CEO)和树的底部(小时工peon)之间走不超过11​​个深度。

Is such a thing possible to do in Access SQL? 在Access SQL中可以做这种事情吗? Ideally I'd prefer not to write a macro but I will if I have to. 理想情况下,我不希望编写宏,但是如果需要的话,我会写宏。 I can build from the bottom up or the top down, I really don't care, but I built my test file in Excel from the top down, and it's easier to start top down, since I'd start with the EE who does not have a direct manager (the CEO). 我可以从下至上或从上至下构建,我真的不在乎,但是我是从上至下在Excel中构建测试文件的,因此自上而下的创建更容易,因为我先是从没有直接经理(首席执行官)。

I am a relative n00b to Access, if that matters. 如果有问题,我是Access的相对n00b。 Thank you. 谢谢。

Access SQL does not support recursion (like recursive CTEs in SQL Server), but the following VBA code will take an input table named [Employees]... Access SQL不支持递归(例如SQL Server中的递归CTE),但是以下VBA代码将采用名为[Employees]的输入表。

ID  EmployeeName    ReportsTo
--  ------------    ---------
1   Jane    
2   Joe             1
3   John            2
4   Julia           2
5   Jack            4
6   Jimbo           2
7   Jill            5

...and populate a table named [EmployeeHierarchy]... ...并填充名为[EmployeeHierarchy]的表...

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: ...像这样:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM