-2

我在这里找到了一些与我的问题类似的解决方案,但它们并没有完全涵盖我的问题,而且由于我对 Powershell 还是很陌生,所以我无法针对我的用例专门修改它们。因此我有一个问题。

我正在从不提供任何过滤选项的系统中进行每周手动 Excel 导出 (.xlsx)。结果是一个包含大约 500 个条目的表。

我的目标是编写一个 powershell 脚本,它会自动删除/删除所有行,在“有效期至”列(Excel 表中的 F1)中包含与“01.01.2099”不同的值。

在此处输入图像描述

我还没有写任何代码,因为我不确定从哪里或如何从这里开始。我确信这是一项非常简单的任务,我们将非常感谢更有经验的Powersheller提供的任何帮助。谢谢!

4

1 回答 1

1

这里最大的挑战是您需要测试一个单元格是否包含某个日期值。
从您的图像中,您可以看到日期以不同的方式格式化,因此将单元格的值与特定格式的日期进行比较是很棘手的。
幸运的是,该DateTime对象有一个静态方法FromOADate()可以为您进行转换。

此外,您需要从下到上删除行,否则通过删除一行,下面的行的索引会更改,因为它们都向上移动一行。

$file  = 'D:\Test\Export.xlsx'
# create a datetime variable to chack against
$checkDate = [datetime]::new(2099, 1, 1)   # or do (Get-Date -Year 2099 -Month 1 -Day 1).Date

$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
# open the Excel file
$workbook = $excel.Workbooks.Open($file)
$sheet    = $workbook.Worksheets.Item(1)
# get the number of rows in the sheet
$rowMax   = $sheet.UsedRange.Rows.Count

# loop through the rows to test if the value in column 6 is date 01/01/2099
# do the loop BACKWARDS, otherwise the indices will change on every deletion.
for ($row = $rowMax; $row -ge 2; $row--) {
    # convert the formatted date in the cell to real DateTime object with time values set all to 0
    # Column 6 is the 'Valid until' column
    $cellDate = [datetime]::FromOADate($sheet.Cells.Item($row, 6).Value2).Date
    if ($cellDate -ne $checkDate) {
        $null = $sheet.Rows($row).EntireRow.Delete()
    }
}

# save and exit
$workbook.Close($true)
$excel.Quit()
# clean up the COM objects used
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

在上面的代码中,列索引被硬编码为 6 如果您不确定,但知道列名,您可以插入以下代码段:

# get the column index for column named 'Valid until'
$colMax = $sheet.UsedRange.Columns.Count
for ($col = 1; $col -le $colMax; $col++) {
    if ($sheet.Cells.Item(1, $col).Value() -eq 'Valid until') { break }  # assuming the first row has the headers
}

在线上方$rowMax = $sheet.UsedRange.Rows.Count和循环内部$sheet.Cells.Item($row, 6).Value2变为$sheet.Cells.Item($row, $col).Value2

于 2021-08-23T12:28:52.200 回答