Надстройка Microsoft Access с использованием VSTO - PullRequest
0 голосов
/ 16 сентября 2018

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

Если я нацелился на MS Word, Excel, Outlook, PowerPoint, Visio, InfoPath, или Project, то Visual Studio Tools for Office (см. здесь ) будет идеальным для этого. Однако, Access никогда не был (официально) частью этой инициативы или был исключен из-за его официальной поддержки довольно давно. Существует компания под названием Add-In Express, которая, похоже, поддерживает VSTO с Access, например, , например, , но лицензия довольно дорогая, и я бы предпочел не привлекать стороннее программное обеспечение, если это можно сделать напрямую. , В 2008 году была опубликована статья в блоге MS с hack , в которой используется «независимая от хоста природа проектов надстроек VSTO» и преобразуется надстройка Word в надстройку Access. Это идет с оговоркой:

Обратите внимание, однако, что я не поощряю людей использовать этот подход в производстве - мы не проверяли это поведение, и оно явно не поддерживается никоим образом. Что я сделал, так это выяснил, как VSTO спроектирован так, чтобы быть оптимально независимым от хоста, чтобы модель надстройки была настолько гибкой, насколько это возможно - не вдаваясь в крайнюю свободную типизацию, предлагаемую старой «общей» надстройкой модель.

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

После выполнения шагов с 1 по 8 без каких-либо проблем, я нажимаю Отладка, и MS Access запускается, а затем выдает следующее сообщение об ошибке:

Microsoft Office Customization Installer
There was an error during installation.

Downloading file:///C:/Temp/MyAddIn/bin/Debug/MyAddIn.vsto did not succeed.

Details:

************** Exception Text **************
System.Deployment.Application.DeploymentDownloadException: Downloading 
file:///C:/Temp/MyAddIn/bin/Debug/MyAddIn.vsto did not succeed. ---> 
System.Net.WebException: Could not find a part of the path 
'C:\Temp\MyAddIn\bin\Debug\MyAddIn.vsto'. ---> System.Net.WebException: 
Could not find a part of the path 'C:\Temp\MyAddIn\bin\Debug\MyAddIn.vsto'. 
---> System.IO.DirectoryNotFoundException: Could not find a part of the path 
'C:\Temp\MyAddIn\bin\Debug\MyAddIn.vsto'.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess 
access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, 
FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean 
bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess 
access, FileShare share, Int32 bufferSize, FileOptions options, String 
msgPath, Boolean bFromProxy)
   at System.Net.FileWebStream..ctor(FileWebRequest request, String path, 
FileMode mode, FileAccess access, FileShare sharing, Int32 length, Boolean 
async)
   at System.Net.FileWebResponse..ctor(FileWebRequest request, Uri uri, 
FileAccess access, Boolean asyncHint)
   --- End of inner exception stack trace ---
   at System.Net.FileWebResponse..ctor(FileWebRequest request, Uri uri, 
FileAccess access, Boolean asyncHint)
   at System.Net.FileWebRequest.GetResponseCallback(Object state)
   --- End of inner exception stack trace ---
   at System.Net.FileWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.Net.FileWebRequest.GetResponse()
   at 
System.Deployment.Application.SystemNetDownloader.DownloadSingleFile
(DownloadQueueItem next)
--- End of inner exception stack trace --- 

Поиск в Google по поводу "загрузка файла vsto не удалась" привел меня здесь , и это показалось актуальным:

Проблема в том, что приложение Office ищет манифест развертывания (.vsto) и манифест приложения (.dll.manifest) и не может их найти.

Я искал расширение файла vsto на моей машине, и единственное, что было найдено, было в папке с моим решением VS. Поэтому я подумал, что, возможно, Шаг 6 из подхода блога был неправильным, и последнюю строку следует заменить на путь к этому файлу vsto. Однако это не проблема.

Затем я нашел эту статью MSDN , посвященную устранению распространенных проблем VSTO, и Common Error 4 совпадает. Перечисленное «решение»:

Эта проблема обычно возникает, когда решение VSTO пытается получить информацию о сертификате (имя издателя и другие данные) от контроллера домена, и время ожидания истекло. Чтобы решить эту проблему, установите это исправление: - KB 981574.

Эта ссылка здесь , то есть страница с названием

Заставка остается открытой дольше обычного, когда вы пытаетесь запустить Excel на компьютере, на котором установлен .NET Framework 3.5 SP1

, который кажется совершенно не связанным. Это неработающая ссылка? Я не уверен, как поступить.

1 Ответ

0 голосов
/ 18 сентября 2018

Я не думаю, что инструменты VSTO действительно стоят того, и, кроме того, если вы создадите «надстройку», то такая надстройка будет загружаться при запуске Access для ВСЕХ приложений Access, а неограничено вашим одним приложением.А необходимость регистрации надстройки в офисе OFTEN приведет к проблемам при запуске в Access.Таким образом, ваша надстройка должна будет загружаться и загружаться для ЛЮБОГО и ВСЕХ случаев, когда Access по какой-либо причине просто запускается.

Все инструменты VSTO действительно настраивают com-интерфейс для офиса, и на самом деле гораздо проще создать «простой» класс в .net, а затем использовать его с помощью кнопки VBA при доступе.

Таким образом, простой подход состоит в том, чтобы «просто» использовать класс .net из кода VBA / office.Взаимодействие с VSTO на самом деле не очень помогает, и к тому времени, когда вы получите все, что работает с VSTO, вы уже давно закончите, просто написав простой класс в .net.

Несколько советов: убедитесь, что вы проверилиполе в .net «регистр» для COM-взаимодействия.Имейте в виду, что эта опция ТОЛЬКО выполняет регазм для вашего удобства во время процесса разработки на вашем компьютере разработчика.

Другая опция (которая по умолчанию установлена ​​по умолчанию !!!) находится в области сборки, и вы простодолжны убедиться, что «сделать сборку видимой для COM).

Для распространения вам нужно будет включить небольшой пакетный файл или использовать установщик.Этот простой пакетный файл или установщик должен выполнить «regasm» на целевых машинах (вы не компьютер dev).

И убедитесь, что вы форсируете проект на x86 (при условии, что вы используете Office x32, что, безусловно, имеет место).Поэтому НЕ используйте «любой» процессор, но принудительно применяйте проект к процессору x86.

Кроме того, вот и все.

Вот простой класс .net.Предполагая .net 4.5 или новее, это позволяет вам создавать zip-файлы из Access VBA.

(вам нужны как system.IO.Compression, так и system.io.compression.Filesystem в качестве ссылок в вашем проекте .net.Результатом является архивирование файлов из Access без каких-либо сторонних инструментов.

Таким образом, класс в .net выглядит так:

Imports System.Runtime.InteropServices
Imports System.IO.Compression
Imports System.IO

<ClassInterface(ClassInterfaceType.AutoDual)>
Public Class AlbertCom1

Private m_Times2 As Integer

Public Sub MsgHello()

    MsgBox("Hello world", MsgBoxStyle.Information, "VB.net example")

End Sub

Public Sub MyZipper(strFileName As String, strZipFile As String)

    Using archive As ZipArchive = ZipFile.Open(strZipFile, ZipArchiveMode.Update)
        archive.CreateEntryFromFile(strFileName, Path.GetFileName(strFileName), CompressionLevel.Fastest)
    End Using

End Sub

Public Function GetConValue(strSetting As String) As String

    ' read a simple value from config file
    Return My.Settings(strSetting).ToString

End Function

Public Property Times2 As Integer
    Get
        Return m_Times2
    End Get
    Set(value As Integer)
        m_Times2 = value * 2
    End Set
End Property

End Class

Таким образом, вышеприведенный текст довольно прост и короток.

В Access VBA за нашей кнопкой мы можем использовать следующий код:

Вызовите / используйте метод окна сообщения Hello сверху:

Sub TestCOMHello()

  Dim mycom      As Object
  Set mycom = CreateObject("AlbertCom1.AlbertCom1")

  mycom.MsgHello

End Sub

Обратите внимание, как указано выше привязка LATE -это будет работать без ссылки в VBA на объект. (поэтому требуется createObject ()).

Однако в следующих примерах используется раннее связывание, но все будет работать, как описано выше, для создания объекта.

Zip-файл из VBA:

Sub TestCOMZip()

  Dim strFromFile      As String
  Dim strToFile        As String

  Dim mycom      As New AlbertCom1.AlbertCom1

  strFromFile = "c:\test\data.txt"
  strToFile = "c:\test\data.zip"

  mycom.MyZipper strFromFile, strToFile


End Sub

Еще несколько советов:

Вам не нужно создавать пользовательский интерфейс в своем классе, и многие "хмурились"«При использовании AutoDual, я думаю, что такой подход очень хорош.«Примеры» в Интернете, которые тратят все это время на создание пользовательского интерфейса, на самом деле являются лишь оправданием мировой бедности.

Последний большой совет: НЕ выставляйте в своем классе несовместимые типы данных.Если вы выставите (случайно или преднамеренно) какой-либо .NET-объект TYPE, который не совместим со стандартными объектами «com», тогда ваш .net-класс будет хорошо скомпилирован, но Access не будет правильно видеть или потреблять объект.Поэтому сохраняйте (объявляйте) эти переменные и процедуры как частные в фактическом классе.(Другой код и части не имеют значения - я говорю только об одном классе).

Так что, например, не раскрывайте тип данных .net long.Если вы придерживаетесь строк, стандартных коллекций, массивов и т. Д., То все будет в порядке.И вы на самом деле «можете» выставлять несовместимые типы объектов как «объект» из .net.(Intel Access в Access не будет показывать методы объектов, но вы все равно можете их использовать).

И хотя публичные функции и даже публичные переменные наиболее просты для ваших методов объекта, здесь используетсяполучить / установить в соответствии со «стандартным» подходом к тому, как создаются методы класса.

Итак, в .net у нас есть:

Public Property Times2 As Integer
    Get
        Return m_Times2
    End Get
    Set(value As Integer)
        m_Times2 = value * 2
    End Set
End Property

А в вашем VBA-коде мы имеем:

Sub TestTimes()

   Dim mycom     As New AlbertCom1.AlbertCom1

   mycom.Times2 = 40

   Debug.Print mycom.Times2

End Sub

output: 80

NОтметьте для раннего связывания, тогда редактор Access VBA «выплюнет» свойства и методы класса:

Например:

enter image description here

В целом использование VSTO - это ОГРОМНОЕ излишество.Просто создайте простой класс .net, чтобы показать, что вам нужно использовать / вызывать из VBA, и вы отправляетесь в гонки.И еще одно БОЛЬШОЕ преимущество - это то, что этот COM-объект можно использовать из сценариев Windows, VB6, FoxPro, Excel, Word, Power-Point и т. Д. Другими словами, вы не ограничены какой-либо одной платформой или JUST Access для использования + использования вашего простого класса.Вы выставляете как COM-объект.В большинстве случаев мне трудно представить аргументы в пользу ВСТО.Таким образом, этот объект теперь может быть легко использован из ЛЮБОГО офисного приложения (код VBA).

...