【问题标题】:Powershell Excel Master SpreadsheetPowershell Excel 主电子表格
【发布时间】:2020-09-09 06:08:20
【问题描述】:

这是一个冗长的,但我会尽量缩短它。

我在每个学期都有一个从我们的 MIS 系统导出的主电子表格,它为我提供了所有课程以及特定学年的学生。

唯一的问题是它是一个工作簿中的一张大表。

看起来像这样:

Redacted Master Sheet Image

我的最终目标是将每个班级剪切并粘贴到单独的工作表中的一个主工作簿,然后该工作表的名称是“班级代码”,即每个部分顶部的{redacted} 部分。

到目前为止,这一直是手动完成的,但需要几个小时。

PowerShell 中有没有办法做到这一点?我需要将Class List Report: ...Males: X Females: X 的数据放入工作簿中自己的工作表中,然后将工作表命名为类代码。不幸的是,这些类的长度不同,所以我不能根据单元格的数量来计算。

非常感谢任何帮助。

【问题讨论】:

  • querying the workbook 使用 SQL 怎么样?
  • @vonPryz SQL 怎么知道表在哪里呢?它们都有不同的尺寸。

标签: excel powershell


【解决方案1】:

根据您提供的图像,这可能会满足您的需求。从本质上讲,它打开了工作簿,主工作表根据关键短语对其进行解析。然后使用关键字中标识符命名的每个关键字的开头之间的数据创建新工作表。

$ExcelFile="SO61954371.xlsx"
$MainSheetName="Sheet1"
$splitOnLike="Class List Report*"
$newExcelFile="SO61954371AA.xlsx"


#create Excel Object
$xl = New-Object -ComObject Excel.Application
#open Workbook
$WorkBook = $xl.Workbooks.Open($ExcelFile)  
#grab main sheet
$mainSheet=$WorkBook.sheets.Item("$MainSheetName")

$classStart=@()
#loop through used rows
for($i=1; $i -le $mainSheet.UsedRange.Rows.Count;$i++){
    #get cell in row $i Column 1(A)
    $cell=$mainSheet.Cells.Item($i,1)
    #check if start of table
    if($cell.Text -like "$splitOnLike")
    {
    #make object with class code and starting cell
    $classStart+=[pscustomobject]@{
        classCode=($cell.text.split(":")[1] -split "as")[0].trim()
        Cell=$cell
        }
    }
}

#Loop though tables
for($c=0; $c -lt $classStart.Count;$c++){
    #create new sheet after last sheet
    $Nsheet=$WorkBook.Sheets.Add($($WorkBook.Worksheets|Select -Last 1))
    #name sheet
    $Nsheet.name=$classStart[$c].classCode
    #get and copy from current class to start of next
    if($c -ne ($classStart.Count-1)){
        $range=$mainSheet.Range("A$($classStart[$c].Cell.Row):$([char](64 + $($mainSheet.UsedRange.Columns.count)))$($classStart[$c+1].Cell.Row-1)")
        $range.Copy() | out-null
        $nsheetrange=$Nsheet.Range("A1")
        $Nsheet.paste($nsheetrange)
    }
    else{
    #for last class get and copy from start of class to end of usable range
        $range=$mainSheet.Range("A$($classStart[$c].Cell.Row):$([char](64 + $($mainSheet.UsedRange.Columns.count)))$($mainSheet.UsedRange.Rows.Count)")
        $range.Copy() | out-null
        $nsheetrange=$Nsheet.Range("A1")
        $Nsheet.paste($nsheetrange)
    }
}
#save the file
$workbook._SaveAs($newExcelFile)

#kill the Excel instance and cleanup
$xl.Quit()
Remove-Variable -Name xl
[gc]::collect()
[gc]::WaitForPendingFinalizers()

【讨论】:

  • 没问题!如果对您有用,请将答案标记为有用,以便将其排在最佳答案中。
  • 快速提问,完成后删除 Sheet1,我在保存行之前添加了$workbook.worksheets.item($MainSheetName).Delete(),但它似乎没有删除工作表,有什么想法吗?
  • 这实际上比我想象的要难。赠品是,执行时您可以听到“叮”声。发生的情况是 com 对象本质上是一个隐藏的 excel 窗口,提示“您确定要删除它吗?”修复是在删除 $WorkBook 之前禁用警报.Application.DisplayAlerts =$false $mainsheet.delete() $WorkBook.Application.DisplayAlerts =$true
猜你喜欢
  • 1970-01-01
  • 2020-11-05
  • 2018-09-23
  • 1970-01-01
  • 1970-01-01
  • 2017-03-18
  • 2017-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多