【问题标题】:Delete excel rows based on a specific value with Powershell [closed]使用Powershell根据特定值删除excel行[关闭]
【发布时间】:2021-10-23 15:47:05
【问题描述】:

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

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

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

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

【问题讨论】:

标签: excel vba powershell


【解决方案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 如果你不确定,但知道列名,你可以插入这个 sn-p:

# 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-27
    • 1970-01-01
    相关资源
    最近更新 更多