簡體   English   中英

自動加入以在Access 2010中創建組織層次結構

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

我正在嘗試使用Access 2010創建員工組織層次結構。我的基本表包含有關員工的信息,包括他們的直接經理。 理想情況下,我想創建一個包含每個報告級別的表。 該查詢的凈輸出將是一個包含所有者,所有者和所有者與所有者之間關系深度的表。

我的數據表可以歸納為:

擁有的EE ID
直接所有者ID

我要創建的凈輸出是這樣的表:

Owner | Owned | Levels between Owner and Owned

例如,假設約翰向喬報告,喬向簡報告。 我的結構將是:

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

我知道在樹的頂部(CEO)和樹的底部(小時工peon)之間走不超過11​​個深度。

在Access SQL中可以做這種事情嗎? 理想情況下,我不希望編寫宏,但是如果需要的話,我會寫宏。 我可以從下至上或從上至下構建,我真的不在乎,但是我是從上至下在Excel中構建測試文件的,因此自上而下的創建更容易,因為我先是從沒有直接經理(首席執行官)。

如果有問題,我是Access的相對n00b。 謝謝。

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

...並填充名為[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

...像這樣:

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