我目前正在使用类似于以下内容的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中的用户主目录(~/
)中指定共享库的位置?
以下是关于我的环境/方法的一些注意事项:
答案 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目录中文件名的路径;然后在加载之前自动将所需的库复制到该位置。注意另一个进程正在使用的文件,但如果它是你想要的文件的不同版本,那只是一个错误。