powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Рекурсия и рекордсет
19 сообщений из 19, страница 1 из 1
Рекурсия и рекордсет
    #33655128
T_Volkova_81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть рекурсивная функция для обхода дерева. (Открыть рекордсет, для каждой записи вызвать эту функцию, закрыть рекордсет). Дерево достаточно большое. Когда открывается 50 рекордсетов, выдается сообщение "Ошибка 3048. Открытие дополнительных баз невозможно". Подскажите, как это побороть?
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655163
Karfaqen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
T_Volkova_81Ошибка 3048. Открытие дополнительных баз невозможно". Подскажите, как это побороть?Если дело именно в "Открытии дополнительных баз " (то есть, вы для открытия Recordset открываете там же Database), то попробуйте в своей рекурсивной функции не делать открытие Database. Откройте ее снаружи и прередайте в фунцию в качестве параметра.
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655212
T_Volkova_81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я делаю CurrentDB.OpenRecordset. Разве при этом открывается база?
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655247
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Если я не ошибаюсь, CurrentDB каждый раз открывает базу заново. Можно попробовать занести CurrentDB в переменную и дальше пользоваться только ею.
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655259
жд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владимир СанычЕсли я не ошибаюсь, CurrentDB каждый раз открывает базу заново. Можно попробовать занести CurrentDB в переменную и дальше пользоваться только ею.
В подтверждение предположения ВС (если речь не идет о MSA < 2000)
из справки
Note In previous versions of Microsoft Access, you may have used the syntax DBEngine.Workspaces(0).Databases(0) or DBEngine(0)(0) to return a pointer to the current database. In Microsoft Access 2000, you should use the CurrentDb method instead. The CurrentDb method creates another instance of the current database, while the DBEngine(0)(0) syntax refers to the open copy of the current database. The CurrentDb method enables you to create more than one variable of type Database that refers to the current database. Microsoft Access still supports the DBEngine(0)(0) syntax, but you should consider making this modification to your code in order to avoid possible conflicts in a multiuser database.
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655267
Karfaqen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
T_Volkova_81Я делаю CurrentDB.OpenRecordset. Разве при этом открывается база?При этом создается новая ссылка на объект CurrentDb, очевидно, на это есть ограничения. Попробуйте все-таки передать базу параметром, в этом случае вам наверняка удастся пройти по дереву чуть дальше - пока не уткнетесть в ограничение по числу открытых таблиц ;)
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655304
T_Volkova_81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, сейчас попробую. А какое ограничение на число открытых таблиц (офис 97)?
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655308
Karfaqen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробовал, у меня при подобной рекурсии:
ошибка 3048 - при числе итераций 250 (это ваш варант с CurrentDb)
ошибка 3014 - при числе итераций 2040 (это вариант с открытием бд снаружи)
MSA2000
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655331
Karfaqen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
T_Volkova_81А какое ограничение на число открытых таблиц (офис 97)?Ограничения такого рода перечислены в справке MSA (по-моему, в разделе "Спецификации").
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655338
LeonM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вместо CurrentDB пользуйтесь DBEngine.Workspaces(0).Databases(0). закрывайте ненужные recordset и уничтожайте переменные.
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655472
Мшсещырф
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владимир СанычЕсли я не ошибаюсь, CurrentDB каждый раз открывает базу заново. ...
думаю, что так сказать нельзя.
То, что CurrentDB занимает одну из ссылок в наборе Databases - это да.
При достижении предела в 250 ссылок на databases идет ошибка.
Но это не значит, что currentdb вновь открывает базу.
По крайней мере никаких следов второго открытия базы в .ldb нет.
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655693
T_Volkova_81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, что-то это не сильно помогло.
Решила привести код.

БД для учета технологического маршрута. Для изготовления номенклатуры проводится несколько операций. На каждой операции, в свою очередь, может расходоваться другая номенклатура.

Таблицы:
Номенклатура(сч,Наименование,Обозначение,...)
Операции(сч,Наименование,Обозначение,...)
МКНоменклатуры(сч,НомерОперации,Операция,КудаВходит(Номенклатура),Участок,...) 'маршрутная карта номенклатуры
СоставОпераций(сч,Номенклатура,Операция,Расход,КоэффициентРегнерации,...) 'нормы расхода номенклатуры на операцию

Код: 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.
Option Compare Database
Option Explicit
Dim i As Integer
Dim j As Integer
Dim db As Database


Private Sub кнПечать_Click()
  Set db = DBEngine.Workspaces( 0 ).Databases( 0 )
  i =  0 
  j =  0 
  Dim izd As String
  izd = Me.ПолеНом.Value
  PrintWork False, izd
  Set db = Nothing
End Sub

Private Sub PrintWork(p_o As Boolean, parent As String)
  i = i +  1 
  Debug.Print "i=" & i
  Debug.Print "i-j=" & (i - j)
  Dim sqls As String
  Dim rs As Recordset
  If p_o = True Then
    sqls = "SELECT СоставОпераций.Номенклатура, Номенклатура.Наименование, Номенклатура.Обозначение  FROM (Номенклатура INNER JOIN СоставОпераций ON Номенклатура.сч=СоставОпераций.Номенклатура)  WHERE СоставОпераций.Операция=" & parent
  Else
    sqls = "SELECT МКНоменклатуры.Операция, Операции.Наименование, Операции.Обозначение  FROM (Операции INNER JOIN  МКНоменклатуры ON Операции.сч=МКНоменклатуры.Операция)WHERE МКНоменклатуры.КудаВходит=" & parent
  End If
  Set rs = db.OpenRecordset(sqls)
  If p_o = True Then
    Do Until rs.EOF
      Debug.Print rs!Наименование & rs!Обозначение
      Call PrintWork(Not p_o, rs!Номенклатура)
      rs.MoveNext
    Loop
  Else
    Do Until rs.EOF
      Debug.Print rs!Наименование & rs!Обозначение
      Call PrintWork(Not p_o, rs!Операция)
      rs.MoveNext
    Loop
  End If
  rs.Close
  Set rs = Nothing
  j = j +  1 
  Debug.Print "j= " & j
End Sub
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655777
T_Volkova_81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CurrentDb- ошибка вылетаkf при i-j=50, сейчас - 63. Думаю рекордсет копировать в массив и тут же закрывать, затем цикл по массиву. Может быть, кто-нибудь еще идею подскажет?
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655814
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поищи алгоритм обхода дерева без рекурсии, он точно есть (в универе помнится на дискретной матиматике его приводил препод), аглогимт был для бинарного дерева, а любое дерево можно однозначно преобразовать в бинарное и обратно, алгоритм есть тоже вот его я даже помню.
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655823
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
А если поиграть с параметрами рекордсета?

Set rs = db.OpenRecordset(sqls,dbopendynaset,dbreadonly)
или
Set rs = db.OpenRecordset(sqls,dbopensnapshot)
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655840
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655870
MsDatabaseru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
лучше реализовать рекурсию в запросе и выводить в первый же рекордсет уже готовые данные о дереве и сответственно выводить куда нужно.
если алготим формирования рекурсивных данных достаточно сложен можно сделать код который будет последовательно формировать временную таблицу инсертами и апдейтами, а потом просто выберешь ее в рекордсет

а вообще текстовое поле в таблице описывающем дерево сданными
типа
ID NODE parentpath1 корень 1\2 Первый элемент 1\2\3 Второй элемент 1\3\4 Первый суб первого эл-та 1\2\4\

позволит быстро найти дочек начиная с любого узла при помощи Like
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655874
Андрей74
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://am.rusimport.ru/MSAccess/topic.aspx?ID=321

А вообще какая конечная задача данной процедуры???
...
Рейтинг: 0 / 0
Рекурсия и рекордсет
    #33655882
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимир СанычА если поиграть с параметрами рекордсета?

Set rs = db.OpenRecordset(sqls,dbopendynaset,dbreadonly)
или
Set rs = db.OpenRecordset(sqls,dbopensnapshot)
я бы ваще открыл либо 4 табличных рекордсета с нужными индексами на уровне модуля, и только Seek-ал бы по ним, либо, на том же уровне модуля, 2 праильно отсортированных динасета и бегал бы по ним файндом ("пока не") и букмарками (по возвращению на уровень рекурсии из вложения).
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Рекурсия и рекордсет
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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