如何从函数返回对象

时间:2019-07-09 15:59:47

标签: excel powershell

当我从Excel工作表中获取数据时,我有一个无法理解的大问题。 我使用此功能从excel读取数据(1行),并且操作正确

function ExtractExcelRows {
    [cmdletbinding()]
    Param($ExcelFile)

    # Excel.exe not autokill fix
    $before = Get-Process | % { $_.Id }
    $excel = New-Object -ComObject Excel.Application
    $excelId = Get-Process excel | % { $_.Id } | ? { $before -notcontains $_ }

    $workbook = $excel.Workbooks.Open($ExcelFile.FullName)
    $sheet = $workbook.Worksheets.Item(1)
    $excel.Visible = $false

    $rowMax = ($sheet.UsedRange.Rows).Count

    # Declare the starting positions
    $rowEmail, $colEmail = 1, 11

    $Rows = @()
    for ($i=1; $i -le $rowMax-1; $i++) {
        if ($sheet.Cells.Item($rowEmail+$i, $colEmail).Text) {
            $Rows += @{
                Email = $sheet.Cells.Item($rowEmail+$i, $colEmail).Text
            }
        }
    }

    $workbook.Close($false)
    $excel.Quit()

    Stop-Process -Id $excelId -Force

    Write-Host $Rows.Count  # count 1 row ! right!

    return $Rows
}

当我尝试将对象保存到全局变量中时,计数结果不同,我也不明白为什么。

$global:ExcelData = ExtractExcelRows $ExcelFile
write-host $ExcelData.Count  # count 4 row!!!! not right!

谁能告诉我错误在哪里以及如何解决?

2 个答案:

答案 0 :(得分:1)

以我的评论作为答案:

function ExtractExcelRows {
    [cmdletbinding()]
    Param($ExcelFile)

    $excel = New-Object -ComObject Excel.Application
    $excel.Visible = $false

    $workbook = $excel.Workbooks.Open($ExcelFile.FullName)
    $sheet    = $workbook.Worksheets.Item(1)
    $rowMax   = ($sheet.UsedRange.Rows).Count

    # Declare the starting positions
    $rowEmail, $colEmail = 1, 11

    $Rows = for ($i = 1; $i -lt $rowMax; $i++) {
        if ($sheet.Cells.Item($rowEmail + $i, $colEmail).Text) {
            [PSCustomObject]@{ 'Email' = $sheet.Cells.Item($rowEmail+$i, $colEmail).Text }
        }
    }

    $workbook.Close($false)
    $excel.Quit()
    # clean up used COM objects
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet)    | Out-Null
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook) | Out-Null
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)    | Out-Null
    [System.GC]::Collect()
    [System.GC]::WaitForPendingFinalizers()

    Write-Host $Rows.Count  # count 1 row ! right!

    # The comma used as unary operator wraps the array in another single element array. 
    # Powershell unboxes that to return an array, even if it is empty.
    return ,$Rows
}

答案 1 :(得分:0)

您检查了该变量的内容吗?我敢打赌,前三个项目是对/错,或类似的东西。原因是Excel com对象的方法倾向于返回一个值来指示执行是否成功,并且所有未显式重定向的输出都是由函数输出的,不仅是您用let products = [ { name: "chair", inventory: 5, unit_price: 45.99 }, { name: "table", inventory: 10, unit_price: 123.75 }, { name: "sofa", inventory: 2, unit_price: 399.50 } ]; let my_product = {name: "stool", inventory: 1, unit_price: 300} 指定的项(因此,无需使用return)。您应将return之类的内容通过管道传递给$workbook.close($false),如下所示:

Out-Null

那应该占您的4个项目中的2个,我不确定另一个是什么。