Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>So the link table gives a self join to doc, you absolutely need a doc to be able to:</p> <ol> <li>Link to itself </li> <li>... as many times as it likes</li> <li>Link to another doc</li> <li>... multiple times</li> <li>Be separately linked to by the same other doc</li> <li>... multiple times</li> <li>Store information about the link</li> </ol> <p>So your link table could have 10 separate links 1-1, 1-1, 1-1, 1-2, 1-2, 1-2, 2-1, 2-1, 2-1, 2-2 etc. with just 2 docs in the 'family'.</p> <hr> <p>I expect when you look at this list you will probably think that you don't need most of them, a lot of the inefficiency in your solution might be coming from this unnecessary flexibility. My favoured suggestion would be to start with a strict hierarchy and build minimally from there.</p> <p>But here is my answer anyway, it's tested and working in Access-2010 and local tables. ADODB should work just as well with linked tables. </p> <pre><code>Option Compare Database Option Explicit Const MaxInFamily = 30 'Requires a reference to "Microsoft ActiveX Data Objects 2.x Library" (VBA Menu: Tools, references) Function GetFamily(id As Long) As Long() Dim Found(MaxInFamily) As Long Dim MaxFound As Integer Dim CurrentSearch As Integer Dim Sql As String Dim rs As New ADODB.Recordset Found(1) = id MaxFound = 1 For CurrentSearch = 1 To MaxInFamily If CurrentSearch &gt; MaxFound Then Exit For Sql = "SELECT doc_id_2 as NewID FROM link WHERE doc_id_1 = " &amp; Found(CurrentSearch) _ &amp; " AND doc_id_2 NOT IN (" &amp; ArrayToCsv(Found, MaxFound) &amp; ")" _ &amp; " UNION " _ &amp; " SELECT doc_id_1 FROM link WHERE doc_id_2 = " &amp; Found(CurrentSearch) _ &amp; " AND doc_id_1 NOT IN (" &amp; ArrayToCsv(Found, MaxFound) &amp; ")" rs.Open Sql, CurrentProject.Connection Do While Not rs.EOF MaxFound = MaxFound + 1 Found(MaxFound) = rs("NewID").Value rs.MoveNext Loop rs.Close Next CurrentSearch GetFamily = Found End Function Function ArrayToCsv(SourceArray() As Long, ItemCount As Integer) As String Dim Csv As String Dim ArrayIndex As Integer For ArrayIndex = 1 To ItemCount Csv = Csv &amp; SourceArray(ArrayIndex) If ArrayIndex &lt; ItemCount Then Csv = Csv &amp; ", " Next ArrayIndex ArrayToCsv = Csv End Function </code></pre> <p>Duplicated results and queries are avoided by excluding items already found at the server, and as the link is unidirectional I've used a <code>UNION</code> query to look both ways at once. At most it'll do <code>MaxInFamily</code> round trips to the server.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload