PowerShell ForEach-Object 仅匹配第一个传递的值

PowerShell ForEach-Object Only Matching first Value passed

我正在编写读取以下格式的 CSV 文件的 PowerShell 脚本:

A,B,ProgrammeSeller,D,E,F,G,H,I,J,K,L,M,N,O,P,SellerCode,Date,Seller,Currency1,InvoiceAmmount,DiscountAmount,PurchasePrice,TotalsCurrency,TotalInvoiceAmmount,TotalDiscountAmmount,TotalPurchasePrice,Reviewed,AC,Signed
,,PROGRAMME,,,,,,,,,,,,,,380,09/12/2021,SELLER_BE,EUR,2813828.46,17594.22,2796234.24,EUR,0,0,0,Reviewed by:,,Signed:
,,PROGRAMME,,,,,,,,,,,,,,383,09/12/2021,SELLER_DE,EUR,3287812.58,17595.8,3270216.78,EUR,0,0,0,Reviewed by:,,Signed:
,,PROGRAMME,,,,,,,,,,,,,,383,09/12/2021,SELLER_DE,USD,1520725.4,11428.98,1509296.42,USD,0,0,0,Reviewed by:,,Signed:
,,PROGRAMME,,,,,,,,,,,,,,381,09/12/2021,SELLER_DK,DKK,6047281.25,26163.13,6021118.12,DKK,0,0,0,Reviewed by:,,Signed:
,,PROGRAMME,,,,,,,,,,,,,,381,09/12/2021,SELLER_DK,EUR,11376479.39,39580.28,11336899.11,EUR,0,0,0,Reviewed by:,,Signed:
,,PROGRAMME,,,,,,,,,,,,,,381,09/12/2021,SELLER_DK,USD,12571895.13,71198.51,12500696.62,USD,0,0,0,Reviewed by:,,Signed:

我想对 3 列 (InvoiceAmmount、DiscountAmount、PurchasePrice) 进行分组和求和,并在新文件上更新列 (TotalInvoiceAmmount、TotalDiscountAmmount、TotalPurchasePrice),该文件是原始文件的副本,但包含列只要货币值匹配,(TotalInvoiceAmmount,TotalDiscountAmmount,TotalPurchasePrice) 就会更新为总和值。

我写了以下脚本:

$csvFile = Import-Csv "C:\OutputFiles\OTC_Purchase_Report_EUProgramme_20220420_TMP.csv"
$csvFinal = "C:\OutputFiles\OTC_Purchase_Report_EUProgramme_20220420.csv"

function WriteTotalsToCSV
{
    $totals | ForEach-Object {
        $totalCurrency = $_.Currency
        $totalInvoiceAmmount = $_.TotalInvoiceAmmount
        $totalDiscountAmmount = $_.TotalDiscountAmmount
        $totalPurchasePrice = $_.TotalPurchasePrice
        $csvFile | ForEach-Object {

            if($_.Currency1 -eq $totalCurrency){
                $_.TotalsCurrency = $totalCurrency
                $_.TotalInvoiceAmmount = $totalInvoiceAmmount
                $_.TotalDiscountAmmount = $totalDiscountAmmount
                $_.TotalPurchasePrice = $totalPurchasePrice
            }
            $_ | Export-Csv $csvFinal -NoTypeInformation -Append 
        }


    }
}

function InvoiceAmmountTotals
{
    param ($file)

    $headers = ($file | Get-Member -MemberType NoteProperty).Name
    $totals = $file | Select-Object $headers | Group-Object Currency1



    foreach ($total in $totals)
    {

        $showtotal = New-Object System.Management.Automation.PsObject
        $showtotal | Add-Member NoteProperty Currency $total.Name
        $showtotal | Add-Member NoteProperty TotalInvoiceAmmount ($total.Group | Measure-Object -Sum InvoiceAmmount).Sum
        $showtotal | Add-Member NoteProperty TotalDiscountAmmount ($total.Group | Measure-Object -Sum DiscountAmount).Sum
        $showtotal | Add-Member NoteProperty TotalPurchasePrice ($total.Group | Measure-Object -Sum PurchasePrice).Sum
        $showtotal
    }
}


#execution
$totals = InvoiceAmmountTotals $csvFile
WriteTotalsToCSV

该脚本按预期对总计进行分组和求和,但是当它写入新的 CSV 文件时,它应该根据 Currency1 列的匹配更新列,但它只对第一个匹配(在本例为 EUR) 并忽略剩余的匹配项,即:

"A","B","ProgrammeSeller","D","E","F","G","H","I","J","K","L","M","N","O","P","SellerCode","Date","Seller","Currency1","InvoiceAmmount","DiscountAmount","PurchasePrice","TotalsCurrency","TotalInvoiceAmmount","TotalDiscountAmmount","TotalPurchasePrice","Reviewed","AC","Signed"
"","","PROGRAMME","","","","","","","","","","","","","","380","09/12/2021","SELLER_BE","EUR","2813828.46","17594.22","2796234.24","EUR","153995434.65","797318.07","153198116.58","Reviewed by:","","Signed:"
"","","PROGRAMME","","","","","","","","","","","","","","383","09/12/2021","SELLER_DE","EUR","3287812.58","17595.8","3270216.78","EUR","153995434.65","797318.07","153198116.58","Reviewed by:","","Signed:"
"","","PROGRAMME","","","","","","","","","","","","","","383","09/12/2021","SELLER_DE","USD","1520725.4","11428.98","1509296.42","USD","0","0","0","Reviewed by:","","Signed:"
"","","PROGRAMME","","","","","","","","","","","","","","381","09/12/2021","SELLER_DK","DKK","6047281.25","26163.13","6021118.12","DKK","0","0","0","Reviewed by:","","Signed:"
"","","PROGRAMME","","","","","","","","","","","","","","381","09/12/2021","SELLER_DK","EUR","11376479.39","39580.28","11336899.11","EUR","153995434.65","797318.07","153198116.58","Reviewed by:","","Signed:"
"","","PROGRAMME","","","","","","","","","","","","","","381","09/12/2021","SELLER_DK","USD","12571895.13","71198.51","12500696.62","USD","0","0","0","Reviewed by:","","Signed:"

请注意,当 Currency1 列的值为 USD 时,列 (TotalInvoiceAmmount、TotalDiscountAmmount、TotalPurchasePrice) 不会更新。

有什么关于我哪里出错的建议吗?

注意: CSV 文件要大得多,为了举例,我添加了少量条目

谢谢

看起来你循环遍历 csv 的每一行的次数与你拥有货币的次数一样多,因为你循环遍历 $totals 并且在每个循环中你循环遍历 csv 的每一行导致重复。

只在 csv 行中循环一次,并为每一行在 $totals 数组中找到匹配的货币以更新每个 csv 行。最后一次性全部输出到Export-Csv

function WriteTotalsToCSV {
    # only one loop through csv lines
    $csvFile | ForEach-Object {
        $line = $_
        # find matching currency in your $totals array using Where()
        $totalsMatch = $totals.Where({ $line.Currency1 -eq $_.Currency })

        $line.TotalsCurrency = $totalsMatch.Currency
        $line.TotalInvoiceAmmount = $totalsMatch.TotalInvoiceAmmount
        $line.TotalDiscountAmmount = $totalsMatch.TotalDiscountAmmount
        $line.TotalPurchasePrice = $totalsMatch.TotalPurchasePrice
        $line

        # collect all the lines first and then export to csv once at the end 
    } | Export-Csv -Path $csvFinal -NoTypeInformation
}