【问题标题】:Using Powershell in Excel to check all cell values in column to trigger copy and paste per row在 Excel 中使用 Powershell 检查列中的所有单元格值以触发每行的复制和粘贴
【发布时间】:2020-12-22 06:24:50
【问题描述】:

我有一个包含 2 个日期列的电子表格,每行中的任何一个都只有一个日期值。有两列对于我的目的来说是多余的,所以我想运行一个 powershell 脚本来检查 Date2 列中的每个单元格,如果为空,请将同一行上的 Date1 值复制到 Date2 列。那是我无法解决的部分;要检查 Date2 列中的所有单元格,如果为空白,请复制相邻的 Date1 值。 完成后,我将删除 Date1 列。 注意:Date2 列有更多日期,因此将其用作要保留的主要列(较少复制/粘贴)。 TIA

Example Test.xlsx:
         A            B
1 |    Date1   |    Date2   |
2 | 01/01/1900 |            |
3 | 01/01/1900 |            |
4 |            | 01/01/1900 |
5 |            | 01/01/1900 |
6 | 01/01/1900 |            |
7 |            | 01/01/1900 |
$Excel = New-Object -Com Excel.Application -Property @{Visible = $false} # Start Excel and hide the window
$Excel.DisplayAlerts = $False # Disable comfirmation prompts
$Workbook = $Excel.Workbooks.Open(C:\Temp\Test.xlsx) # Open spreadsheet file

#This is the part I'm stuck on:
#If cell in column Date2 is empty, then copy the adjacent Date1 value to the Date2 cell - This is done until at the end of the columns

[void]$Workbook.Sheets.Item("Test").Cells.Item(1, 1).EntireColumn.Delete() # Deleting "Date1" column
$Workbook.Save() # Save changes
$Workbook.Close($true) # Close workbook
$Excel.Quit() # Quit Excel
[Runtime.Interopservices.Marshal]::ReleaseComObject($Excel) # Release COM

【问题讨论】:

    标签: excel powershell if-statement cell copy-paste


    【解决方案1】:

    您在代码中只需要循环遍历行,如果为空,则使用第 1 列 (A) 的值更新第 2 (B) 列中的单元格。

    试试

    $Excel = New-Object -Com Excel.Application -Property @{Visible = $false} # Start Excel and hide the window
    $Excel.DisplayAlerts = $False # Disable comfirmation prompts
    $Workbook = $Excel.Workbooks.Open("D:\Test\Test.xlsx") # Open spreadsheet file
    $Sheet    = $Workbook.Worksheets.Item("Test")
    
    # get the total number of rows in the sheet
    $rowCount = ($Sheet.UsedRange.Rows).Count
    # update cell values in a loop
    for ($row = 1; $row -le $rowCount; $row++) {
        $value = $Sheet.Cells.Item($row, 2).Text
        if ([string]::IsNullOrWhiteSpace($value)) {
            # copy the cell format first; then the value
            $Sheet.Cells.Item($row, 2).NumberFormat = $Sheet.Cells.Item($row, 1).NumberFormat
            $Sheet.Cells.Item($row, 2) = $Sheet.Cells.Item($row, 1)
        }
    }
    
    [void]$Sheet.Cells.Item(1, 1).EntireColumn.Delete() # Deleting "Date1" column
    $Workbook.Save() # Save changes
    $Workbook.Close($true) # Close workbook
    $Excel.Quit() # Quit Excel
    
    # clean up COM objects
    $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()
    

    【讨论】:

    • 嗨 Theo,谢谢,但复制的日期丢失了日期格式; 01/01/1900 复制为“1”。你知道如何将单元格设置为日期格式吗?
    • 我明白了!我在 for 循环中 if 语句的末尾添加了一行: $Sheet.Cells.Item($row, 2).NumberFormat = "d/MM/yyyy" # 只有一个 'd' 可以去掉前导零。我需要在一月份进行测试,以确认我的其余代码是否需要 M 或 MM 一个月。干杯
    • @S.Hampton 我已更新代码以复制原始单元格 NumberFormat。这使它更通用,您不必通过反复试验自己弄清楚该格式是什么。干杯!
    【解决方案2】:

    这是一项经常性的任务吗?如果没有,使用 excel 函数可能会更快。

    无论如何,对于 excel 数据操作,我强烈推荐使用 ImportExcel 模块

    因此,您将阅读具有两列作为属性的工作表,根据前两个的三元运算创建第三个属性。

    【讨论】:

      猜你喜欢
      • 2021-04-28
      • 2017-12-30
      • 1970-01-01
      • 2013-12-11
      • 1970-01-01
      • 1970-01-01
      • 2018-09-25
      • 2019-06-04
      • 1970-01-01
      相关资源
      最近更新 更多