powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Иерархия и рекурсия
25 сообщений из 120, страница 3 из 5
Иерархия и рекурсия
    #32509008
Sergey_New
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Victosha
Увы :(
А что под № 2) ?
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509014
Фотография Zenia
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
'а зачем LEFT JOIN
Set rst = dbs.OpenRecordset(_  
            "SELECT ребенок FROM семьи LEFT JOIN дети ON семьи.id=дети.семья WHERE Not ребенок Is Null AND (муж=" _        
           & id & " OR жена=" & id & ")", dbOpenForwardOnly)

'можно сократить
Set rst = dbs.OpenRecordset(_  
            "SELECT ребенок FROM семьи INNER JOIN дети ON семьи.id=дети.семья" _ 
& "WHERE муж=" & id & " OR жена=" & id & ")", dbOpenForwardOnly)
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509015
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2) - минорный улучшайзинг- закешируй обращения к полям и используй .Collect
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509021
Sergey_New
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 фыыф
Вы очень хорошо обо мне думаете :)
Мне только, чтобы разобраться в смысле написанного потребуется день!
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509034
Sergey_New
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Victosha
Что это Collect?
В справке не нашел.
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509038
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
давай еще раз попробуем
1) DBENgine.Idle dbRefreshCache

2 ) перед AddNew поставь DBENgine.BeginTrans
после Update поставь DBEngine.CommitTrans
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509042
фыыф
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
о! идея (находюся)

откройте 2 рекордсета rstS(0 to 1)
и сразу при открытии один раз (не в рекурсивной части)

Код: plaintext
1.
2.
3.
    sIn( 0 ) = "Мid": sIn( 1 ) = "Жid"
    For iSx =  0  To  1         
        rstS(iSx).Index = sIn(iSx)
    next iSx
а в рекурсивной переключаться меж рекордсетами, а не менять индекс:

Код: plaintext
1.
2.
3.
4.
5.
    For iSx =  0  To  1 
        With rstS(iSx)
            '.Index = sIn(iSx) - уже задан, не будем!'
            ...
                    End With
                    '.Index = sIn(iSx) 'НЕ мог смениться
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509048
Sergey_New
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Zenia
Есть семьи без детей. В какой-то версии возникала ошибка.
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509063
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пардон Collect - соврал - он - .CollectionIndex - недокументированный и самый быстрый способ обращения к значению поля для DAO.Recordset
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509069
Sergey_New
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Victosha
Проверил. Без улучшения.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
Sub FindDescendantT(id As Long, iGeneration As Long)
    On Error Resume Next
    Dim i As Long, nS As Long, nR As Long, iSx As Long
    Dim sIn( 0  To  1 ) As String
    sIn( 0 ) = "муж": sIn( 1 ) = "жена"
    For iSx =  0  To  1 
        With rstS
            .Index = sIn(iSx)
            .Seek ">=", id
            If Not .NoMatch Then
                Do While .Fields(iSx +  1 ) = id
                    nS = .Fields("id")
                    With rstD
                        .Seek ">=", nS,  0 
                        If Not rstD.NoMatch Then
                            Do While .Fields("Семья") = nS
                                nR = .Fields("Ребенок")
                                With rstDesc
                                    DBEngine.BeginTrans
                                    .AddNew
                                    .Fields( 0 ) = nR
                                    .Fields( 1 ) = iGeneration
                                    .Update
                                    DBEngine.CommitTrans
                                End With
                                i = iGeneration +  1 
                                FindDescendantT nR, i
                                .Seek ">", nS, nR
                                If .NoMatch Then Exit Do
                            Loop
                        End If
                    End With
                    .Index = sIn(iSx) 'мог смениться
                    .Seek ">", id, nS
                    If .NoMatch Then Exit Do
                Loop
            End If
        End With
        DBEngine.Idle dbRefreshCache
    Next iSx
End Sub
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509074
фыыф
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
т.е. (с учетом "хорошо думаю") попробуйте вот так: (и приведите результаты, если не сложно)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
Option Compare Database
Option Explicit
  Dim dbs As Database, rstDesc As Recordset, rstS( 0  To  1 ) As Recordset, rstD As Recordset ', n As Long
  Private Pc(0 To 0) As Long, Pn(0 To 0) As Long

Sub startM()
    Dim iSx As Long
    Dim sIn(0 To 1) As String
    Set dbs = CurrentDb
    dbs.Execute ("Delete From потомки")
    Set rstDesc = dbs.OpenRecordset("потомки")
    
    sIn(0) = "Мid": sIn(1) = "Жid"
    For iSx = 0 To 1
        Set rstS(iSx) = dbs.OpenRecordset("семьи", dbOpenTable)
        rstS(iSx).Index = sIn(iSx)
    Next iSx

    Set rstD = dbs.OpenRecordset("дети", dbOpenTable)
    rstD.Index = "СемьяРебенок"
    FindDescendantM 1, 1 '29,  1 
    rstDesc.Close
    Set rstDesc = Nothing
    For iSx =  0  To  1 
        rstS(iSx).Close
        Set rstS(iSx) = Nothing
    Next iSx
    rstD.Close
    Set rstD = Nothing
End Sub

Sub FindDescendantM(id As Long, iGeneration As Long)
    On Error Resume Next
    Dim i As Long, nS As Long, nR As Long, iSx As Long
    'Set rst = dbs.OpenRecordset("SELECT ребенок FROM семьи LEFT JOIN дети ON семьи.id=дети.семья WHERE Not ребенок Is Null AND (муж=" & id & " OR жена=" & id & ")")
    Dim sIn(0 To 1) As String
    sIn(0) = "Мid": sIn(1) = "Жid"
    For iSx = 0 To 1
        With rstS(iSx)
            '.Index = sIn(iSx)
            .Seek ">=", id,  0 
            If Not .NoMatch Then
                Do While .Fields(iSx +  1 ) = id
                    nS = .Fields("id")
                    With rstD
                        .Seek ">=", nS,  0 
                        If Not rstD.NoMatch Then
                            Do While .Fields("Семья") = nS
                                nR = .Fields("Ребенок")
                                With rstDesc
                                    .AddNew
                                    .Fields( 0 ) = nR
                                    .Fields( 1 ) = iGeneration
                                    .Update
                                End With
                                i = iGeneration +  1 
                                FindDescendantM nR, i
                                .Seek ">", nS, nR
                                If .NoMatch Then Exit Do
                            Loop
                        End If
                    End With
                    '.Index = sIn(iSx) 'мог смениться
                    .Seek ">", id, nS
                    If .NoMatch Then Exit Do
                Loop
            End If
        End With
    Next iSx
End Sub
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509080
фыыф
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
блин, просмотрел!
- выкиньте еще:
Dim sIn(0 To 1) As String
sIn(0) = "Мid": sIn(1) = "Жid"
из рекурсивной части
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509084
Sergey_New
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 фыыф
авторо! идея (находюся)
Я не успеваю за вами.
Нельзя ли идею в полном виде?
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509096
фыыф
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
именно к этому "идея" см. полный код 13:45 + примечание 13:47


главное - есть ли профит (от неперечтения индексов, но с платой - лишним рекордсетом)
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509109
Sergey_New
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 фыыф
Профита нет. Совсем :(
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509113
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну вот еще один заход шаманский - не уверен, что поможет, но результат услышать бы хотелось.

попробуй после DBEngine.Idle
поставить DoEvents
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509114
фыыф
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
именно те же количества? за те же времена?
а вызывали вы именно FindDescendantM
(с помощью startM),
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509167
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
что-то я сегодня совсем зарапартовался- видно спать пора -
CollectionIndex - он, конечно, не значение возвращает, а номер поля в наборе данных

пошел спать
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509170
Sergey_New
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 фыыф
Запускал из нового модуля, так что без ошибок (своих :0) )...
Результаты теже.
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509195
Sergey_New
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Victosha
авторпопробуй после DBEngine.Idle
поставить DoEvents
По прежнему...
авторпошел спать
Спокойного сна!
Возвращайся! :)
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509227
фыыф
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ну, попробу так (без рекурсий)
что-то сомневаюсь я, но все таки должен быть другой тип зависимости времени от числа возвращенных записей:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
Option Compare Database
Option Explicit
Private dbs As Database, rstDesc As Recordset, rstS( 0  To  1 ) As Recordset, rstD As Recordset ', n As Long
Private pC() As Long, pN() As Long

Sub startA()
    Dim iSx As Long
    Dim sIn(0 To 1) As String
    Set dbs = CurrentDb
    dbs.Execute ("Delete From потомки")
    Set rstDesc = dbs.OpenRecordset("потомки")
    
    sIn(0) = "Мid": sIn(1) = "Жid"
    For iSx = 0 To 1
        Set rstS(iSx) = dbs.OpenRecordset("семьи", dbOpenTable)
        rstS(iSx).Index = sIn(iSx)
    Next iSx

    Set rstD = dbs.OpenRecordset("дети", dbOpenTable)
    rstD.Index = "СемьяРебенок"
    FindDescendantAll 1, 1 '29,  1 
    rstDesc.Close
    Set rstDesc = Nothing
    For iSx =  0  To  1 
        rstS(iSx).Close
        Set rstS(iSx) = Nothing
    Next iSx
    rstD.Close
    Set rstD = Nothing
End Sub

Sub FindDescendantAll(id As Long, iGeneration As Long)
Dim nP As Long, nC As Long, iG As Long, bF As Boolean
Dim iC As Long

    On Error Resume Next
    bF = FindDescendantA(id, iGeneration)   'первый вызов
    iG = iGeneration
    Do While bF  'цикл по поколениям
        If (bF) Then  'лишняя проверка, осталась от отладки :)
            'переместим следующих в текущий
            Erase pC
            ReDim pC( 0  To UBound(pN))
            For iC =  0  To UBound(pN)
                pC(iC) = pN(iC)
            Next iC
        End If
        Erase pN    'очистка следующего
        bF = False
        iG = iG + 1
        For nC = 0 To UBound(pC)
            bF = FindDescendantA(pC(nC), iG) Or bF
        Next nC
    Loop
End Sub

Function FindDescendantA(id As Long, iGeneration As Long) As Boolean
    Dim i As Long, nS As Long, nR As Long, iSx As Long
    On Error Resume Next        
    For iSx = 0 To 1
        With rstS(iSx)
            '.Index = sIn(iSx)
            .Seek ">=", id,  0 
            If Not .NoMatch Then
                Do While .Fields(iSx +  1 ) = id
                    nS = .Fields("id")
                    With rstD
                        .Seek ">=", nS,  0 
                        If Not rstD.NoMatch Then
                            Do While .Fields("Семья") = nS
                                nR = .Fields("Ребенок")
                                With rstDesc
                                    .AddNew
                                    .Fields( 0 ) = nR
                                    .Fields( 1 ) = iGeneration
                                    .Update
                                End With
                                i = iGeneration +  1 
                                FindDescendantA = True 'есть хоть один
                                'FindDescendantA nR, i
                                Dim kN As Long
                                kN = UBound(pN) +  1 
                                ReDim Preserve pN( 0  To kN)
                                pN(kN) = nR 'вызовем потом
                                '.Seek ">", nS, nR
                                .MoveNext
                                If .NoMatch Then Exit Do
                            Loop
                        End If
                    End With
                    '.Seek ">", id, nS
                    .MoveNext
                    If .NoMatch Then Exit Do
                Loop
            End If
        End With
    Next iSx
End Function

обрати внимание на вызовы (имена :). И приведи таки вид зависимости от времени.
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509251
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
проснулся

СТОП - а потомки там часом не индексированы ли ?
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509348
фыыф
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 Victosha

мдя, я тут не фигней ли занимаюсь в поэлементном присвоении массива?
Нельзя ли его как-то с помощью передачи указателя(ей) передвинуть?


ЗЫ (была как-то задачка, для которой тип. содержащий коллекции и массивы (не помню, но кажется массивы с членами - коллекциями) неплохо б было клонировать. Так там тоже было бы невредно исхитрятся без поэлементного присвоении, только там область памяти как-то надо было еще "сдвигать" (а стало быть и все указатели на объектные поля типа) - после клонирования действия над объектами (коллекциями и их членами) были разные).
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509354
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 фыыф

1) собственно массива "на присвоение" я тут не проглядываю,
2) в переводе с русского на русский - сие есть глубокий хакинг, применительно к тому месту о котором ты говоришь - надо в DAO SDK углубляться - я этого не делал.
...
Рейтинг: 0 / 0
Иерархия и рекурсия
    #32509388
фыыф
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 Victosha

это я спрашал исключительно про кусок нерекурсивного варианта (последнего из предложенных), касательно сдвига следующего поколения в текущий:
Код: plaintext
1.
2.
3.
4.
            Erase pC
            ReDim pC( 0  To UBound(pN))
            For iC =  0  To UBound(pN)
                pC(iC) = pN(iC)
            Next iC


_______________
ЗЫ. а задачка со сдвигом/клонированием объектов возникла при идее использовать "человеческие" описания "генов" в генетическом алгоритме (типы со значащими полями, а не строки бит) для конкретной задачки.
...
Рейтинг: 0 / 0
25 сообщений из 120, страница 3 из 5
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Иерархия и рекурсия
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]