|
|
|
| Всем доброго здравия!
Есть проблема.
Нужно выполнять из одного Mde процедуры/функции из других Mde, но имена файлов этих Mde заранее неизвестны. Добавлять ссылки через References.AddFromFile удаётся только в Mdb, но это не подходит.
Подскажите, есть ли альтернативное решение.
Спасибо. | |
|
| |
|
|
|
| >Нужно выполнять из одного Mde процедуры/функции из других Mde, но имена файлов этих >Mde заранее неизвестны.
непонятно, а как вы собираетесь задавать имена файлов и функций в mde?
Можно попробовать использовать Run. | |
|
| |
|
|
|
| Если имя внешнего файла Mde фиксированное, то всё просто: делается руками ссылка на внешний файл Mde, и его процедуры можно использовать как свои. Это есть в хелпе.
Run не интересен. | |
|
| |
|
|
|
| >Run не интересен.
Вы бы хоть объясняли, например, почему неинтересен Run.
Вы не ответили, как в mde вы планируете передавать имена файлов, процедуры которых хотите использовать. Для совета не хватает деталей. Вы должны поддерживать не только свой интерес, но и интерес тех, кто хотел бы (а может быть и мог) вам помочь. | |
|
| |
|
|
|
| Прошу прощения, если излагаю непонятно.
Идея в том, что есть некая программа, делающая какие-то стандартные вещи, например забирает файлы из почты и куда-то их выкладывает. После этого хочется запускать обработчики этих файлов. Какие это будут обработчики и что будут за файлы в данный момент неизвестно. Поэтому хочется проблему решить методом подключения "плагинов", имена и настройки которых можно прописать во внешнем ini-файле. Т.о. "основная" программа может не знать сколько будет плагинов и что они будут делать, ей главное их запускать в нужный момент. Run плох тем, что надо "ловить" его корректное завершение. Методы, которые я знаю, включая использование WinApi, работают нормально не в 100% случаев, а файлов обрабатывется много (тысячи в день). И вообще, согласитесь, некрасиво Run'ом запускать один Access из другого.
Постарался написать понятно, но если что не бейте сильно :) | |
|
| |
|
|
|
| >И вообще, согласитесь, некрасиво Run'ом запускать один Access из другого.
Не соглашусь. Это аналогично использованию мастера. Вас сильно напрягает, что при использовании мастера, вы используете ACWZMAIN.MDE, ACWZTOOL.MDE? И эти мастера (не все конечно) могут запускаться из MDE. Это не требует поднятия дополнительного Application.
Может вы как-то не так представляете себе использование Run? | |
|
| |
|
|
|
| К сож прямого способа я тоже не нашел тоже. Но поступил примерно так: все что требует секретов и защиты типа мде - я перенес в mde - а вот вызовы функций мдe и прочего поместил в mdb модуль -его правил на лету. - еще как Вариант тока он мною до конца не был изучен - (как-то некоторые вещи "своеобразно" работали ):
' вырезка из куска моего кода
Dim AppAccess as application
Set AppAccess = CreateObject("Access.Application")
If path = "" Then ' если нет пути то объект находится в текущей базе
Set AppAccess = Application
Else
AppAccess.OpenCurrentDatabase (path)
End If
Select Case ObjectType ' типы объектов (видно из методов запуска)
Case 1
AppAccess.DoCmd.OpenForm ObjectName, , , , , OpenMode, Argument
Case 2
AppAccess.DoCmd.OpenReport ObjectName, acViewPreview, , , OpenMode, Argument
DoCmd.RunCommand acCmdZoom100
Case 3
Temp = ObjectName & "('" & Argument & "')" ' Это если необходимо выполнить функцию ' или процедуру
AppAccess.Eval (Temp)
Case 4
AppAccess.DoCmd.OpenQuery ObjectName
Case 5
AppAccess.DoCmd.RunMacro ObjectName
End Select | |
|
| |
|
|
|
| http://www.sql.ru/forum/actualthread.aspx?bid=4&tid=332027&hl=run
Уже 5 месяцев использую, нареканий не имею. | |
|
| |
|
|
|
| Спасибо всем ответившим!
Не мог поблагодарить раньше, т.к. болел и было не до этого.
Работу Run'а я как-то неправильно себе представлял.
Похоже, это то что надо.
Спасибо.
| |
|
| |
|
|
|
| Всё таки Run надежд, увы, не оправдал.
Всё, конечно работает, НО:
Когда Run непрерывно вызывается в цикле из запускающей программы, то работать на компьютере становится практически невозможно: постоянно пытается высветиться Access'овское окно, запущенное Run'ом (хотя никакого вывода на экран там нет и в помине - одни копирования и импорт файлов), тут же пропадает, снова пытается высветиться и т.д. В этот момент экран мерзко дёргается и т.д. и т.п.
В общем "скрытого" запуска не получается - всё равно "один Access из другого", как и предполагалось.
А жаль... | |
|
| |
|
|
|
| Пример можно посмотреть. Что-то не так. | |
|
| |
|
|
|
| Вот сочинил пример.
Два Mdb в папке C:\Test:
C:\Test\Test1.mdb
C:\Test\Test2.mdb
---
Test1.mdb:
---
'Запускается через макрос Autoexec
Public Function Autoexec()
Do While True
Dim appAccess As New Access.Application
appAccess.OpenCurrentDatabase "C:\Test\Test2.mdb"
appAccess.Run "Plugin"
appAccess.CloseCurrentDatabase
Loop
End Function
---
Test2.mdb:
---
Public Sub Plugin()
End Sub
-------------
Запускаем Test1.mdb и наблюдаем дёргающееся в конвульсиях окно второго Access'а | |
|
| |
|
|
|
| Зачем создавать Access.Application.
Увы, вы не вникли в суть предложения.
test2.mdb переименуйте в test2.mda
и запуск
Public Function Autoexec()
Run "C:\Test\Test2.Plugin"
End Function
|
| |
|
| |
|
|
|
| В MSAccess-97 такое мне сделать не удаётся. | |
|
| |
|
|
|
| Может быть, я проверял в Access 2002-2003.
Но точно известно, что подобное работает, если библиотечный файл (в данном случае Test2.mda) расположен в том же каталоге, где и msaccess.exe.
И вызов будет таким
Public Function Autoexec()
Run "Test2.Plugin"
End Function
|
если вы скажите, что это не работает, то ищите ошибку у себя. | |
|
| |
|
|
|
| Да, если скопировать файл в папку с самим Аксессом, то работает и в 97-м тоже.
К сожалению, это не подходит по ряду причин.
Пока остановился на варианте с созданием Access.Application и скрытием нового созданного окна. Вроде жить можно.
Спасибо за помощь. | |
|
| |
|
|
|
| >К сожалению, это не подходит по ряду причин.
Если не лень, скажите, какие могут быть причины, препятствующие расположить библиотечные файлы в каталоге msaccess.exe?
Мне надо для общего развития. | |
|
| |
|
|
|
| Коротко написать как-то не получается, но попробую.
До этого весь софт подобного рода в нашей конторе представлял собой группу файлов, которые кладутся в одну папку и там же работают. На уровне файлов или папок раздаются права доступа. Настройки поиска файлов, папок, подключений - фиксированные, прописанные в ini-файлах или внутри программы.
В данном случае пришлось бы учитывать необходимость кидать часть файлов в другую папку, что там будет с правами доступа неизвестно, обслуживают эти компьютеры (сервера) разные люди, надо писать витиеватые инструкции или инсталляторы и т.д. и т.п.
Для этой задачи это слишком большие сложности ради такой ерунды, без которой можно обойтись, сисадминам и так работы хватает. Это ведь не новая ОС какая-нибудь.
Попросту говоря, раньше так не делали и всё тут :)
Извиняюсь, если не убедил. | |
|
| |
|
|
|
| СПАСИБО за пример а, я дурень заморачивался с созданием Application. Тока у меня возникло несколько вопросов - сам не пробовал может уже знаете: У меня есть интерфейс (грид и дерево и еще куча функций), есть несколько программ - используеющих этот интефейс - в каждой программе есть небольшие таблицы - в которых хранятся данные присущие только этой программе - и находятся внутри прогрммы а не в прилинкованных таблицах. Как передать контекст выполнения каждой программы (даже и не знаю как правильно выразить)- суть в чем когда я вызываю функции интерфейса - исполняющие следующий код Set rs= Currentdb.openrecordset ("SELECT * FROM table1") из программы А - то таблица должна использоваться именно программы А и аналогично для программ Б, В .... | |
|
| |
|
|
|
| Естьтакое желание ответиь так -
Используйте Currentdb
Но думаю, что я чего-то не понял, так что, на всякий случай вот выдержка из хелпа:
Функцию CodeDb используют в модуле для определения имени объекта Database, описывающего открытую базу данных, в которой выполняется текущая программа. Функция CodeDb обеспечивает доступ к объектам доступа к данным, являющимся частью библиотечной базы данных.
Например, функция CodeDb может быть использована в модуле библиотечной базы данных для создания объекта Database, описывающего библиотечную базу данных. После этого становится возможным открытие и изменение набора записей, выбираемого из таблицы в библиотечной базе данных.
Синтаксис
Set базаДанных = CodeDb
Функция CodeDb использует следующий аргумент.
Аргумент Описание
базаДанных Объектная переменная типа Database.
Дополнительные сведения
Функция CodeDb возвращает объект Database, у которого значением свойства Name является полное (включая путь) имя файла базы данных, из которой была вызвана данная функция. Функция CodeDb используется для работы с объектами доступа к данным в библиотечной базе данных.
При вызове данной функции в библиотечной базе данных текущей остается база данных, из которой была вызвана функция, даже во время выполнения программы модуля библиотечной базы данных. Для ссылки на объекты доступа к данным в библиотечной базе данных необходимо знать имя объекта Database, представляющего библиотечную базу данных.
Предположим, например, что в библиотечной базе данных имеется таблица, содержащая список сообщений об ошибках. Для того чтобы выполнить из программы обработку данных в этой таблице следует с помощью функции CodeDb определить имя объекта Database, содержащего ссылку на библиотечную базу данных, в которой содержится таблица.
Если функция CodeDb вызывается в текущей базе данных, то она возвращает имя текущей базы данных аналогично функции CurrentDb. | |
|
| |
|
|
|
| Т.е. если я правильно понял я должен передавать ссылку в библиотечную базу (функуцию находящуюся в ней) на вызывающюю программу т.е. примерно так: run ("c:\test\test.tstfunction", Currentdb) т.е. по хелпу
Run(Procedure, Arg1, Arg2.....)
А уже в самой вызываемой функции так (код- упрощенно только для понимания) :
Dim db as database
Set db=arg1
db.Openrecordset ("......")
Я все правильно понял ? | |
|
| |
|
|
|
| Если в коде библиотечного файла Вы воспользуетесь функцией CurrentDb, то библиотечный файл будет видеть таблицы основного файла.
Если же воспользуетесь СodeDb, то библиотечный файл будет видеть свои таблицы.
Ни чего в качестве аргумента передовать не надо, т.е. в вызываемой функции будет так.
Dim db as DAO.Database
Set db=CurrentDb
db.Openrecordset ("......")
|
| |
|
| |
|
|
|
| БОЛЬШОЕ СПАСИБО !!! за разъясение | |
|
| |