Программное добавление и удаление ссылок
Теперь я хочу рассмотреть еще один пример, являющийся ответом на следующий вопрос одного из моих читателей:
Как программно добавляются и удаляются ссылки коллекции References?
Задача Сергея Шершнева (так зовут моего читателя) состояла в том, что, работая с системой документов, ему в зависимости от выбора пользователя необходимо было подключать программные проекты тех или иных документов. Чтобы получить доступ в главном документе к процедурам подключенных проектов, ему необходимо было предварительно программно установить ссылки на подключаемые проекты. Не буду вдаваться во все тонкости его проблем и рассмотрю лишь две конкретные задачи, как программно включить (выключить) ссылку на программный проект и как вызывать процедуры подключенных проектов.
Для ответа на эти вопросы рассмотрим следующую ситуацию. Пусть у нас есть главный документ DocOne и два других документа DocTwo и DocThree. Все три документа обладают программными проектами. Открыв главный документ, мы интересуемся предпочтениями пользователя и, в зависимости от его выбора подключаем документ DocTwo или DocThree, вызывая затем соответствующие процедуры подключенного документа. По ходу дела необходимо также уметь отключить ранее подключенный документ. Рассмотрим одно из возможных решений этой задачи.
Прежде, чем перейти к непосредственному решению задачи, сделаю одно замечание. Решение задачи начинается с выяснения предпочтений пользователя. Типичное решение задачи о выборе предпочтений пользователя состоит в том, что ему предъявляется форма, содержащая список всех допустимых значений, задающих предпочтения. Работая с этим списком пользователь формирует множество своих предпочтений. Сейчас я ограничусь более простой процедурой, учитывающей мой частный случай работы с документами:
Public Sub ChooseProject(NoF As String, NoP As String) Const Msg = "Введите имя файла, хранящего документ и его программный проект!" NoF = InputBox(Msg, "Projects", "DocTwo.doc") Const Msg1 = "Введите имя проекта, хранящегося в документе!" NoP = InputBox(Msg1, "Projects", "DocTwo") End Sub
Листинг 4.7.
(html, txt)
Заметьте, для работы со ссылками, - их программного подключения и отключения необходимо знать имя файла, в котором хранится сам подключаемый документ и имя проекта этого документа. В моем примере я проектам во всех документах давал имя, совпадающее с именем документа. Это нашло отражение в установках, задаваемых по умолчанию в функции InputBox.
Вызов функции ChooseProject позволяет установить предпочтения пользователя. Зная их, можно включить соответствующую ссылку на документ. Вот как это делается:
Public Sub CreateRef() 'Создание ссылки на проект с именем NoP, хранящийся в файле с именем NoF Dim MyPath As String Dim MyRef As Object Dim NameOfProject As String Dim NameOfFile As String
'Выбор добавляемого проекта Call ChooseProject(NameOfFile, NameOfProject)
'Запоминание глобальных переменных программы NoF = NameOfFile NoP = NameOfProject With ActiveDocument MyPath = .Path 'Вставка ссылки If Not ExistRef(NameOfProject, MyRef) Then .VBProject.References.AddFromFile MyPath & "\" & NameOfFile End If CallProcFromProject Debug.Print "Имя файла -", NoF, "Имя проекта -", NoP End With End Sub
Листинг 4.8.
(html, txt)
Как видите, для подключения ссылки я использую метод AddFromFile коллекции References. В качестве параметра необходимо задать полный путь к файлу, содержащему документ с подключаемым проектом. Имя проекта при этом указывать не нужно, - оно автоматически будет найдено в документе. Обратите внимание на использование переменной MyPath, задающей путь к активному документу. Я предполагаю, что активным является мой главный документ. Второе, более сильное предположение состоит в том, что все подключаемые документы находятся в одном каталоге с главным. Это позволяет безболезненно переносить все документы на другой компьютер и размещать их в любом каталоге.
Заметьте также, что прежде, чем добавить ссылку, я проверяю возможность существования ее в коллекции ссылок, чтобы исключить ее повторную запись. Булева процедура ExistRef решает эту задачу. Первый параметр NameOfProject является входным и задает имя проекта, ссылку на который мы ищем. Второй параметр - MyRef является выходным и задает объект класса Reference, найденную ссылку в случае успеха поиска. Вот текст этой функции:
Листинг 4.9.
(html, txt)
Программно удалить ссылку также просто, как и ее добавить. Вот текст соответствующей процедуры:
Листинг 4.10.
(html, txt)
Для удаления ссылки я использую метод Remove коллекции References. В качестве параметра этому методу необходимо передать объект, задающий удаляемую ссылку. К счастью у нас уже написана функция ExistRef, которая по имени удаляемого проекта вернет ссылку на него. Поэтому все проблемы с удалением ссылки тем самым решены.