我目前正在使用Powershell处理excel文件(* .xlsm)。问题是下面的代码只能读取“ test.xlsm”。如果未像“ this.xlsm”这样测试名称,则该代码无法读取该文件。任何帮助...?谢谢您的提前答复:)
$destination = "C:\JJ\"
$dirName = Get-ChildItem -Name -Filter *.xlsm
$saveAs = $destination + "new\"
foreach($z in $dirName){
$excel=New-Object -ComObject Excel.Application
$excel.visible=$false
$excel.Displ`ayAlerts=$false
$book=$excel.Workbooks.Open($destination + $z)
$sheet=$book.Worksheets.item(1)
$sheet.Cells.Item(1,5)="=max(B2:B6)"
$book.SaveAs($saveAs + $z)
$excel.Quit()
$excel=$null
}
您在代码中使用了令人困惑的变量名。为什么调用源路径$destination
?
无论如何,您应该使用-File
cmdlet上的Get-ChildItem
开关来确保它只会返回FileInfo对象,也不会返回DirectoryInfo对象。 (这些是Objects,而不是字符串)
然后,有一种更好的方法来构造路径。使用Join-Path而不是使用$destination + $z
进行连接。
最后,在循环和清理内存之前,我只会创建一次Excel对象。现在,您将在每次迭代中创建新的COM对象,而永远不会从内存中释放它们。
下面的代码应该按照您的意图进行:
$source = "C:\JJ"
$destination = Join-Path -Path $source -ChildPath 'new'
# test if the destination path already exists and if not, create it
if (!(Test-Path -Path $destination -PathType Container)) {
$null = New-Item -Path $destination -ItemType Directory
}
# create the Excel COM object outside the loop
$excel = New-Object -ComObject Excel.Application
$excel.visible = $false
$excel.DisplayAlerts = $false
# get all *.xlsm files inside the source folder
Get-ChildItem -Path $source -Filter '*.xlsm' -File | ForEach-Object {
# The $_ automatic variable represents 1 FileInfo object in each iteration
$book = $excel.Workbooks.Open($_.FullName)
$sheet = $book.Worksheets.item(1)
$sheet.Cells.Item(1,5) = "=max(B2:B6)"
# join the destination path and the file name for output
$saveAs = Join-Path -Path $destination -ChildPath $_.Name
$book.SaveAs($saveAs)
$book.Close()
}
# cleanup Com objects
$excel.Quit()
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($book)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
$excel = $null
注意,如果您的PowerShell版本低于3.0,则-File
开关不可用。相反,请使用
Get-ChildItem -Path $source -Filter '*.xlsm' | Where-Object {!$_.PSIsContainer} | ForEach-Object { ... }
# remove -name to get a directory object instead of a string
$dirName = Get-ChildItem -Filter *.xlsm
# you need the file name from the directory object listing
foreach($z in $dirName.name){ ...... }