Я вызываю скрипт Python из VBA. Структура этого скрипта Python является единственной функцией без каких-либо других функций:
def myFunction():
# do stuff
return stuff_output
Я знаю, что эта функция работает правильно, потому что если она добавлена, print(myFunction())
генерирует правильный результат (ответ JSON) в командной строке.
В моем коде VBA "RetVal" всегда представляет собой 4-значное целочисленное значение. Возможно, функция Python даже не выполнена?
Какой код и как его исправить, чтобы он работал? Я был бы признателен за решение, которое близко к моему текущему коду и без внешних библиотек, если это возможно.
Option Explicit
Sub RunPython()
Dim RetVal
Dim scriptPath As String
scriptPath = "C:\Users\Rychu\Desktop\python\myPythonScript.py"
RetVal = Shell("C:\Python36-32\python.exe" & " " & scriptPath, vbHide)
If RetVal = 0 Then
MsgBox "Couldn't run python script!", vbOKOnly
Else
Debug.Print RetVal
End If
End Sub
Я не мог найти прямой способ передать значение, возвращаемое функцией Python, поэтому я обработал его, сохранив результат Python в текстовый файл на рабочем столе и прочитав + удалив тот же файл с помощью VBA.
Важные вещи:
shellObj.Run
отличие от Shell
позволяет установить логический параметр для ожидания возврата в True
, так что остальная часть кода VBA не пытается получить данные из текстового файла, пока еще не создано.
Если в текстовом файле не указан полный путь к файлу, только имя файла, Python не будет создавать текстовый файл в каталоге, в котором находится скрипт Python, как это происходит при запуске скрипта через командную строку или Visual Studio. По-видимому, когда вызывается из VBA, Python имеет другое восприятие каталога по умолчанию, и он также не является каталогом файла VBA.
Вот мой код Python:
def myFunction():
# do stuff
return stuff_output
import os
f = open(os.path.expanduser("~\Desktop") + "\myTemp.txt","w") #create a new text file on Desktop in write mode
f.write(str(myFunction())) #write output to created text file
f.close() #close file object
Вот мой код VBA:
Option Explicit
Sub RunPython()
Dim shellObj As Object: Set shellObj = CreateObject("WScript.Shell")
Dim tempTxtPath As String
Const scriptPath As String = "C:\Users\Rychu\Desktop\python\myPythonScript.py"
Const pythonPath As String = "C:\Python36-32\python.exe"
tempTxtPath = CreateObject("WScript.Shell").specialfolders("Desktop") & "\myTemp.txt"
shellObj.Run pythonPath & " " & scriptPath, vbHide, True
Debug.Print (getTextAndDelete(tempTxtPath))
End Sub
Function getTextAndDelete(filePath) As String
Dim fileNum As Long
Dim myData As String
fileNum = FreeFile
Open filePath For Binary As #fileNum
myData = Space$(LOF(1))
Get #fileNum, , myData
Close #fileNum
Kill filePath
getTextAndDelete = myData
End Function