Ms access 在物料清单中查找起始部件处于Access中的最终项目的方法是什么?阵列?递归函数?

Ms access 在物料清单中查找起始部件处于Access中的最终项目的方法是什么?阵列?递归函数?,ms-access,vba,ms-access-2016,Ms Access,Vba,Ms Access 2016,我正在寻找一种开始的方法,不一定是一个完整的解决方案。我的问题是如何构造一个程序,该程序采用零件号并在物料清单中逐级递增,检查下一个更高的组件是否列在单独的表中,同时仍记住用户输入的第一个零件号?我已经包括了示例数据以及该程序在我心目中的工作方式 我相信我需要使用数组或某种递归函数。我真的不知道除了SQL之外,找到下一个更高的程序集的最佳方法是什么 我有一个表,上面有零件号和下一个更高的组件,如图所示,该表给出了各种零件号的物料清单,称为tbl_PartandNHA: Part Number N

我正在寻找一种开始的方法,不一定是一个完整的解决方案。我的问题是如何构造一个程序,该程序采用零件号并在物料清单中逐级递增,检查下一个更高的组件是否列在单独的表中,同时仍记住用户输入的第一个零件号?我已经包括了示例数据以及该程序在我心目中的工作方式

我相信我需要使用数组或某种递归函数。我真的不知道除了SQL之外,找到下一个更高的程序集的最佳方法是什么

我有一个表,上面有零件号和下一个更高的组件,如图所示,该表给出了各种零件号的物料清单,称为tbl_PartandNHA:

Part Number NHA
Part A  Part L
Part A  Part M
Part L  Part S
Part M  Part S
Part M  Part R
Part S  Part Y
Part S  Part Z
Part R  Part Y
Part B  Part N
Part N  Part Q
Part Q  Part W
我还有另一个表,其中列出了符合某些标准的零件号。我称之为tbl_PartMeetCriteria

零件符合标准

Part Z
Part Q
对于W部分,物料清单如下所示:

Part W
    Part Q
        Part N
            Part B
该程序将获得一个零件号,并在材料清单中查找tbl_PartMeetSciteria中列出的零件号。该算法的工作原理如下:查找B部分的NHA。NHA是N部分。检查tbl_PartMeetCriteria中的N部分。它不在表中,所以请找到NHA。这是Q部分。请检查tbl_PartMeetsCriteria中的Q部分。它在桌子上。停止例程并显示msgbox“Part Q在表中。Part B构建Part Q”。实际上,我的程序将把匹配存储在其他位置

现在我们有A部分要分析。A部分的材料清单写在这里

Part Y
    Part S
        Part L
            Part A
        Part M
            Part A  
    Part R
        Part M
            Part A
Part Z
    Part S
        Part L
            Part A
        Part M
            Part A
该计划将看到A部分有两个国家公路局(L部分,M部分)。该程序将在tbl_PartMeetSciteria中检查每一项。然后,该计划必须扩展。它必须先查找M部分的NHA,然后再查找R部分的NHA。它将在没有匹配项的情况下出现。然后,它必须返回并检查第一部分的NHA,然后检查第二部分的NHA,以在tbl_PartMeetsCriteria中查找匹配项。S部分的NHA是Y部分和Z部分。程序将找到与Z部分匹配的部分,并说“Z部分在表中。a部分构建Z部分”

我的问题是,我如何构建一个程序,该程序可以在物料清单的每个选项上查找匹配项

我将其视为一系列嵌套数组,如下所示:

Part W
    Part Q
        Part N
            Part B
A部分(L部分(S部分(Y部分,Z部分)),M部分(R部分(Y部分),S部分(Y部分,Z部分)))


我了解如何使用SQL查询某些内容。我了解数组和FOR循环的基本知识,但我不知道这是否是正确的方法。问题在于,示例数据是物料清单的简化版本。有数千个连接和更多级别,具体取决于较低的零件号。程序将需要数组中的动态数组来存储选项,并研究下一个更高程序集的每个可能线程,直到找到匹配或达到最高级别。我怎么能这样做?有比数组更好的选择吗?

真正关心的是允许您编辑源数据的方式。循环引用将导致无限递归,这就是为什么任何递归设置都不允许直接输入。任何输入都必须经过验证

无论如何,这里有一些使用VBA的递归示例,然后是问题的答案,您可以在这里阅读和展开以满足您的需要

下面的代码将递归搜索下一个元素,直到找不到下一个元素为止。 F(x)=F(F(x))


你应该知道这只是一个概念的证明。您可以使用它来了解VBA的递归功能,但在实现它之前必须采取额外的安全措施。您可以使用子函数缩短几行代码。我把更大的版本留给你去理解。递归深度由您来实现。

Access(JET/Ace)SQL不执行递归或循环。至于VBA解决方案,这个问题太广泛了。有很多方法可以解决这个问题,还有数组的替代方法,比如对象和集合。你能给一些关于对象和集合的提示吗?比如一些资源或链接。这会很有帮助。看看Joe Celko的例子,对象是面向对象编程语言中编程的核心概念。是一个非常基础的youtube教程,涵盖了一些基础知识。然而,为了进一步理解,我可以推荐一门关于面向对象编程的完整课程,以及OOP中的家长和孩子。有关集合,请参见此处了解VBA中带记录集的基本递归:非常感谢!这将需要一些时间来研究和实施,但它非常有用。
Public Function RecursiveSingleNodeFindMeet(PartNumber As String, Optional NHA As String, Optional recursionDepth As Integer) As String

    On Error Resume Next
    If PartNumber = "" Then Exit Function

    If (Nz(DLookup("partnumber", "PartMeetsCriteria", "partnumber='" & PartNumber & "'"), "") <> "") Then
        RecursiveSingleNodeFindMeet = Nz(DLookup("partnumber", "PartMeetsCriteria", "partnumber='" & PartNumber & "'"), "")
    Else
        RecursiveSingleNodeFindMeet = RecursiveSingleNodeFindMeet(Nz(DLookup("nha", "tbl_PartandNHA", "partnumber='" & PartNumber & "'"), ""))

    End If

End Function
Public Function FindNHA(PartNumber As String)

    Dim SQL_GET As String
    SQL_GET = "SELECT * FROM tbl_PartandNHA WHERE(partnumber like '" & PartNumber & "')"

    Dim MyRs As Recordset
    Set MyRs = CurrentDb.OpenRecordset(SQL_GET)
    If Not (MyRs.BOF Or MyRs.EOF) Then

        Dim Result As String

        While Not MyRs.EOF
            'Recursive method to find the part matching in partmeetcriteria table
            Result = FindNHAR(Nz(MyRs("partnumber"), ""), Nz(MyRs("nha"), ""))
            If (Result <> "") Then
                FindNHA = Result
                Exit Function
            End If

            MyRs.MoveNext
        Wend
    End If
End Function



Public Function FindNHAR(PartNumber As String, Optional NHA As String, Optional recursionDepth As Integer) As String
    'Recursively search for next element and check if it's found in your PartMeetsCriteria. Return blank if not

    On Error Resume Next
    If PartNumber = "" Then Exit Function

    If (Nz(DLookup("partnumber", "PartMeetsCriteria", "partnumber='" & PartNumber & "'"), "") <> "") Then
        ' if partnumber is found in meetsCriteria table return it
        FindNHAR = Nz(DLookup("partnumber", "PartMeetsCriteria", "partnumber='" & PartNumber & "'"), "")
    ElseIf (Nz(DLookup("partnumber", "PartMeetsCriteria", "partnumber='" & NHA & "'"), "") <> "") Then
            ' if NHAis found in meetsCriteria table return it
        FindNHAR = Nz(DLookup("partnumber", "PartMeetsCriteria", "partnumber='" & NHA & "'"), "")
    Else
        If Not NHA = "" Then
            'For each element, check if it has multiple nodes and search each element in each node again, starting with NHA
            FindNHAR = FindNHA(NHA)
        Else
'Same as above since NHA is empty, use partnumber
            FindNHAR = FindNHAR(Nz(DLookup("nha", "tbl_PartandNHA ", "partnumber='" & PartNumber & "'"), ""))
        End If

    End If

End Function
?FindNHA("Part S") Part Z
?FindNHA("Part A") Part Z
?FindNHA("Part B") Part Q
?FindNHA("Part R") ""
?FindNHA("Part M") Part Z
?FindNHA("Part N") Part Q