Таким образом, таблица ссылок дает самостоятельное соединение с документом, вам абсолютно необходим документ, чтобы иметь возможность:
- Ссылка на себя
- ... столько раз, сколько оналайки
- Ссылка на другой документ
- ... несколько раз
- Отдельно связана с тем же другим документом
- ... несколько раз
- Хранить информацию о ссылке
Таким образом, ваша таблица ссылок может иметь 10 отдельных ссылок 1-1, 1-1, 1-1, 1-2, 1-2, 1-2, 2-1, 2-1, 2-1, 2-2 и т. Д. С двумя документами в «семье».
Я ожидаю, что когда вы посмотрите на этот список, вы, вероятно, подумаете, чтовам не нужно большинство из них, большая часть неэффективности вашего решения может быть вызвана этой ненужной гибкостью.Моим любимым предложением было бы начать со строгой иерархии и минимально строить оттуда.
Но в любом случае, вот мой ответ, он протестирован и работает в Access-2010 и локальных таблицах.ADODB должен так же хорошо работать со связанными таблицами.
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 > MaxFound Then Exit For
Sql = "SELECT doc_id_2 as NewID FROM link WHERE doc_id_1 = " & Found(CurrentSearch) _
& " AND doc_id_2 NOT IN (" & ArrayToCsv(Found, MaxFound) & ")" _
& " UNION " _
& " SELECT doc_id_1 FROM link WHERE doc_id_2 = " & Found(CurrentSearch) _
& " AND doc_id_1 NOT IN (" & ArrayToCsv(Found, MaxFound) & ")"
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 & SourceArray(ArrayIndex)
If ArrayIndex < ItemCount Then Csv = Csv & ", "
Next ArrayIndex
ArrayToCsv = Csv
End Function
Избегать дублированных результатов и запросов, исключая элементы, уже найденные на сервере, и, поскольку ссылка является однонаправленной, я использовал запрос UNION
для одновременного просмотра в обоих направлениях.Самое большее, это будет MaxInFamily
поездок туда и обратно на сервер.