Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VBA Shell function in Office 2011 for Mac

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 MacScript function, but the VBA interpreter doesn't seem to be able to find the script in either case.

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

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

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

Any suggestions?

like image 592
Francis Cave Avatar asked May 26 '11 10:05

Francis Cave


People also ask

Does Office for Mac have VBA?

Outlook for Mac and OneNote for Mac don't support VBA.

How do I enable VBA in Excel for Mac?

Shortcut Key (Window) You can also use the keyboard shortcut key Alt + F11 to open the VBE in windows and Opt + F11 or Fn + Opt + F11 for MAC.

How do I run a shell command in VBA?

In Windows, the shell is commonly known as the Command Prompt. To access it, click on the Windows button and type cmd (Windows 10). Windows finds the program for you, so click on it to start it.

What is the shortcut to open VBA in Excel for Mac?

It can be opened by clicking the Visual Basic button on the Developer tab in Excel. The keyboard shortcut to open the VB Editor in any Windows version of Excel is Alt + F11 . The shortcut in the Mac version is Opt + F11 or Fn + Opt + F11 .


1 Answers

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).

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).

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

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.html for documentation.

system() only returns the exit code. If you want to get the output from the command, you could use 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 Long arguments in the above example are pointers, so will have to be changed if a 64bit version of Mac Word is ever released.

like image 59
Robert Knight Avatar answered Sep 23 '22 01:09

Robert Knight