使用VSTO的Microsoft Access加载项

问题描述 投票:1回答:1

我正在尝试扩展MS Access的功能。我希望用户能够从Access应用程序中触发此功能,理想情况是通过单击我引入的按钮。我希望能够使用C#实现此功能。

如果我的目标是MS Word,Excel,Outlook,PowerPoint,Visio,InfoPath或Project中的任何一个,那么Visual Studio Tools for Office(请参阅here)将是理想的选择。然而,Access要么从未(正式)成为这项计划的一部分,要么就是dropped在很久以前就得到了它的正式支持。对于example,有一家名为Add-In Express的公司似乎支持VSTO和Access,但许可证非常昂贵,如果可以直接完成,我宁愿不涉及第三方软件。 2008年有一篇MS博客文章,其中hack利用了“VSTO加载项项目主要与主机无关的特性”,并将Word加载项转换为Access加载项。这有一个警告:

但请注意,我并不鼓励人们在生产中使用这种方法 - 我们没有测试过这种行为,并且明确表示不支持任何方式。我所做的是探索VSTO如何被设计为与主机无关的最佳设置,以便加载项模型尽可能灵活 - 不会出现旧的“共享”加载项提供的松散类型的极端情况模型。

这种方法是针对this最近的SO问题而提出的,并且显然被提问者成功使用。虽然我担心缺乏官方支持,但这可能足以成为原型而我试图使用它。

按照步骤1到8进行操作后没有任何问题,我点击Debug并启动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 --- 

谷歌搜索“vsto下载文件没有成功”给我带来here,这似乎相关:

问题是Office应用程序正在查找部署清单(.vsto)和应用程序清单(.dll.manifest),但无法找到它们。

我在我的机器上搜索了一个vsto文件扩展名,找到的唯一一个是在我的VS解决方案文件夹中。所以我想也许从博客方法的第6步是错误的,最后一行应该用这个vsto文件的路径替换。然而,这似乎不是问题。

然后我发现这个MSDN article在解决常见的VSTO问题和常见错误4是匹配。列出的“解决方案”是:

当VSTO解决方案试图从域控制器获取证书信息(发布者名称和其他数据)并且超时时,通常会出现此问题。若要解决此问题,请安装此修补程序: - KB 981574。

这链接here这是一个标题为的页面

当您尝试在安装了.NET Framework 3.5 SP1的计算机上启动Excel时,启动屏幕会比平时保持打开状态

这似乎完全不相关。这是一个破损的链接?我不知道该怎么办。

c# visual-studio ms-access plugins office-addins
1个回答
2
投票

我不认为VSTO工具真的值得这么麻烦,而且如果你创建一个“加载项”,那么这个add = in将在所有Access应用程序的Access启动时加载,而不仅限于你的一个申请。并且必须在办公室注册加载项OFTEN将导致Access启动问题。因此,您的加载项必须加载,并加载任何和所有只出于任何原因启动Access的情况。

所有的VSTO工具确实都是为办公室设置了一个com界面,在.net中构建一个“简单”类,然后在访问中从你的VBA按钮中消耗它就不那么麻烦了。

因此,一种简单的方法是“只”从VBA / office代码中使用.net类。与VSTO混淆无论如何都没有多大帮助,随着时间的推移,你将所有的VSTO工作都搞定,你只需要在.net中编写一个简单的类就可以完成并完成。

一些提示:确保您选中.net“register”中的框用于COM互操作。请记住,此选项仅在您的开发计算机上的开发过程中执行一个regasm以方便您使用。

另一个选项(默认设置为!!!)在装配区域中,您只需确保“使装配COM可见”。

对于分发,您必须包含一个小批处理文件或使用安装程序。那个简单的批处理文件或安装程序必须在目标机器(非开发计算机)上执行“regasm”。

并确保您强制项目到x86(假设你使用办公室x32,这肯定是这种情况)。所以不要使用“任何”CPU但强制项目到x86 CPU。

除此之外,就是这个。

这是一个简单的.net类。假设.net 4.5或更高版本,这允许您从Access VBA创建zip文件。

(您需要system.IO.Compression和system.io.compression.Filesystem作为.net项目中的ref。结果是从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())。

但是,以下示例使用早期绑定,但所有这些都将按照上面的方式工作以创建对象。

从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时“皱眉”,但我认为这样的方法很好。互联网上花费所有这些时间创建自定义界面的“例子”实际上只是世界贫困的借口。

最后一个重要提示:不要在您的类中公开任何不兼容的数据类型。如果您(意外或意图)暴露任何与标准“com”对象不兼容的.net对象TYPE,那么您的.net类将编译得很好,但Access将无法正确查看或使用该对象。因此,在实际的上面的类中保持(声明)这些变量和例程是私有的。 (其他代码和部分无关紧要 - 只有一个类是我所说的)。

因此,请勿公开.net长数据类型。如果你坚持使用字符串,标准集合,数组等,那么你应该没问题。而你实际上“可以”将非兼容的对象类型公开为来自.net的“对象”。 (Access中的Intel-sense不会显示对象方法,但您仍然可以使用它们)。

虽然公共函数甚至公共变量对于对象的方法来说都是最简单的,但是这里使用了一个get / set按照“标准”方法来创建类方法。

所以在.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

注意早期绑定,然后Access VBA编辑器将“吐出”类的属性和方法:

例如:

enter image description here

总而言之,使用VSTO通常是一种巨大的过度杀伤力。只需构建一个简单的.net类来展示您需要使用/从VBA调用的内容以及您参加比赛。而其他BIG好处是这个COM对象可以用于Windows脚本,VB6,FoxPro,Excel,Word,power-point等。换句话说,你不限于任何一个平台或JUST访问消费+使用你的简单类您作为COM对象公开。在大多数情况下,我很难为VSTO提供案例。因此,现在可以非常轻松地从任何办公应用程序(VBA代码)使用此对象。

© www.soinside.com 2019 - 2024. All rights reserved.