经过一天的研究,我以为我的问题就在最后。我让自己全都学习了递归查询,并设法让它在SQL Server Management Studio 2014中执行得非常漂亮。但是,在将我在SQL Server 2014中编写的查询转换为Access 2013应用程序时,我立即被击落。阅读其他文章,我现在明白Access不支持递归查询。有了这个,我需要帮助找到一种资源有效的方法来提取这些记录并将它们放入数组变量中。我过去在VBA中模仿这一点的努力是可怕的;导致处理30-60秒。任何有关如何利用这一过程的建议将不胜感激。
我想模仿的递归查询是:
WITH MyCTE(BusinessUnitID, Active)
AS(
SELECT a.BusinessUnitID, a.Active
FROM t_EMS_BM_BusinessUnits AS a
WHERE BusinessUnitID = 7
UNION ALL
SELECT d.BusinessUnitID, d.Active
FROM MyCTE AS c
INNER JOIN t_EMS_BM_BusinessUnits AS d
ON c.BusinessUnitID = d.ParentUnit)
SELECT *
FROM MyCTE
WHERE Active = 1
我糟糕的VBA脚本是:
Private Sub LoadArray(intBU As Integer)
'set rollup data for business unit by adding all child units to intBUs array
Dim sql As String
Dim rs As Recordset
Dim intCount As Integer
sql = "SELECT BusinessUnitID, ParentUnit FROM t_EMS_BM_BusinessUnits WHERE Active = true ORDER BY BusinessUnitID"
Set rs = currentdb.OpenRecordset(sql, dbOpenDynaset, dbSeeChanges)
'look for child units
With rs
intCount = 0
ReDim intBUs(1 To 1) As Integer
If Not .EOF And Not .BOF Then
.MoveLast
.MoveFirst
Do While Not .EOF
If IsChild(intBU, !BusinessUnitID) = True Then
'add to array
intCount = intCount + 1
If intCount > 1 Then
ReDim Preserve intBUs(1 To UBound(intBUs) + 1) As Integer
intBUs(UBound(intBUs)) = !BusinessUnitID
ElseIf intCount = 1 Then
intBUs(UBound(intBUs)) = !BusinessUnitID
End If
End If
.MoveNext
Loop
End If
.Close
End With
Set rs = Nothing
Private Function IsChild(TargetBU, CurrentBU As Integer) As Boolean
'check if unit is lowest level child
'is TargetBU a child of CurrentBU?
Dim intX As Integer
Dim intCount As Integer
intX = 0
If TargetBU = CurrentBU Then
'return a value of true
IsChild = True
Else
Do Until intX = -1
'find bottom level of heiarchy
intCount = DCount("BusinessUnitID", "t_EMS_BM_BusinessUnits", "ParentUnit=" & CurrentBU)
If intCount = 0 Then
intX = -1
Else
CurrentBU = DLookup("BusinessUnitID", "t_EMS_BM_BusinessUnits", "ParentUnit=" & CurrentBU)
intX = 0
End If
Loop
'reset sentinal value
intX = 0
Do Until intX = -1
'tree up until the record matches the TargetBU or reaches the top "0"
If CurrentBU = TargetBU Or CurrentBU = 0 Then
IsChild = True
intX = -1
Else
'move up to the next level
CurrentBU = Nz(DLookup("ParentUnit", "t_EMS_BM_BusinessUnits", "BusinessUnitID = " & CurrentBU), 0)
IsChild = False
intX = 0
End If
Loop
End If
End Function