Итак, начну с задачи, которую я решаю - может, кто подскажет другой способ. У меня есть класс Database, представляющий базу данных SQLite. Есть также класс Recordset, представляющий наборы записей. Я создаю множество экземпляров класса Recordset, родителем которых является объект Database.
В какойто момент объект Database запускает на выполнение какую-нибудь инструкцию SQL, и мне необходимо пробежаться по всем дочерним объектам Recordset, чтобы выполнить их метод Refresh. Вот такая, тривиальная на первый взгляд, задача.
Первое, что пришло на ум: создать коллекцию объектов Recordset внутри класса Database и добавлять туда все вновь созданные объекты, чтобы при необходимости можно было их перебрать. Проблема: объекты Recordset иногда удаляются из памяти (Set rs = Nothing), и делается это НЕ внутри класса Database. А наличие коллекции объектов не позволяет очистить память (объекты Recordset могут занимать очень много памяти).
Таким образом, задача звучит так: нужно иметь возможность пробежаться только по существующим объектам Recordset, не мешая при этом очищать память. Следующей идеей было отказаться от коллекций и собирать массив ссылок VarPtr на все созданные объекты Recordset, что, как мне кажется не должно мешать очистке памяти (верно?). А в нужный момент я планировал воспользоваться функцией GetMemObj, чтобы при необходимости получать объектные переменные. Подразумевалось, что, если GetMemObj вернёт ошибку, значит ссылка на объект битая, и её можно удалить. Собственно, проблема оказалась именно в использовании GetMemObj:
- Код: Выделить всё
Private Declare Function GetMemObj Lib "msvbvm60" _
(ByVal pSrc As Long, ByRef MyObj As Object) As Long
Public Sub RefreshAllRecordsets()
On Error GoTo ErrHandler
10 Dim i As Long
12 Dim rv As Long
14 Dim obj As Object
16 If Connection.AffectedRows = 0 Then Exit Sub
18 For i = 1 To nPointers
20 If aPointers(i) > 0 Then
22 rv = GetMemObj(aPointers(i), obj)
23 Debug.Print TypeName(obj)
24 If rv = 0 Then
26 obj.Refresh
28 Else
30 aPointers(i) = 0
32 End If
34 End If
36 Next
ErrHandler:
Debug.Print Erl & ", " & Err.Description
End Sub
Не могу получить объектную переменную при помощи GetMemObj. Ошибки возникают в 22-ой строке и при помощи On Error внутри этой процедуры они не отлавливаются (вылетает в вызывающую процедуру в обычном модуле, минуя дочерний объект, который её реально вызвал). Строку определил при помощи установки Break point.