导入 Excel:将导入的 Excel 列展开为单独的行条目

问题描述 投票:0回答:1

有人可以帮我弄清楚如何取消透视导入 Excel 数据,以便可以将列扩展为单独的行条目吗? 这实际上更多的是如何重新渲染进入数组的自定义 PSObject 的问题。

更多详情:

我正在使用 Import-Excel 和 Powershell 从多个 Excel 电子表格中提取数据。 这些是员工的双月时间表,列是相关月份内的日期。 我想要取消透视这些列,这样我就可以将这些列作为每个日期、每个项目的事务(由时间表上的员工)写入 SQL。 我很难想象我的下一步。

每个电子表格的格式如下所示(2024 年 11 月上半年): spreadsheet image

如果此标题从电子表格的(例如)第 7 行开始,我可以按如下方式提取核心项目数据:

$data = Import-Excel -Path $excelFilePath -Sheet "sheet1" -StartRow 7 

此时,如果我有 SQLServer 模块,我可以按如下方式将条目写入 SQL:

$data  | Write-SqlTableData -ServerInstance "myserver" -DatabaseName "mydatabase" -TableName "testTimesheetEntries" -Force

这将为我提供一些 1:1 的 SQL 条目,这是一个很好的开始: sql output

如果我看

$data[0]
我有这个:

PROJECT NUMBER : xx1
PROJECT NAME   : some project
1              :
2              :
3              :
4              : 2
5              :
6              :
7              : 1
8              :
9              :
10             :
11             : 1
12             :
13             : 1
14             : 1
15             :

但我的最终目标是在写入 SQL 之前将它们拆分出来,这样它就成为每个项目员工日期一行,更像是这样:

mockup of desired output

employee number
month
year
很容易被抓住,因为它们位于静态单元格位置,所以假设它们进入例如
$employee
$monthInt
$yearInt
:有人可以帮助我可视化循环现有
data
数组的逻辑,以便这些行采用员工-项目-日期格式吗?

谢谢!!

powershell importexcel
1个回答
0
投票

我已经为您制定了一个解决方案。代码输出:

PROJECT NUMBER EntryDate Hours
-------------- --------- -----
xx1            4         2
xx1            7         1

代码只是遍历输入对象的属性并选择名称为数字的属性(例如“4”),然后使用该名称查找输入对象中的小时值。

$inputObj = [pscustomobject]@{
    "PROJECT NUMBER"="xx1" 
    "PROJECT NAME"="some project" 
    "1"=$null 
    "4"="2" 
    "7"="1"
}

$inputObj.PSobject.Properties | 
    Where-Object Name -match "^\d+$" |           # Keep only properties with numeric Names, e.g "4".
    Select-Object -ExpandProperty Name |         # Put the Name string (e.g. "4") into the pipeline.
    Select-Object -PipelineVariable name |       # Put that Name string (e.g. "4") in the variable $name.
    ForEach-Object {                             # Make our output object.
        [pscustomobject]@{
            "PROJECT NUMBER"=$inputObj."PROJECT NUMBER" 
            EntryDate=$name                      # Put e.g. "4" in the EntryDate property.
            Hours=$inputObj.$name                # We are doing e.g. $inputObject."4" here.
        }
    } |
    Where-Object Hours -ne $null                 # Filter out the entries with no Hours
© www.soinside.com 2019 - 2024. All rights reserved.