Пожалуйста, помогите мне запустить скрипт Python из Excel 365 VBA на Mac Mini с Big Sur

Мой первый вопрос на эту тему был закрыт из-за недостаточной конкретики, поэтому я попытаюсь рассказать вам, что я пробовал до сих пор, но это не сработало. Я пытаюсь перенести книги Excel 2010 на свой новый компьютер Mac mini Big Sur с помощью Office 365. Это мой первый Mac, поэтому я очень плохо знаком с операционной системой и отличиями от мира Microsoft. Кроме того, я впервые использую Office 365. Я надеюсь, что вы будете достаточно любезны, чтобы помочь мне. В своих макросах VBA я запускаю скрипты Python для сбора данных с веб-страниц. Обычно скрипт Python создает файл .csv, который затем открываю в макросе VBA для чтения и заполнения необходимых ячеек в рабочей книге. Это код, который я использую в версии для ПК для вызова скрипта Python:

Kill strFileOfData
Set objWsh = VBA.CreateObject("WScript.shell")
strPython = """C:\Users\Phil\AppData\Local\Programs\Python\Python37-32\python.exe"""
strPyScript = """C:\Users\Phil\Documents\PyScripts\GetMarketsStks1-0.py"""
objWsh.Run strPython & strPyScript
Err = 0
Do Until Dir(StrFileOfData) <> 0
  Application.Wait (Now() + TimeValue("0:00:01"))
Loop

Это может быть не самое лучшее, но оно надежно работает на ПК. Сначала я удаляю файл данных, запускаю скрипт Python, жду, пока файл данных будет создан, затем продолжаю. Я установил последнюю версию Python на Mac и переписал скрипт Python, чтобы получить больше данных, и запустил скрипт Python в Терминале, чтобы убедиться, что он выполняется правильно. Он работал нормально и правильно создал файл .csv. Затем я изменил код в макросе VBA, чтобы учесть различные файловые структуры. Это новый код:

Kill strFileOfData
Set objWsh = VBA.CreateObject("WScript.shell")
strPython = """/Library/Frameworks/Python.framework/Python"""
strPyScript = """/Users/minime/MyDocuments/Finance/GetHistory1-0.py"""
objWsh.Run strPython & strPyScript

Err = 0
Do Until Dir(StrFileOfData) <> 0
  Application.Wait (Now() + TimeValue("0:00:01"))
Loop

Когда я запускаю это на Mac, я получаю:

Ошибка выполнения «429»: компонент ActiveX не может создать объект

Подозревая, что это разница в способах создания и использования оболочек, я начал исследовать, как вызывать Python из Excel на Mac. После значительных тупиков я нашел этот поток 4 года назад: Как запустить внешний процесс Python из Excel 365 VBA в OSX?

Я пытался просто идти вперед и следовать инструкциям. Я немного узнал об AppleScript, добавил папку: ~/Library/Application Scripts/com.microsoft.Excel/, создал AppleScript с именем PythonCommand.scpt и поместил его в эту папку. Поскольку я не смог найти путь в примере, я заменил его тем, что я считал правильным путем, предполагая, что это произошло из-за разницы в MacOS с 4-летней давности. Мой AppleScript выглядит так:

on PythonCommand(pythonScript)
   do shell script "/Library/Frameworks/Python.framework/Python" & pythonScript
end PythonCommand

Затем я добавил этот код в макрос VBA:

strPyScript = """/Users/minime/MyDocuments/Finance/GetHistory1-0.py"""
Dim result As String
result = AppleScriptTask("PythonCommand.scpt", "PythonCommand", strPyScript)

Когда я запустил макрос VBA. Я получил это сообщение:

Ошибка выполнения «13»: несоответствие типов

Я попробовал еще раз с одинарными кавычками вместо тройных и получил тот же результат. Я пытался работать в обратном порядке, чтобы убедиться, что части работают. Я снова без проблем запустил скрипт Python из окна терминала, поэтому следующим шагом, который я попробовал, был запуск AppleScript из IDLE. Я набрал это:

AppleScriptTask("PythonCommand.scpt", "PythonCommand","/Users/minime/MyDocuments/Finance/GetHistory1-0.py")

и получил такой результат:

Трассировка (последний последний вызов): файл ‹pyshell#0›, строка 1, в AppleScriptTask(PythonCommand.scpt, PythonCommand,/Users/minime/My Documents/Finance/GetHistory1-0.py) NameError: name 'AppleScriptTask' is не определено

После дополнительных исследований я попробовал этот AppleScript в редакторе:

do shell script "/Library/Frameworks/Python.framework/Versions/3.9/Python /Users/minime/MyDocuments/Finance/GetHistory1-0.py"

Я получил этот результат:

ошибка sh: /Library/Frameworks/Python.framework/Versions/3.9/Python: невозможно выполнить двоичный файл номер 126

Далее я попробовал это:

do shell script "Python /Users/minime/MyDocuments/Finance/GetHistory1-0.py"

и получил это:

error "Traceback (most recent call last):
  File \"/Users/philipackermann/MyDocuments/Finance/GetHistory1-0.py\", line 2, in <module>
    from urllib.request import urlopen
ImportError: No module named request" number 1

Это действительно может быть некоторый прогресс! Этот оператор импорта является первой строкой кода в моем скрипте Python, но я понятия не имею, почему он зашел дальше, чем предыдущая попытка, и почему он работает иначе, чем выполнение скрипта Python в Терминале. Но я только что заметил, что в терминале я ввожу Python3, поэтому я попробовал это:

do shell script "Python3 /Users/minime/MyDocuments/Finance/GetHistory1-0.py"

и получил всплывающее окно с ошибкой сценария: введите здесь описание изображения и это: введите здесь описание изображения

Прочитав больше о терминале, я понял, что на Mac есть скрытые файлы, поэтому я попробовал этот AppleScript:

do shell script "/usr/local/bin/Python3 /Users/minime/MyDocuments/Finance/GetHistory1-0.py"

И это сработало!! CSV-файл успешно создан. Итак, теперь мне нужно выяснить, как вызвать это из Excel. Я нашел статью здесь:

https://stackoverflow.com/questions/38723420/how-to-simply-run-an-applescript-task-from-mac-excel-2016

Это действительно работает. Я преобразовал AppleScript в приложение (просто изменил расширение с scpt на app) и переместил его в папку «Приложения», а затем поместил этот код в макрос VBA:

ThisWorkbook.FollowHyperlink Address:="/Applications/RunGetHistory.app", NewWindow:=True

Это сработало! Конечно, он не передает никаких аргументов и не получает никаких результатов. Одна проблема, однако, как и в моей предыдущей версии для ПК, код не ждет завершения приложения, поэтому мне нужен способ проверить, будет ли это сделано, и поскольку я изменил скрипт Python, чтобы открыть файл в начале и написать строки для него при очистке веб-страниц файл создается сразу, поэтому этого кода, который я использовал в версии для ПК, недостаточно:

Do Until Dir(strFileNmHistory) <> ""
    Application.Wait (Now() + TimeValue("0:00:01"))
Loop

Я полагаю, я мог бы добавить отдельный файл, написанный в конце скрипта Python, просто чтобы сказать, что это сделано, но это довольно хромой хак. Так что технически, я думаю, я мог бы сказать, что решил эту проблему и МОЖЕТ запустить скрипт Python из Excel, но я должен верить, что есть лучший способ, и я уверен, что в этом сообществе есть люди намного умнее меня, которые могут сделать это лучше. Кто-нибудь смог заставить работать решение 4-летней давности? Это может решить проблемы с аргументами, результатами и ожиданием завершения скрипта Python. Любые предложения, которые вы можете сделать, будут наиболее полезными. Я тщательно исследовал эту проблему, и в некоторых ответах говорилось, что песочница не позволяет Excel запускать Python, но если мы сможем запустить приложение, которое запускает скрипт Python, я думаю, это обойдется. Если вы можете прокомментировать конкретные ошибки, с которыми я столкнулся выше, я попробую разные подходы и отчитаюсь. Пожалуйста помоги. Фил


person Phil    schedule 13.06.2021    source источник
comment
С помощью VaughanR я узнал, как правильно редактировать и размещать AppleScript и запускать его с помощью команды AppleScriptTask в VBA. Вот ссылка на этот пост: stackoverflow.com/questions/67994030/ AppleScript, который я использовал для этого упражнения, просто имел возврат в нем и успешно вернулся аргумент, который я передал. Однако, когда я попытался вызвать скрипт Python, я получил то же сообщение об ошибке 5:.   -  person Phil    schedule 26.06.2021
comment
Мне кажется, что одно и то же сообщение Erroe5: может быть вызвано несколькими проблемами: если первый аргумент (имя AppleScript) не разрешается, если AppleScript правильный, но имя команды не разрешается, и (где я думаю, что я сейчас), если командный вызов сценария Python неверен или имеет какую-либо другую проблему.   -  person Phil    schedule 26.06.2021


Ответы (1)


РЕШЕНО! ...и я многому научился на этом пути! Я постараюсь изложить только шаги, необходимые для этой работы, но я склонен к бессвязности, извините. Одна проблема, которая делала это сложнее, чем должна была быть, была проста: мне не хватало пробела в операторе do shell script в AppleScript. Вот код VBA, который работает для меня:

Result = AppleScriptTask("PythonCommand.scpt", "PythonCommandHandler", "/Users/minime/MyDocuments/Finance/PythonScripts/GetHistory1-0.py")

Вот код AppleScript:

on PythonCommandHandler(pythonScript)
    do shell script "/usr/local/bin/Python3 " & pythonScript
    return "Handler succeeded!  " & pythonScript
end PythonCommandHandler

Обратите внимание на пробел после Python3. Создайте AppleScript в удобной папке и скопируйте его в /Users/minime/Library/Application Scripts/com.microsoft.Excel

Попытка отредактировать его в этой папке проблематична, поверьте мне. Переместите его туда. Сценарий Python может быть где угодно, если вы укажете путь в команде AppleScriptTask в коде VBA.

Убедитесь, что все ссылки на CSV-файлы указывают на папку песочницы Excel. Я использовал этот, но подозреваю, что другие тоже будут работать: /Users/minime/Library/Containers/com.microsoft.Excel/Data/Documents

См. примечания ниже, если вы не можете найти эту папку. Это сработало 01.07.2021! Посмотрим, что будет, когда выйдет новая OS X. Вызов AppleScriptTask ожидает полного выполнения сценария Python, прежде чем продолжить. Я еще не придумал хороший способ обработки ошибок в скрипте Python.

Вот несколько заметок о важных вещах, которые я узнал в процессе работы и которые могут быть полезны начинающим пользователям Mac, таким как я:

  1. ИЗМЕНИТЕ ШРИФТ РЕДАКТОРА VBA. Хорошо, на самом деле это не обязательно, но шрифт по умолчанию для редактора VBA в версии Mac Excel 365, которую я использую, не был пропорциональным шрифтом, поэтому такие вещи, как часть операторов Dim, не выстраивались для меня. Может быть, небольшая, но большая неприятность легко решается: в редакторе щелкните слово Excel в строке меню (верхний ряд слов и значков). Нажмите «Настройки», и появится окно с заголовком «Параметры». Перейдите на вкладку «Формат редактора» и выберите Courier New в раскрывающемся списке «Шрифт». Я изменил размер: на 16. Да, и, кстати, Command, shift, я проведу вас через код VBA, как это делает F8 на ПК.
  2. ПОМЕСТИТЕ НЕКОТОРЫЕ ФАЙЛЫ В ПЕСОЧНИЦУ. Несколько слов о песочнице, которые, я уверен, другие могли бы объяснить лучше, чем я. Для повышения безопасности концепция песочницы должна ограничивать код от выполнения чего-либо за пределами его ожидаемой области: например. вы бы не хотели, чтобы ошибка в вашем коде (или вредоносный код) изменила некоторые системные настройки, которые не имеют ничего общего с тем, что вы намеревались. Я понимаю. Хорошая концепция. В древние времена (мейнфреймы) мы получили SOC 1 для такого типа проблем. Песочница — это часть компьютера, в которой вам разрешено играть. Не пытайтесь выйти за его пределы (есть исключения, которые я еще не совсем понимаю). На Mac это означает, что если вы даже попытаетесь сделать что-либо с файлом .csv в своем коде VBA, которого нет в песочнице, вы получите предупреждение о том, что вам нужно предоставить разрешение, чтобы это произошло. Рабочая книга Excel с кодом VBA не обязательно должна находиться в песочнице, потому что важно то, что исполняемый файл Excel находится в песочнице (я полагаю), и ему разрешено обращаться к вашей книге (исключение из правила?) и делать все, что вы просили, включая запуск вашего кода VBA с ограничениями. AppleScript также должен быть в песочнице, а скрипт Python — нет (не знаю почему). Нас здесь интересует только песочница Excel, там, видимо, разные для разных приложений. Теперь несколько слов об псевдонимах. Для простоты считайте, что ваша песочница Excel находится здесь: /Users/philipackermann/Library/Containers/com.microsoft.Excel. Здесь находится псевдоним: /Users/philipackermann/Library/Containers/com.microsoft.Excel/Data/Library/ Сценарии приложений/com.microsoft.Excel Перемещение файла в один волшебным образом переместит файл и в другой. Кстати, первый com.microsoft.Excel в этом псевдониме будет отображаться как Microsoft Excel в Finder, если вы попытаетесь найти его, пройдя путь с самого начала. Да, кстати, Command, shift, . позволит вам увидеть скрытые папки и файлы в Finder. Это понадобится вам для начала. Если я правильно понимаю, значки папок в Finder со стрелочкой в ​​левом нижнем углу указывают на то, что папка является псевдонимом (или имеет псевдоним, указывающий на нее? Я не уверен). Папка, которую я использовал для файлов .csv, не является псевдонимом или не имеет псевдонима), поэтому мне пришлось использовать очень длинный путь. Таким образом, книга Excel и сценарий Python не должны находиться в песочнице, но AppleScript и файлы .csv должны быть там.
  3. НЕ РЕДАКТИРОВАНИЕ В ПАПКЕ Псевдонимов SANDBOX! Проверьте ссылку, которую я упомянул в комментариях выше, с VaughanR. Он помог мне лучше понять проблему с псевдонимами. Спасибо VaughanR. Попытка редактирования в этих папках была безумным и бесполезным занятием. Избавьте себя от травм и отредактируйте свой AppleScript в локальной папке и скопируйте его в папку песочницы. Я сделал это, открыв два окна Finder (одно с локальной папкой и одно с папкой песочницы) и удерживая нажатыми клавиши Command и Option, перетаскивая файл AppleScript из локальной папки в папку песочницы.
  4. ПРОВЕРЬТЕ APPLESCRIPT В РЕДАКТОРЕ СЦЕНАРИЙ. Как я уже упоминал в другом месте, эта надоедливая ошибка 5: может появиться по ряду причин. В редакторе сценариев добавьте эту строку над оператором PythonCommandHandler on: PythonCommandHandler(GetHistory1-0.py) и запустите ее в редакторе, чтобы убедиться, что она делает то, что вы хотите. Вот так я обнаружил проблему с отсутствующим пространством и протестировал разные пути, чтобы запустить его.
  5. РАЗНОЕ ПРИМЕЧАНИЯ EXCEL. Если вы пытаетесь перенести книги Excel из среды Windows на Mac, обратите внимание на следующие проблемы, с которыми я уже сталкивался: SORTS. У меня были жестко запрограммированные сортировки в моем коде VBA, которые вызывали сбой Excel, когда я пытался запустить их на Mac. Я записал сортировку, и она отлично работает в коде. На Mac НЕТ ПОЛЬЗОВАТЕЛЬСКИХ ФОРМ! Я пока не нашел альтернативы использованию.
person Phil    schedule 01.07.2021