Office 2011 for Mac 中的 VBA Shell 函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6136798/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 11:31:34  来源:igfitidea点击:

VBA Shell function in Office 2011 for Mac

macosshellvbaexcel-vba-mac

提问by Francis Cave

I am trying to launch a shell script from a VBA macro in Word 2011 for Mac that will run in a Terminal window. I have tried using both the Shell function and the MacScriptfunction, but the VBA interpreter doesn't seem to be able to find the script in either case.

我正在尝试从 Word 2011 for Mac 中的 VBA 宏启动一个 shell 脚本,该脚本将在终端窗口中运行。我曾尝试同时使用 Shell 函数和MacScript函数,但 VBA 解释器似乎无法在任何一种情况下找到脚本。

According to the VBA reference documentation, the following should work:

根据 VBA 参考文档,以下应该有效:

 RetVal = Shell("Macintosh HD:Applications:Calculator.app", vbNormalFocus)

This produces a run-time error 53 'File not found'.

这会产生运行时错误 53“找不到文件”。

Any suggestions?

有什么建议?

回答by Robert Knight

The Shell()VBA function on Mac appears to require the full path as an HFS-style path (with colons instead of slashes). It also doesn't appear to accept arguments as it does on Windows (reporting a 'Path not found' error if any arguments are added).

Shell()Mac 上的VBA 函数似乎需要完整路径作为 HFS 样式的路径(使用冒号而不是斜杠)。它似乎也不像在 Windows 上那样接受参数(如果添加了任何参数,则会报告“找不到路径”错误)。

The MacScript()VBA function can also be used: MacScript("do shell script ""command"""). This is likely to be the simplest option and what I would suggest doing. The downside is that it has quite a lot of overhead (100-200ms per call).

MacScript()VBA函数也可以用:MacScript("do shell script ""command""")。这可能是最简单的选择,也是我建议做的。缺点是它有相当多的开销(每次调用 100-200 毫秒)。

Another alternative is the system()function from the standard C library:

另一种选择是system()标准 C 库中的函数:

Private Declare Function system Lib "libc.dylib" (ByVal command As String) As Long

Sub RunSafari()
    Dim result As Long
    result = system("open -a Safari --args http://www.google.com")
    Debug.Print Str(result)
End Sub

See http://pubs.opengroup.org/onlinepubs/009604499/functions/system.htmlfor documentation.

有关文档,请参阅http://pubs.opengroup.org/onlinepubs/009604499/functions/system.html

system()only returns the exit code. If you want to get the output from the command, you could use popen().

system()只返回退出代码。如果你想从命令中获取输出,你可以使用popen().

Private Declare Function popen Lib "libc.dylib" (ByVal command As String, ByVal mode As String) As Long
Private Declare Function pclose Lib "libc.dylib" (ByVal file As Long) As Long
Private Declare Function fread Lib "libc.dylib" (ByVal outStr As String, ByVal size As Long, ByVal items As Long, ByVal stream As Long) As Long
Private Declare Function feof Lib "libc.dylib" (ByVal file As Long) As Long

Function execShell(command As String, Optional ByRef exitCode As Long) As String
    Dim file As Long
    file = popen(command, "r")

    If file = 0 Then
        Exit Function
    End If

    While feof(file) = 0
        Dim chunk As String
        Dim read As Long
        chunk = Space(50)
        read = fread(chunk, 1, Len(chunk) - 1, file)
        If read > 0 Then
            chunk = Left$(chunk, read)
            execShell = execShell & chunk
        End If
    Wend

    exitCode = pclose(file)
End Function

Sub RunTest()
    Dim result As String
    Dim exitCode As Long
    result = execShell("echo Hello World", exitCode)
    Debug.Print "Result: """ & result & """"
    Debug.Print "Exit Code: " & str(exitCode)
End Sub

Note that several of the Longarguments in the above example are pointers, so will have to be changed if a 64bit version of Mac Word is ever released.

请注意,Long上面示例中的一些参数是指针,因此如果发布了 64 位版本的 Mac Word,则必须对其进行更改。

回答by brwnj

Hopefully you've found the answer by now but you just need the full path:

希望您现在已经找到了答案,但您只需要完整路径:

RetVal = Shell("Macintosh HD:Applications:Calculator.app:" & _
              "Contents:MacOS:Calculator", vbNormalFocus)

Another example is something like:

另一个例子是这样的:

RetVal = Shell("Macintosh HD:Users:brownj:Documents:" & _
              "rnaseq:IGV_2.0.14:igv.sh", vbNormalFocus)

回答by sage

Another problem presents exactly like this: permissions cause your script to fail due to differences between the AppleScript environment and your user's bash environment. This Q&A helped me figure this out. To get my script to work, I had to resolve some path and permissions issues (not the script itself, but things touched by the script).

另一个问题完全是这样的:由于 AppleScript 环境和您用户的 bash 环境之间的差异,权限会导致您的脚本失败。这个问答帮助我解决了这个问题。为了让我的脚本工作,我必须解决一些路径和权限问题(不是脚本本身,而是脚本触及的问题)。

Here is my recommendation, which hopefully gives better insight during your troubleshooting than the meaningless Excel errors I was seeing before I used AppleScript Editor:

这是我的建议,与我在使用 AppleScript 编辑器之前看到的无意义的 Excel 错误相比,它有望在您的故障排除过程中提供更好的洞察力:

  1. Use AppleScript Editor to confirm that the script actually works as whatever user and with whatever environment variable happens to be used:

    1. In Spotlight, start typing "applescript editor" until it shows up and then click on it
    2. Create a new AppleScript Editor file
    3. Type your simple script into the new file withoutdoubling the double quotes - mine reads

      do shell script "parseCsvAndOpen.sh"
      
    4. Hit the "Run" button for your script
    5. Track down any issues, make changes, and repeat hitting the "Run" button until you get it to execute from within AppleScript Editor
      • The good news here is that you have a narrower search if you need to go back to StackOverflow or Google for help ;-)
  2. now copy your simple script from AppleScript Editor to your vba and confirm it still works

    1. I was able to just double my double quotes and put it in double quotes after the MacScript code:

      MacScript "do shell script ""parseCsvAndOpen.sh"""
      

      That is indeed one, two, and then three double-quote characters! (presumably escaping the double quotes)

  1. 使用 AppleScript 编辑器确认该脚本实际上可以作为任何用户和碰巧使用的任何环境变量工作:

    1. 在 Spotlight 中,开始输入“applescript editor”直到它出现,然后单击它
    2. 创建一个新的 AppleScript 编辑器文件
    3. 将您的简单脚本输入到新文件中,无需将双引号加倍 - 我的读取

      do shell script "parseCsvAndOpen.sh"
      
    4. 点击脚本的“运行”按钮
    5. 跟踪任何问题,进行更改,然后重复点击“运行”按钮,直到您在 AppleScript 编辑器中执行它
      • 好消息是,如果您需要返回 StackOverflow 或 Google 寻求帮助,您的搜索范围将缩小;-)
  2. 现在将您的简单脚本从 AppleScript 编辑器复制到您的 vba 并确认它仍然有效

    1. 我能够将双引号加倍,并在 MacScript 代码之后将其放在双引号中:

      MacScript "do shell script ""parseCsvAndOpen.sh"""
      

      那确实是一个,两个,然后三个双引号字符!(大概是转义双引号)

回答by Lord iPhonius

Just not enough points to make a comment, but feel this as an addition to Robin Knights answer. Credits of course still to and for him.
For Excel 15.18 (2015) the opencall used in the system()function from the standard C library doesn't need the --argskeyword anymore:

只是没有足够的分数来发表评论,但觉得这是对 Robin Knights 回答的补充。学分当然仍然属于他。
对于 Excel 15.18 (2015),标准 C 库函数中open使用的调用system()不再需要--args关键字:

Private Declare Function system Lib "libc.dylib" (ByVal command As String) As Long

Sub RunSafari()
    Dim result As Long
    result = system("open -a Safari http://www.google.com")
    Debug.Print Str(result)
End Sub

This works fine. Didn't test this under 2011.

这工作正常。没有在 2011 年测试这个。