$Path = 'D:/ETL_Data/TwitchTVData.xlsx'
$csvPath = 'D:/ETL_Data/TwitchTVData2.csv'
# Open the Excel document and pull in the 'Sheet1' worksheet
$Excel = New-Object -Com Excel.Application
$Workbook = $Excel.Workbooks.Open($Path)
$page = 'Sheet1'
$ws = $Workbook.Worksheets | Where-Object {$_.Name -eq $page}
$Excel.Visible = $true
$Excel.DisplayAlerts = $false
# Set variables for the worksheet cells, and for navigation
$cells = $ws.Cells
$row = 1
$col = 4
$formula = @"
=NOW()
"@
# Add the formula to the worksheet
$range = $ws.UsedRange
$rows = $range.Rows.Count
for ($i=0; $i -ne $rows; $i++) {
$cells.Item($row, $col) = $formula
$row++
}
$ws.Columns.Item("A:D").EntireColumn.AutoFit() | Out-Null
$ws.Columns.Range("D1:D$rows").NumberFormat = "yyyy-MM-dd hh:mm"
$Excel.ActiveWorkbook.SaveAs($csvPath)
$Excel.Quit()
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
我试图遵循这一点,但由于某种原因,我SaveAs()
不起作用。它给了我一个错误
无法访问文件'D:// ETL_Data / E567DF00
我需要做些什么才能将其保存到CSV?
编辑:
注释中建议的没有fileformat参数6
的确切错误:
Microsoft Excel cannot access the file 'D:\//ETL_Data/8011FF00'. There are several possible reasons: o The file name or path does not exist. o The file is being used by another program. o The workbook you are trying to save has the same name as a currently open workbook. At D:\PS_Scripts\twitchExcelAddSnapShot.ps1:32 char:1 + $Excel.ActiveWorkbook.SaveAs($csvPath) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (:) [], COMException + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
fileformat参数6
的确切错误:
The file could not be accessed. Try one of the following: o Make sure the specified folder exists. o Make sure the folder that contains the file is not read-only. o Make sure the file name does not contain any of the following characters: < > ? [ ] : | or * o Make sure the file/path name doesn't contain more than 218 characters. At D:\PS_Scripts\twitchExcelAddSnapShot.ps1:32 char:1 + $Excel.ActiveWorkbook.SaveAs($csvPath,6) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (:) [], COMException + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
答案 0 :(得分:4)
虽然PowerShell在路径分隔符方面非常宽容,但COM +服务器(如Excel.Application
)可能不是。
将$csvPath
变量值更改为使用\
而不是/
:
$csvPath = 'D:\ETL_Data\TwitchTVData2.csv'
答案 1 :(得分:2)
使用背景信息 补充 Mathias R. Jessen's helpful answer:
似乎 Excel的特定于应用程序的行为是导致问题的原因,与使用的基础子系统或API无关。
(Excel的自动化API恰好是COM服务器。)
我不明白为什么Excel会这样做 - 它也会在交互式使用中这样做,尽管你可以说至少在 programmatic 中使用它应该允许{{ 1}}。
提供广义建议:
在 Windows 上,为了安全起见,请使用/
,尤其是在处理应用程序级自动化API时,尽管在系统API \
级别应该工作也好 - 见下文。
在跨平台代码中,使用/
(但要注意上述例外情况; /
报告适合平台的(主要)字符)。
虽然很少使用,但在API级别的 Windows允许可互换地使用[System.IO.Path]::DirectorySeparatorChar
和\
(显然是goes back to the DOS 2.0 days),当引入对目录的支持时),并且也反映在更高级别的子系统中,如以下示例所示。
/
这是最小示例,用# PS:
# Should output c:\windows\win.ini
(Get-Item c:/windows/win.ini).FullName
# .NET:
# Should return the 1st child dir.'s path.
# Note that the child directory names will be appended with "\", not "/"
[System.IO.Directory]::GetDirectories('c:/windows/system32') | Select-Object -First 1
# COM:
# Should return $true
(New-Object -ComObject Scripting.FileSystemObject).FileExists('c:/windows/win.ini')
# Windows API:
# Should return a value such as 32.
(Add-Type -PassThru WinApiHelper -MemberDefinition '[DllImport("kernel32.dll")] public static extern uint GetFileAttributes(string lpFileName);')::GetFileAttributes('c:/windows/win.ini')
# cmd.exe
# Note: quoting matters here, so that tokens with / aren't mistaken for options.
# INCONSISTENT:
# attrib: works
cmd /c 'attrib "c:/windows/win.ini"'
# dir: works with DIRECTORIES, but fails with FILES
cmd /c 'dir /b "c:/windows/system32"' # OK
cmd /c 'dir /b "c:/windows/win.ini"' # FAILS with 'File not found'
cmd /c 'dir /b "c:/windows\win.ini"' # Using \ for the FILE component (only) works.
演示了 Excel的问题:
/