Convert .xls to .xlsb Running PowerShell Script from Python, ERROR: "You cannot call a method on a null-valued expression"

Convert .xls to .xlsb Running PowerShell Script from Python, ERROR: "You cannot call a method on a null-valued expression"

我正在尝试 运行 PowerShell 脚本从 python 将 .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"You cannot call a method on a null-valued expression.\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 进程中执行命令时,cmd3cmd4cmd5 将没有变量 $Excel 可用。 Powershell 默认为不存在的变量设置 $null 值,因此出现错误消息“您不能在空值表达式上调用方法”。变量 $xlExcel12 也是如此。这些变量仅在创建它们的进程为 运行ning 时存在,并且仅在这些进程中可见,即使您设法并行创建两个进程也是如此。

解决方案

命令 cmd1..5 需要在同一个 Powershell 进程中 运行,因此每个命令都能够“看到”之前命令创建的变量:

run( cmd1 + ';' + cmd2 + ';' + cmd3 + ';' + cmd4 + ';' + cmd5 )

您需要更改 cmd4 以将另一个变量用于将用于保存的扩展名,例如。 G。 extSave

cmd4 = f"$WorkBook.SaveAs('{psPath}{extSave}',$xlExcel12,[Type]::Missing, 
       [Type]::Missing,$false,$false,2)"    

cmd6是完全独立的,因为它不依赖于Powershell变量。它只依赖于 python 个变量,这些变量在进程开始之前就已经解决了,所以它仍然可以 运行 在一个单独的进程中。