Access 2010-2016 VBA: можете ли вы ссылаться на библиотеку объектов MS Outlook в нескольких версиях?

Меня попросили устранить неполадки в сценарии VBA, который отправляет электронное письмо из базы данных Access. БД и VBA были разработаны для Access 2010 (данные, хранящиеся в базе данных SQL) и, вероятно, нацелены на Outlook 2010.

В настоящее время мы используем Outlook 2013 и 2016.

Когда мой сценарий (указанный ниже) запускается, в объявлении Outlook.Application генерируется ошибка: Тип данных, определяемый пользователем, не определен.

Это начало сценария, в котором мы определяем типы данных.

Option Compare Database
Option Explicit
 
' InitOutlook sets up outlookApp and outlookNamespace.
Private outlookApp As Outlook.Application
Private outlookNamespace As Outlook.NameSpace

Остальная часть сценария ниже. Он запускается кнопкой формы, которая напрямую вызывает SendEmail () и передает адрес электронной почты в качестве переменной.

Private Sub InitOutlook()
    ' Initialize a session in Outlook
    Set outlookApp = New Outlook.Application
    
    'Return a reference to the MAPI layer
    Set outlookNamespace = outlookApp.GetNamespace("MAPI")
    
    'Let the user logon to Outlook with the
    'Outlook Profile dialog box
    'and then create a new session
    outlookNamespace.Logon , , True, False
End Sub

Public Sub SendEmail(varTo As Variant)
    Dim mailItem As Outlook.mailItem
        
    InitOutlook
    Set mailItem = outlookApp.CreateItem(olMailItem)
    mailItem.To = varTo & ""
    mailItem.Subject = "subject text"
    mailItem.Body = "Body text"
    mailItem.Display
    
    Set mailItem = Nothing
    CleanUp
End Sub

Я не очень хорошо знаком с VBA / Access, но я работал с VB.NET и с самого начала был достаточно уверен, что это был простой вопрос: «отсутствует инструкция импорта или ссылка».

Немного покопавшись в этом, я обнаружил в сети здесь, что для использования этой функции вы должны добавить ссылку в библиотеке объектов Microsoft Outlook XX.X.

Я еще не видел ссылок, которые есть в этой базе данных (сейчас работаю над тем, чтобы добраться туда), так как у меня ограниченный доступ к этой базе данных доступа, поскольку она содержит много конфиденциальной информации, и при ее просмотре я должен находиться под наблюдением.

Однако, учитывая, что мы использовали Outlook 2010, когда писали этот сценарий, и теперь разделены между Outlook 2013 и 2016, я считаю, что нам нужно обновить эту ссылку на более новую.

Я обсуждал это с коллегой здесь, и он задал мне важный вопрос:

Can we reference more than one version of the Microsoft Outlook Object Library?

Если мы нацелимся на самую последнюю версию библиотеки, например, Outlook 2016, не будет ли сценарий работать для пользователей Outlook 2013?

Update: I found out through testing that if we used the MS Outlook 16.0 object library, Outlook 2013 would not recognize the reference, and would throw errors that the reference was missing.

If we used the MS Outlook 15.0 library, the script worked on machines with either version of outlook.

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

braX 01.05.2018 17:36

Как я уже упоминал, здесь, вы можете избежать всего этого, если будете просто использовать позднее связывание вместо раннего. Если вы настаиваете на раннем связывании и должны быть независимыми от версии, вам, вероятно, придется пойти по пути использования Условная компиляция. Раннее связывание будет намного проще :)

David Zemens 04.05.2018 14:41

@DavidZemens Я попытался переключиться на позднюю привязку, и ваш пост очень помог в этом, но во время тестирования понял, что есть много несвязанных разделов нашего кода, которые также необходимо изменить, которые также использовали раннее связывание. Я не знаком с другими областями, которые необходимо обновить, и поэтому не могу надежно протестировать изменения на других страницах, чтобы убедиться, что они будут работать для всех пользователей. В итоге я обратился к библиотеке объектов MS Outlook 15.0, и это устранило проблему для пользователей Outlook 2013 и 2016.

schizoid04 04.05.2018 17:34

Причина, по которой я спрашивал о ссылках, заключалась в том, что поздняя привязка не сработала, поскольку это не то, что я практиковал раньше, и у меня не было ресурсов для ее устранения, если у меня возникли проблемы с этим, поскольку это не моя основная должностная функция

schizoid04 04.05.2018 17:35

это тоже сработает. просто включите самую раннюю поддерживаемую ссылку, и она позаботится о себе сама. очень немногие вещи не имеют обратной совместимости. ваше здоровье

David Zemens 04.05.2018 17:37

Не имеет прямого отношения к вашему вопросу, но убедитесь, что у вас есть права на распространение библиотек Outlook, если вы планируете связать их со своим приложением.

nicomp 04.05.2018 18:49

Нет, если вы используете предыдущую ссылку, КОГДА вы делаете эту ссылку, вы замечаете, что это жестко заданное имя пути. BEYOND SILLY, чтобы предположить, что более ранняя привязка волшебным образом будет работать с более поздними версиями. Если вы пишете на VB6, FoxPro, C++, .net и т. д., И вы ссылаетесь на конкретную библиотеку, то такой код будет НАСТОЯЩИМ ПЕРЕПАДОМ! Такие ссылки представляют собой жестко запрограммированное имя пути. ЕДИНСТВЕННАЯ причина, по которой доступ "может" работать, заключается в том, что при запуске он пытается изменить ссылки, но на самом деле вы уже нарушили код.

Albert D. Kallal 04.05.2018 21:16

Изменение позднего связывания ОЧЕНЬ незначительно. Если все сделано правильно, необходимо изменить только объект create - остальной код обычно работает как «есть», но некоторые константы должны быть установлены, поскольку компилятор не будет использовать константы, предоставленные указанной библиотекой, на которую вы больше не ссылаетесь.

Albert D. Kallal 04.05.2018 21:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
3 352
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Краткий (-новатый) ответ: Да, можно.

И по вашему второму вопросу; ссылка на библиотеку не должна иметь какого-либо неблагоприятного воздействия, подобного описанному. Я бы сказал, что лучший способ проверить наверняка - это проверить проблему.

Длинный ответ: зачем вам это нужно? IIRC; новая ссылка должна содержать все, что делала старая, с дополнительной библиотечной информацией. Однако, если это почему-то не так и новая ссылка не охватывает проблему, добавление новой ссылки, вероятно, решит проблему, но добавление ссылок на библиотеки волей-неволей не всегда является лучшей практикой.

Я предполагаю, что единственная ссылка на библиотеку Outlook в любом случае решит вашу проблему.

Так следует ли мне просто выбрать последнюю версию библиотеки Outlook? Или мне лучше попробовать перейти на позднюю привязку?

schizoid04 01.05.2018 17:04

Просто используйте поздние привязки. Он решает подобные проблемы. Преобразование в поздние привязки должно быть очень простым.

Erik A 01.05.2018 18:03

Более новая библиотека должна содержать все, что делала старая (обычно). Но более новая библиотека не будет доступна в более старой версии приложения, что является проблемой OP. ЕСЛИ вы должны прикрепить ссылку (а не просто использовать ссылки на объекты с поздней привязкой), я думаю, вам нужно прикрепить версию, поддерживаемую самый ранний.

David Zemens 04.05.2018 14:43

@DavidZemens был прав в этом отношении; Я испытал это вчера через некоторое тестирование. Обновили оп.

schizoid04 04.05.2018 17:41
Ответ принят как подходящий

Если вам нужно использовать раннее связывание, добавьте ТОЛЬКО самую раннюю поддерживаемую ссылку (т. Е. Нет необходимости добавлять ссылку на Outlook 2003, если вы собираетесь поддерживать только 2013+), и он сам позаботится о себе. Очень немногие вещи не имеют обратной совместимости

В противном случае используйте позднее связывание. Это требует использования функции CreateObject вместо ключевого слова New для любого Outlook.__object__.

Примечание, что вам нужно явно объявить константы Outlook, такие как olMailItem, иначе они вызовут ошибки компиляции (при условии, что вы используете Option Explicit):

Option Compare Database
Option Explicit

' InitOutlook sets up outlookApp and outlookNamespace.
Private outlookApp As Object ' Outlook.Application
Private outlookNamespace As  Object ' Outlook.NameSpace

А затем небольшие изменения в теле вашего кода:

Const olMailItem As Long = 0 '## You need to add this enumeration!

Private Sub InitOutlook()
    ' Initialize a session in Outlook
    Set outlookApp = CreateObject("Outlook.Application")

    'Return a reference to the MAPI layer
    Set outlookNamespace = outlookApp.GetNamespace("MAPI")

    'Let the user logon to Outlook with the
    'Outlook Profile dialog box
    'and then create a new session
    outlookNamespace.Logon , , True, False
End Sub

Public Sub SendEmail(varTo As Variant)
    Dim mailItem As Object ' Outlook.mailItem

    InitOutlook
    Set mailItem = outlookApp.CreateItem(olMailItem)
    mailItem.To = varTo & ""
    mailItem.Subject = "subject text"
    mailItem.Body = "Body text"
    mailItem.Display

    Set mailItem = Nothing
    CleanUp
End Sub

Другие вопросы по теме