【问题标题】:Why are the columns getting skipped?为什么列被跳过?
【发布时间】:2020-05-11 12:16:14
【问题描述】:

我正在导入一个 xlsx 文件,通过在末尾添加一个“_sfx”来重命名列,并将工作表导出到它自己的 csv 文件中。目的不一定是修改 xlsx 文件,只是从这个 xlsx 文件生成的 csv 文件。

xlsx 工作表文件列示例:

Total MYTrim,Model Year,MY Trim,MYTrim Code

我注意到输出仅在 2 列上工作,其余列被跳过/以某种方式无法识别

重命名 [MYTrim] 工作表中的 [Total MYTrim] 列...

列 [Total MYTrim] 已重命名为 [Total MYTrim__sfx] !加工 其他列(如果有)...

在 [MYTrim] 工作表中重命名列 [MY Trim]...

列 [MY Trim] 已重命名为 [MY Trim__sfx] !进一步处理 列(如果有)...

重命名 [MYTrim] 工作表中的列 []...

列 [] 已重命名为 [__sfx] !处理更多列(如果 任何)...

重命名 [MYTrim] 工作表中的列 []...

列 [] 已重命名为 [__sfx] !处理更多列(如果 任何)...

继续将 [MYTrim] 工作表导出到 CSV 操作...

预期的 csv 文件列:

Total MYTrim_sfx,Model Year_sfx,MY Trim_sfx,MYTrim Code_sfx

这是生成的 csv 文件列:

Total MYTrim__sfx,Model Year,MY Trim__sfx,MYTrim Code,__sfx,,__sfx

代码如下:

$columnNameSuffix = '_sfx'
$Path = 'C:\MyFolder\Book2.xlsx'

function Rename-WorkSheetColumns ($wrksht, $colNameSuffix) {
    $ColumnsCount = $wrksht.UsedRange.Columns.Count
    for ($i=1; $i -le $ColumnsCount; $i++)
    {
        $column = $wrksht.Columns.Item($i).EntireColumn #$wrksht.sheets.columns.entirecolumn.hidden=$true
        $columnname = $column.cells.item(1,$i).value2

        if ($column.hidden -eq $true) { 
            if ($wrksht.Visible -eq 0) #worksheet hidden
            {
                "`r`nHidden column [{0}] found in hidden [{1}] worksheet. Renaming..." -f $columnname, $($wrksht.name)
            }
            else {
                "`r`nHidden column [{0}] found in [{1}] worksheet. Renaming..." -f $columnname, $($wrksht.name)
            }
        }
        else {
            if ($wrksht.Visible -eq 0) #worksheet hidden
            {
                "`r`nRenaming column [{0}] in hidden [{1}] worksheet..." -f $columnname, $($wrksht.name)
            }
            else {
                "`r`nRenaming column [{0}] in [{1}] worksheet..." -f $columnname, $($wrksht.name)
            }
        }

        if ($columnname -notlike "*$colNameSuffix*") {          
            try {
                $column.cells.item(1,$i).value2 = $columnname + '_' + $colNameSuffix
                $columnNewName = $column.cells.item(1,$i).value2

                "`r`nColumn [{0}] was Renamed to [{1}] ! Processing further columns (if any)...`r`n" -f $columnname, $columnNewName
            }
            catch {
                "`r`nFailed to Rename column [$columnname] in [$($wrksht.name)] worksheet! $($error[0])`r`n$($error[0].InvocationInfo.PositionMessage)`r`n$($error[0].ScriptStackTrace)"
                #$_ | Select *
            }
        }
        else {
            "`r`nColumn [{0}] already contains '{1}' in its name! Skipping to other columns (if any)...`r`n" -f $columnname, $colNameSuffix
        }
        #$i = $i - 1
    }
    "`r`nProceeding with Export of [{0}] worksheet to CSV operation...`r`n" -f $($wrksht.name)
}

$csvPATH = Join-Path -Path 'C:\MyFolder' -ChildPath CSV_Files
New-Item -ItemType Directory -Force -Path $csvPATH | out-null

"`r`nTerminating Excel process (if any) to prevent 'Can't access' (file in use) exception..."

Get-Process 'exce[l]' | Stop-Process -Force #this is to avoid "Can't access" exception if file is opened or in use

$excel = New-Object -ComObject Excel.Application -Property @{
    Visible       = $false
    DisplayAlerts = $false
}

$filename = [System.IO.Path]::GetFileNameWithoutExtension($Path)

"`r`nGenerating CSV files from '$Path' Worksheet(s)..."

$workbook = $excel.Workbooks.Open($Path)

foreach ($worksheet in ($workbook.Worksheets)) {

    Rename-WorkSheetColumns $worksheet $columnNameSuffix

    $ws = $worksheet

    $name = Join-Path -Path $csvPATH <# $root #> -ChildPath "$($ws.Name).csv"

    try {
        $ws.SaveAs($name, 6) #6 to ignore formatting and convert to pure text, otherwise, file could end up containing rubbish

        #"`r`n'$name' generated successfully!"
    } 
    catch {
        "`r`nFailed to save csv! Path: '$name'. $($error[0])`r`n$($error[0].InvocationInfo.PositionMessage)`r`n$($error[0].ScriptStackTrace)"
    }
}

$excel.Quit()
$null = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($excel)

【问题讨论】:

  • 我会将列导出为 CSV,然后进行重命名。如果事情横向发展,这似乎更容易调试...... [grin]
  • @Lee_Dailey 我想这是我可以做到的一种方式......虽然这部分工作真的很好奇
  • 是的,我很好奇……但我没有 MSOffice,只有 LibreOffice,所以我无法测试任何一个。
  • @Lee_Dailey 我明白了,感谢您简短地检查一下 :)
  • @Lee_Dailey 实际上,也许您可​​以根据您的建议帮助我。我找到了如何重命名 csv 中的列,但我发现的所有示例都有列名 herdcoded。您能否发布一个示例,说明如何导入 csv 文件、更改所有列名(添加后缀)?

标签: powershell


【解决方案1】:

这是正确的函数!

function Rename-WorkSheetColumns ($wrksht, $colNameSuffix) {

    foreach($column in $wrksht.usedrange.columns)
    {
        $columnname = "$($column.cells.item(1,1).value2)".Trim() 

        if ($column.hidden -eq $true) { 
            if ($wrksht.Visible -eq 0) #worksheet hidden
            {
                "`r`nHidden column [{0}] found in hidden [{1}] worksheet. Renaming..." -f $columnname, $($wrksht.name)
            }
            else {
                "`r`nHidden column [{0}] found in [{1}] worksheet. Renaming..." -f $columnname, $($wrksht.name)
            }
        }
        else {
            if ($wrksht.Visible -eq 0) #worksheet hidden
            {
                "`r`nRenaming column [{0}] in hidden [{1}] worksheet..." -f $columnname, $($wrksht.name)
            }
            else {
                "`r`nRenaming column [{0}] in [{1}] worksheet..." -f $columnname, $($wrksht.name)
            }
        }

        if ($columnname -notlike "*$colNameSuffix*") {          
            try {
                $column.cells.item(1,1).value2 = "$($columnname)_$colNameSuffix"
                $columnnewname = "$($column.cells.item(1,1).value2)" 

                "`r`nColumn [{0}] was Renamed to [{1}] ! Processing further columns (if any)...`r`n" -f $columnname, $columnNewName
            }
            catch {
                "`r`nFailed to Rename column [$columnname] in [$($wrksht.name)] worksheet! $($error[0])`r`n$($error[0].InvocationInfo.PositionMessage)`r`n$($error[0].ScriptStackTrace)"
                #$_ | Select *
            }
        }
        else {
            "`r`nColumn [{0}] already contains '{1}' in its name! Skipping to other columns (if any)...`r`n" -f $columnname, $colNameSuffix
        }
        #$i = $i - 1
    }
    "`r`nProceeding with Export of [{0}] worksheet to CSV operation...`r`n" -f $($wrksht.name)
}

感谢 powershell.org 上的 Doug Maurer!

【讨论】:

  • 出了什么故障?我还是想不通……[脸红]
  • @Lee_Dailey 不知道,我正在尝试比较它们
  • 当您找到它时...请在您的答案中添加注释吗?我很好奇……
  • @Lee_Dailey 确定!
猜你喜欢
  • 2021-11-07
  • 2021-03-19
  • 2015-05-06
  • 2014-05-28
  • 1970-01-01
  • 2018-09-17
  • 2014-09-24
  • 2016-12-13
  • 2019-05-14
相关资源
最近更新 更多