是否可以在用户的​​主目录中为VBA中的共享库指定位置(在Office for Mac中)?

时间:2012-10-30 12:36:01

标签: vba ms-office

我目前正在使用类似于以下内容的VBA代码来指定共享库的位置,以便在从Office应用程序到桌面应用程序进行通信(传递字符串)时使用。 VBA代码/宏需要存在于加载项(.ppa)中。

Private Declare Sub sharedLibPassString CDecl Lib "/Users/myUserName/Library/Application Support/myCompanyName/MySharedLib.dylib" Alias "PassString" (ByVal aString As String)

在VBA宏的代码中,我可以执行以下操作。

Call sharedLibPassString(myString)

我的通讯工作正常,但我想用当前用户的主目录替换/Users/myUserName/部分。通常在Mac上,您指定~/Library/Application Support/...,但~/语法不起作用,产生“找不到文件”运行时错误。

我发现使用以下环境变量方法可以获得我需要的~/位置:

Environ("HOME")

但是,我没有看到将CDecl Lib语句作为这一部分的方法,因为据我所知,Environ在运行时被评估。

有没有办法在VBA中的用户主目录(~/)中指定共享库的位置?


以下是关于我的环境/方法的一些注意事项:

  • 我正在使用Mac,但我相信如果有解决方案,它会在PC上类似。
  • 我不认为这不重要,但我正在使用的Office应用程序是PowerPoint(2011)。
  • 我试图访问Application Support目录中的某个区域而不是共享库的默认位置的原因是因为我希望桌面应用程序将共享库放在没有安装程序的位置,并且无需用户或管理员的权限。如果有更好的解决方案或位置来完成相同的任务,这也将非常有用。

2 个答案:

答案 0 :(得分:2)

很抱歉给出了很长的回复,我只是想确保我解释得这么好。

从这个页面(Anatomy of a Declare Statement)我们读到了

  

Lib关键字指定哪个DLL包含该函数。注意   DLL的名称包含在Declare中的字符串中   声明。   (重点补充)

从实验中,如果我尝试提供除字符串常量之外的任何东西,VBE就会骂我。

我所知道的唯一工作需要在运行时重写字符串常量。

以下是一个如何完成此操作的示例:假设您的delaration语句位于当前项目的Module1中,并且您故意在模块顶部以此格式编写声明:

Private Declare Sub sharedLibPassString CDecl Lib _
"/Users/myUserName/Library/Application Support/myCompanyName/MySharedLib.dylib" _
Alias "PassString" (ByVal aString As String)

您可以通过此代码访问该模块(需要在开发人员宏设置下列出的信任中心的VBA权限):

Dim myModule
set myModule = ActivePresentation.VBProject.VBComponents("Module1").CodeModule

获得CodeModule后,您可以直接替换第二行:

myModule.ReplaceLine 2, Environ("HOME") & " _"

完成任务!

如果这样做,则需要在尝试调用声明的子代码之前更新路径。执行必须中断,允许VBA识别更改。此外,在中断模式下,您将无法修改代码。

现在,如果我这样做,我想确保替换正确的行,以免破坏代码。您可以通过调用此myModule.Lines(2,1)来检查第二行的内容,这将返回该行的字符串值。

但是,这是一个更强大的解决方案,它将找到正确的行,然后替换它(假设myModule已经定义如上所列):

Dim SL As Long, EL As Long, SC As Long, EC As Long
Dim Found As Boolean
SL = 1     ' Start on line 1
SC = 1     ' Start on Column 1
EL = 99999 ' Search until the 99999th line
EC = 999   ' Search until the 999th column
With myModule
    'If found, the correct line will be be placed in the variable SL
    'Broke search string into two pieces so that I won't accidentally find it.
    Found = .Find("/Users/myUserName/Library/Application Support/myCompanyName/" & _
             "MySharedLib.dylib", SL, SC, EL, EC, True, False, False)
    If Found = True Then
        'Replace the line with the line you want, second paramater should be a string of the value.
        .ReplaceLine SL, Environ("HOME") & " _"
    End If
End With

答案 1 :(得分:2)

我没有Mac,所以这是一个不完整的答案,我不知道它是否会有所帮助,但这是一些想法。

我知道在Windows上,在你第一次尝试调用用它声明的函数之前,VB不会加载外部库,如果你只在declare语句中指定文件名,它将使用系统路径来查找它。一旦我做了同样的事情,从动态路径加载库,只指定文件名,然后进行系统API调用,将当前工作目录设置为库的目录,然后再加载它。更改PATH环境变量可能也有效。

第二个想法:你可以硬编码/ tmp目录中文件名的路径;然后在加载之前自动将所需的库复制到该位置。注意另一个进程正在使用的文件,但如果它是你想要的文件的不同版本,那只是一个错误。