Функция VBA Shell в Office 2011 для Mac

Я пытаюсь запустить оболочку script из макроса VBA в Word 2011 для Mac, который будет запускаться в окне терминала. Я попытался использовать как функцию Shell, так и функцию MacScript, но интерпретатор VBA, похоже, не может найти script в любом случае.

В соответствии с справочной документацией VBA должно работать следующее:

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

Это создает ошибку времени выполнения 53 'Файл не найден'.

Любые предложения?

Ответы

Ответ 1

Функция Shell() VBA на Mac, по-видимому, требует полного пути в виде пути в стиле HFS (с двоеточиями вместо косых черт). Он также не принимает аргументы, как в Windows (сообщая об ошибке "Путь не найден", если добавлены какие-либо аргументы).

Также может использоваться функция VBA MacScript(): MacScript("do shell script ""command"""). Вероятно, это будет самый простой вариант, и я бы предложил сделать. Недостатком является то, что у него довольно много накладных расходов (100-200 мс на звонок).

Другой альтернативой является функция 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

См. Http://pubs.opengroup.org/onlinepubs/009604499/functions/system.html для документации.

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

Обратите внимание, что некоторые из аргументов Long в приведенном выше примере являются указателями, поэтому их придется изменить, если когда-либо будет выпущена 64-битная версия Mac Word.

Ответ 2

Надеюсь, вы уже нашли ответ, но вам нужен полный путь:

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

Другой пример что-то вроде:

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

Ответ 3

Другая проблема возникает именно так: разрешения вызывают потерю script из-за различий между средой AppleScript и средой пользователя bash. Этот Q & A помог мне понять это. Чтобы заставить мой script работать, мне пришлось решить некоторые проблемы с путями и разрешениями (не сам script, а все, что коснулось script).

Вот моя рекомендация, которая, надеюсь, дает лучшее понимание во время устранения неполадок, чем бессмысленные ошибки Excel, которые я видел, прежде чем я использовал редактор AppleScript:

  • Используйте редактор AppleScript, чтобы подтвердить, что script работает как любой пользователь и с любой переменной среды, которая используется:

    • В центре внимания, начните вводить "applescript editor" до тех пор, пока он не появится, а затем нажмите на него.
    • Создайте новый файл редактора AppleScript
    • Введите свой простой script в новый файл без удвоения двойных кавычек - мои чтения

      do shell script "parseCsvAndOpen.sh"
      
    • Нажмите кнопку "Запустить" для своего script
    • Отслеживать любые проблемы, вносить изменения и повторять нажатие кнопки "Запустить" до тех пор, пока вы не сможете выполнить ее из редактора AppleScript
      • Хорошая новость заключается в том, что у вас есть более узкий поиск, если вам нужно вернуться в StackOverflow или Google за помощью; -)
  • теперь скопируйте свой простой script из AppleScript Editor в ваш vba и подтвердите, что он все еще работает

    • Мне удалось удвоить двойные кавычки и поместить его в двойные кавычки после кода MacScript:

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

      Это действительно один, два, а затем три символа двойной кавычки! (предположительно, избегая двойных кавычек)

Ответ 4

Просто не хватает очков, чтобы сделать комментарий, но почувствуйте это как дополнение к ответу Робин Найтс. Кредиты конечно еще и для него.
В Excel 15.18 (2015) для вызова open используемого в функции system() из стандартной библиотеки C, больше не требуется ключевое слово --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

Это отлично работает. Не проверял это под 2011.

Ответ 5

Я не нахожу libc.dylib в моем Mac (High Sierra 10.13.6), как мне его установить и где он должен находиться для кода vba, чтобы найти его в Excel Mac 2016?