python - 将 .xls 转换为 .xlsb 从 Python 运行 PowerShell 脚本,错误:“您不能在空值表达式上调用方法”
问题描述
我正在尝试从 python 运行 PowerShell 脚本以将 .xls 文件转换为 .xlsb。通过循环文件名列表。我遇到命令 3(即 cmd3)的 PowerShell 错误“您不能在空值表达式上调用方法”,我不确定原因(这是我第一次使用 python 并通常运行 PowerShell 脚本)。尝试打开工作簿时遇到错误,但是当直接在 PowerShell 中运行命令时,它似乎工作正常。
代码:
import logging, os, shutil, itertools, time, pyxlsb, subprocess
# convert .xls to .xlsb and / transfer new terminology files
for i in itertools.islice(FileList, 0, 6, None):
# define extension
ext = '.xls'
# define file path
psPath = f'{downdir}' + f'\{i}'
# define ps scripts
def run(cmd):
completed = subprocess.run(["powershell", "-Command", cmd], capture_output=True)
return completed
# ps script: open workbook
cmd1 = "$xlExcel12 = 50"
cmd2 = "$Excel = New-Object -Com Excel.Application"
cmd3 = f"$WorkBook = $Excel.Workbooks.Open('{psPath}{ext}')"
cmd4 = f"$WorkBook.SaveAs('{psPath}{ext}',$xlExcel12,[Type]::Missing,
[Type]::Missing,$false,$false,2)"
cmd5 = "$Excel.Quit()"
# ps script: delete.xls files
cmd6 = f"Remove-Item '{psPath}{ext}'"
run(cmd1)
run(cmd2)
run(cmd3)
# change extension
ext = '.xlsb'
run(cmd4)
run(cmd5)
run(cmd6)
# copy .xlsb files to terminology folder
shutil.copy(i + ext, termdir)
错误:
Out[79]: CompletedProcess(args=['powershell', '-Command', "$WorkBook = > > $Excel.Workbooks.Open('C:\Users\Username\Downloads\SEND Terminology.xls')"] , returncode=1, stdout=b'', stderr=b"您不能在空值表达式上调用方法。\r\nAt line:1 char:1\r\n+ $WorkBook = $Excel.Workbooks.Open ('C:\Username\User\Downloads\SEND Ter ...\r\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n + CategoryInfo : InvalidOperation: (: ) [], RuntimeException\r\n + FullyQualifiedErrorId : InvokeMethodOnNull\r\n \r\n")
任何输入都会有所帮助。
谢谢!
解决方案
问题
正如评论者 vonPryz正确指出的那样,Powershell 命令在单独的进程中运行。进程的内存空间是相互隔离的,当一个进程结束时会被清空。
当您在单独的 Powershell 进程中运行命令时cmd3
,cmd4
和cmd5
将没有$Excel
可用的变量。Powershell 默认$null
为不存在变量的值,因此错误消息“您不能在空值表达式上调用方法”。变量也是如此$xlExcel12
。这些变量仅在创建它们的进程正在运行时才存在,并且仅在这些进程中可见,即使您设法并行创建了两个进程。
解决方案
命令 cmd1..5 需要在同一个 Powershell 进程中运行,因此每个命令将能够“看到”先前命令创建的变量:
run( cmd1 + ';' + cmd2 + ';' + cmd3 + ';' + cmd4 + ';' + cmd5 )
您将需要更改cmd4
为使用另一个变量作为将用于保存的扩展名,例如extSave
cmd4 = f"$WorkBook.SaveAs('{psPath}{extSave}',$xlExcel12,[Type]::Missing,
[Type]::Missing,$false,$false,2)"
是完全独立的cmd6
,因为它不依赖于 Powershell 变量。它只依赖于 python 变量,这些变量在进程启动之前被解析,因此它仍然可以在单独的进程中运行。
推荐阅读
- java - 在 Visual Studio 代码中遇到 launch.json 问题
- swift - 为 CALayer 添加多个遮罩(1 用于添加角)
- excel - 粘贴到excel时数据差异
- asynchronous - 从 C# 异步方法返回多个值
- c# - 页面刷新后保留 GridView 的可见属性(ASP.NET、C#)
- wso2esb - 从 WSO2 中的本地条目 XML 获取数据
- excel - Excel vba:网格线帮助
- javascript - 在回调函数内部更改变量并在外部使用
- php - 具有相同收据编号的两次交易
- html - 单击我的博客后,页面顶部的博主标签文本变小/不同。我如何解决它?