Как сохранить значение глобальной переменной после динамической загрузки ссылки? - PullRequest
1 голос
/ 17 августа 2011

У меня есть база данных Access 2003, которая будет динамически загружать базы данных MDB в качестве справочной библиотеки. Причиной этого является то, что эта база данных является интерфейсом меню для 60+ баз данных приложений. Вместо того, чтобы иметь дело с постоянными ссылками на все эти базы данных, интерфейс меню будет динамически ссылаться на то, что необходимо, когда пользователь делает выбор. Я работал над перемещением этой базы данных в Access 2010 и созданием пользовательской ленты. Я начал использовать технику с здесь для захвата объекта ленты в глобальную переменную при загрузке ленты. Затем я столкнулся с проблемой, при которой я мог убедиться, что код выполняется, и глобальной переменной правильно назначена ссылка на ленту, но после того, как база данных пройдет через процедуру запуска, эта глобальная переменная будет сброшена в Nothing.

Чтобы проверить, что происходит, я создал простую базу данных для тестирования. В этой базе данных у меня был модуль с глобальной переменной:

Public obj as Object

У меня тогда была такая функция:

Public Function SetObj()

Set obj = Application

Debug.Print "IsNothing=" & (obj Is Nothing)

References.AddFromFile "Test.mdb"

Debug.Print "IsNothing=" & (obj Is Nothing)

End Function

Очевидно, в моем коде "Test.mdb" относится к реальному файлу. Если я запускаю этот код, Debug.Print выдает мне «IsNothing = False» для обоих экземпляров, но после завершения функции и, если я подожду пару секунд, Debug.Print выдаст мне «IsNothing = True». Если я закомментирую References.AddFromFile, Debug.Print выдаст мне «IsNothing = False» независимо от того, как долго я буду ждать.

Для меня имеет смысл, что, так как Access должен перекомпилировать код VBA после загрузки библиотеки, все глобальные переменные сбрасываются. Я экспериментировал с перемещением глобальной переменной в класс, но так как тогда мне нужна глобальная переменная для класса, вместо этого переменная класса получает сброс. Я попытался использовать локальную переменную в функции, чтобы сохранить значение глобальной переменной, но похоже, что Access ждет пару секунд после завершения выполнения кода, чтобы выполнить повторную компиляцию, так что это тоже не работает. У кого-нибудь есть другие идеи для достижения этой цели?

Ответы [ 2 ]

1 голос
/ 18 августа 2011

Я действительно не знаю, решит ли это проблему для такого рода ссылок, но в целом я не использую публичные переменные для такого рода вещей, а вместо этого использую переменную STATIC внутри вашей функции. Это было бы что-то вроде этого:

  Public Function SetObj() As Object
    Static obj As Object

    If (obj Is Nothing) Then
       Set obj = Application
    End If
    Set SetObj = obj
  End Function

Тогда вы просто использовали бы SetObj как объект для использования вашего приложения. В производственном приложении вам также понадобится код разрыва, но здесь я его опускаю.

Я сомневаюсь, что это помогает, но ваш код показался мне довольно неэффективным и неполным.

0 голосов
/ 18 августа 2011

Я нашел решение своей проблемы, и спасибо @ David-W-Fenton, так как ваш ответ дал мне идею.Я использую ваш подход в библиотечной базе данных для кэширования часто используемых значений, которые хранятся в таблице, но не меняются после первоначального запуска.Эти значения не теряются при каждом изменении ссылок, и именно тогда лампочка загорается.

Решение состоит в том, чтобы поместить глобальную переменную в базу данных библиотеки.Похоже, что доступ сбрасывает только глобальные переменные в базе данных, в которую загружается ссылка, - что имеет смысл, подумав об этом.Таким образом, поскольку база данных библиотеки не перекомпилируется, она не сбрасывает глобальные (или частные, или статические) переменные.

В итоге я создал новый модуль в существующембаза данных библиотеки.Он имеет закрытую переменную и два метода - один для установки переменной, другой для получения значения переменной.В моей интерфейсной базе данных меню, когда лента загружает и вызывает мою функцию обратного вызова, а не сохраняет объект ленты в интерфейсной базе данных, я передаю его этому модулю для сохранения.Теперь я больше не теряю эту ссылку на ленту всякий раз, когда новые базы данных добавляются в ссылки на библиотеки на лету.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...