请帮助我在运行Big-Sur的Mac Mini上运行Excel 365 VBA中的Python脚本

2024-04-18 13:25:30 发布

您现在位置:Python中文网/ 问答频道 /正文

关于这个问题,我的第一个问题因为不够具体而被关闭了,所以我将试着告诉你我迄今为止所做的哪些尝试没有奏效。我正在尝试使用Office 365将Excel 2010工作簿移动到我的新Mac mini Big Sur机器上。这是我的第一台Mac电脑,因此我对操作系统以及与微软世界的差异非常陌生。这也是我第一次使用Office 365。我希望你能帮助我。在我的VBA宏中,我运行Python脚本来抓取网页中的数据。通常我会让Python脚本创建一个.csv文件,然后在VBA宏中打开该文件以读取和填充工作簿中必要的单元格。这是我在PC版本中用来调用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

它可能不是最好的,但在PC上工作可靠。我先删除数据文件,运行Python脚本,等待创建数据文件,然后继续。 我在Mac上安装了最新版本的Python,重写了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上运行时,我得到:

Run-Time error '429': ActiveX component can't create object

我怀疑这是shell创建和使用方式的不同,于是开始研究如何在Mac上从Excel调用Python。在经历了相当多的死胡同后,我发现了这条4年前的线索: How can I launch an external python process from Excel 365 VBA on OSX?

我试着简单地前进,按照指示去做。我学习了一些关于AppleScript的知识,添加了文件夹:“~/Library/Application Scripts/com.microsoft.Excel/”,创建了名为PythonCommand.scpt的AppleScript,并将其放在该文件夹中。因为我在示例中找不到路径,所以我替换了我认为正确的路径,假设这是由于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宏时。我得到了这个信息:

Run-time error '13': Type mismatch

我再次尝试使用单引号而不是三引号,得到了相同的结果。 我试着反向工作,以确保这些部件工作正常。我再次从终端窗口运行Python脚本,没有问题,因此我尝试的下一步是从空闲状态运行AppleScript。我输入了以下内容:

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

得到了这个结果:

Traceback (most recent call last): File "<pyshell#0>", line 1, in AppleScriptTask("PythonCommand.scpt", "PythonCommand","/Users/minime/My Documents/Finance/GetHistory1-0.py") NameError: name 'AppleScriptTask' is not defined

经过进一步研究,我在编辑器中尝试了以下应用程序脚本:

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

我得到了这个结果:

error "sh: /Library/Frameworks/Python.framework/Versions/3.9/Python: cannot execute binary file" number 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

这实际上可能是一些进步!那个import语句是我的Python脚本中的第一行代码,但我不知道为什么这比上次的尝试更深入,为什么它的运行方式与终端中Python脚本的执行方式不同。 但我刚刚注意到在终端我进入了Python3,所以我尝试了以下方法:

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

并弹出一个带有脚本错误的弹出窗口: enter image description here 这是: enter image description here

在阅读了更多关于终端的内容后,我意识到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),并将其移动到Applications文件夹,然后将此代码放入VBA宏:

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

这成功了!当然,它没有传递任何参数或接收任何结果。但是有一个问题,就像我以前的PC版本一样,代码不会等待应用程序完成,所以我需要一种方法来检查它是否完成,因为我更改了Python脚本,在开始时打开文件,并在抓取网页时向其写入行,所以文件会立即创建,所以我在PC v中使用的这段代码版本不足:

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

我想我可以添加一个单独的文件,写在Python脚本的末尾,只是说它已经完成了,但这是一个相当蹩脚的攻击。所以从技术上讲,我想我可以说我解决了这个问题,可以从Excel运行Python脚本,但我必须相信有更好的方法,我相信这个社区有比我聪明得多的人,他们可以做得更好。有没有人能够从4年前的解决方案中获得成功?这可能会解决参数、结果和等待Python脚本结束的问题。你能提出的任何建议都会很有帮助。我已经对这个问题进行了广泛的研究,一些回答说沙箱正在阻止Excel运行Python,但是如果我们可以运行运行Python脚本的应用程序,我想这会解决问题。如果你能对我在上面遇到的具体错误发表评论,我将尝试不同的方法并报告。 请帮忙。 菲尔


Tags: 文件代码py脚本macshellvbaexcel
1条回答
网友
1楼 · 发布于 2024-04-18 13:25:30

解决了。。。一路上我学到了很多!我将尝试只列出实现这一目标所需的步骤,但我确实倾向于漫无边际,对不起。有一个问题让这比需要的更难:我在AppleScript的“DoShell脚本”语句中缺少了一个空格。以下是适用于我的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”

尝试在该文件夹中编辑它是有问题的,相信我。把它移到那里。 只要在VBA代码中的AppleScriptTask命令中给出路径,Python脚本就可以在任何地方

确保对.csv文件的所有引用都指向Excel沙盒文件夹。我用了这个,但我怀疑其他人也会用: “/Users/minime/Library/Containers/com.microsoft.Excel/Data/Documents”

如果找不到此文件夹,请参阅下面的注释。这在2021年7月1日起作用!我们将看到当新的OSX问世时会发生什么。对AppleScriptTask的调用将等待Python脚本的完全执行,然后再继续。我还没有找到处理Python脚本中错误的好方法

以下是我在学习过程中学到的一些重要知识,可能对像我这样的第一次使用Mac的用户有所帮助:

  1. 更改VBA编辑器字体。好的,这不是必须的,但是我使用的Mac Excel 365版本上VBA编辑器的默认字体不是比例字体,所以Dim语句中的“as”部分对我来说不合适。小的也许但大的烦恼很容易解决:在编辑器中,单击菜单栏(单词和图标的顶行)中的“Excel”一词。单击“首选项”,将弹出一个标题为“选项”的窗口。单击“编辑器格式”选项卡,并从“字体:”下拉列表中选择“Courier New”。我把“尺寸”改为16。哦,顺便说一句,“Command,shift,i”会像F8在PC上一样,逐步引导您完成VBA代码
  2. 将一些文件放在沙箱中。关于“沙盒”的一句话,我相信其他人可以比我更好地解释。为了提高安全性,沙盒概念应该限制代码在其预期区域之外执行某些内容:例如,您不希望代码中的错误(或恶意代码)改变与您的意图无关的某些系统设置。我明白了。好主意。在古代(大型机),我们有一个SOC 1为这类问题。沙盒基本上是计算机的一部分,您可以在其中玩游戏。不要试图超越它(有些例外我还没有完全理解)。在Mac上,这意味着,如果您甚至尝试对VBA代码中不在沙箱中的.csv文件执行任何操作,您将收到一条警报,说您需要为此授予权限。带有VBA代码的Excel工作簿不需要在沙箱中,因为重要的是Excel可执行文件在沙箱中(我假设),并且允许它接触到您的工作簿(规则的一个例外?),并执行您要求它执行的所有事情,包括运行VBA代码,但有限制。AppleScript也需要放在沙箱中,但是Python脚本没有(我不知道为什么)。我们只对Excel沙盒感兴趣,显然,不同的应用程序有不同的沙盒。现在谈谈别名。为了简单起见,请考虑你的Excel沙箱在这里: “/Users/philipackermann/Library/Containers/com.microsoft.Excel” 此处有一个别名: “/Users/philipackermann/Library/Containers/com.microsoft.Excel/Data/Library/Application Scripts/com.microsoft.Excel” 将一个文件移动到一个文件上,也会神奇地将该文件移动到另一个文件上。顺便说一句,如果您试图通过从begi开始的路径来查找别名路径中的第一个“com.microsoft.Excel”,它将在Finder中显示为“microsoft Excel”安宁。哦,顺便说一句,“Command,shift,”,会让你在Finder中看到隐藏的文件夹和文件。你需要这样才能开始。如果我理解正确,Finder中的文件夹图标和左下角的小箭头表示该文件夹是一个别名(或者有一个别名指向它?我不确定)。我用于.csv文件的文件夹不是别名或没有别名),因此我必须使用非常长的路径。因此Excel工作簿和Python脚本不需要在沙箱中,但AppleScript和.csv文件需要在沙箱中
  3. 不要在沙盒别名文件夹中编辑!查看我在上面评论中提到的与沃恩的链接。他为我指明了更好地理解别名问题的途径。谢谢你,沃恩。试图在这些文件夹中进行编辑是徒劳的疯狂行为。保存创伤并在本地文件夹中编辑AppleScript,然后将其复制到sandbox文件夹。我打开两个Finder窗口(一个是本地文件夹,另一个是沙盒文件夹),按住命令键和选项键,同时将AppleScript文件从本地文件夹拖到沙盒文件夹
  4. 在脚本编辑器中测试APPLESCRIPT。正如我在其他地方提到的,这个令人讨厌的错误5:可能会因为一些原因而突然出现。在脚本编辑器中,在PythonCommand Handler on语句上方添加此行: “PythonCommand处理程序(“GetHistory1-0.py”)” 并在编辑器中运行它,以确保它正在执行您希望它执行的操作。这就是我如何发现缺少空间的问题并测试不同路径以使其运行的原因
  5. 杂项。EXCEL NOTES。如果您试图将Excel工作簿从Windows环境带到Mac,请注意到目前为止我遇到的这些问题:排序。我在VBA代码中硬编码了排序,当我试图在Mac上运行它们时,导致Excel崩溃。我记录了一个排序,它在代码中运行良好。Mac上没有用户表单!我还没有找到替代品

相关问题 更多 >