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

cky*_*880 6 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)
Run Code Online (Sandbox Code Playgroud)

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

Call sharedLibPassString(myString)
Run Code Online (Sandbox Code Playgroud)

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

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

Environ("HOME")
Run Code Online (Sandbox Code Playgroud)

但是,我没有看到制作CDecl Lib声明这一部分的方法,因为据我所知,它Environ是在运行时进行评估的.

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


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

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

Dan*_*iel 3

抱歉回复太长,我只是想确保我已经很好地解释了这一点。

从这个页面(声明语句的剖析)我们读到

Lib 关键字指定哪个 DLL 包含该函数。请注意,DLL 的名称包含在Declare 语句内的字符串中。(强调已添加)

根据实验,如果我尝试提供除字符串常量之外的任何内容,VBE 会责骂我。

我所知道的唯一解决方法需要在运行时重写字符串常量。

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

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

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

Dim myModule
set myModule = ActivePresentation.VBProject.VBComponents("Module1").CodeModule
Run Code Online (Sandbox Code Playgroud)

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

myModule.ReplaceLine 2, Environ("HOME") & " _"
Run Code Online (Sandbox Code Playgroud)

任务完成!

如果您这样做,您将需要在尝试调用您声明的子程序之前更新路径。执行中必须有一个中断,以便 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
Run Code Online (Sandbox Code Playgroud)