是否可以在用户';VBA中共享库的主目录(在Office for Mac中)?

是否可以在用户';VBA中共享库的主目录(在Office for Mac中)?,vba,ms-office,Vba,Ms Office,我目前正在使用类似于以下内容的VBA代码来指定共享库的位置,以用于从Office应用程序到桌面应用程序的通信(传递字符串)。VBA代码/宏需要存在于外接程序(.ppa)中 在VBA宏的代码中,我可以执行以下操作 Call sharedLibPassString(myString) 我的通信正常,但我想用当前用户的主目录替换/Users/myUserName/部分。通常在Mac上,您会指定~/Library/Application Support/…,但~/语法不起作用,产生“未找到文件”运行时

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

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

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

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

Environ("HOME")
然而,我看不到一种方法可以使这部分成为
CDecl Lib
语句的一部分,因为据我所知,
Environ
是在运行时进行计算的

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


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

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

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

从这一页我们读到

Lib关键字指定包含函数的DLL。注意 DLL的名称包含在声明中的字符串中 陈述 (增加重点)

从实验来看,如果我试图给出字符串常量以外的任何东西,VBE都会责骂我

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

下面是一个如何做到这一点的示例:假设您的delaration语句位于当前项目的模块1中,并且您故意在模块顶部以这种格式编写声明:

Private Declare Sub sharedLibPassString CDecl Lib _
"/Users/myUserName/Library/Application Support/myCompanyName/MySharedLib.dylib" _
Alias "PassString" (ByVal aString As String)
您可以通过此代码访问该模块(需要在“开发人员宏设置”下列出的信任中心中访问VBA的权限):

获得CodeModule后,您可以直接更换第2行:

myModule.ReplaceLine 2, Environ("HOME") & " _"
任务完成

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

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

但是,这里有一个更健壮的解决方案,它将找到正确的行,然后替换它(假设myModule已经按照上面列出的定义):


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

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


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

非常感谢您在这方面的专业知识,以及您非常全面的回复。我能够在演示文稿的上下文中实现这一点,但我没有提到的是,这些宏最终将进入外接程序(.ppa)。据我所知,更换线路不起作用。我假设外接程序是编译代码。你知道在ppa环境下有类似的替代方案吗?我已经更新了原始问题,在外接程序中添加了关于交付的注释。我没有访问Mac的权限,也从未制作过ppa。。。但是我相信你是对的,这个代码不在PPA中工作。我认为您最好的解决方案是确保您的库位于您的程序可以找到它的地方。都是关于声明一个DLL的,虽然它适用于VB6,但它可能是有效的。该页面指出,如果由于未指定路径而找不到您的文件,则它将检查path变量。更新到你想要的可能是一个可行的解决方案。谢谢。尽管将库放置在/usr/bin、/bin等位置。。(在PATH变量中找到的值)在运行时继续产生“未找到文件”错误,将其放置在DYLD_回退_库_路径的任何默认位置似乎都有效。根据您的建议,我将尝试继续研究使用VBA插件设置环境变量的方法。我不确定是否有办法做到这一点,但如果有另一种方法可以在任意用户的计算机上设置环境变量
Dim myModule
set myModule = ActivePresentation.VBProject.VBComponents("Module1").CodeModule
myModule.ReplaceLine 2, Environ("HOME") & " _"
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