1. 程式人生 > >powershell 簡單實現核算單位往來(對賬)

powershell 簡單實現核算單位往來(對賬)

01 前言

核算單位(或部門)之間往來賬,也說對賬,是很多財務或者審計工作中都會涉及的。下面用powershell簡單實現一把,需要的可以拿去用,格式有要求。

02 正文

1、準備CSV檔案

格式說明

  1. 檔案編碼為ASCII(一般系統預設)
  2. 列名要求至少包含掛賬單位對方單位金額方向四個(名字不要改),其他列可選。取值的時候要注意的是:
    金額——可以含逗號
    方向——簡單說,這筆賬對於掛賬單位來說是收入還是支出,+表示收入,-表示支出

如圖:
CSV內容格式

2、執行指令碼

<#
	環境:powershell 5.1
	2018-11-18 By Hokis

	.NOTES
    CSV格式(5列,其中 掛賬單位,對方單位,金額,方向 必須有):
        掛賬單位,對方單位,科目, 金額,方向
        df,i,應收賬款,"42,217.00",+
        ......
	思路:
		1.先歸類
		2.再彙總

	.DESCRIPTION
	核對往來

#>
function Main-Do{ param( [string]$filePath ) #匯入 if (Test-Path $filePath) { [Object[]]$records = Import-Csv -Path $filePath -Encoding Default | Sort-Object -Property 掛賬單位, 對方單位 if ($records -and $records -is [system.array]) { $units = @{} #所有單位 #分類
foreach ($r in $records) { if($r.對方單位 -and $r.掛賬單位){ if ($units.keys -contains ($r.對方單位 + "|" + $r.掛賬單位)) #先判斷有無反過來的情況 { $units[($r.對方單位 + "|" + $r.掛賬單位)][1] += $r } elseif($units.Keys -contains ($r.掛賬單位 + "|"
+ $r.對方單位)){ $units[($r.掛賬單位 + "|" + $r.對方單位)][0] += $r } else #無此掛賬單位 { $units += @{ ($r.掛賬單位 + "|" + $r.對方單位) = @(@($r),@()) } } } } #彙總 $info = New-Object 'object[][]' $units.Count,4 | Out-Null #二維陣列,4列 foreach($k in $units.Keys){ $sum1 = ([decimal[]]($units[$k][0]|Where-Object{$_.方向 -eq "+"}|Select-Object -Property "金額").金額 | Measure-Object -Sum).Sum $sum2 = ([decimal[]]($units[$k][0]|Where-Object{$_.方向 -eq "-"}|Select-Object -Property "金額").金額 | Measure-Object -Sum).Sum $ownerU,$otherU = $k -split "\|" #轉義 $info += ,@($ownerU,$otherU,$sum1,$sum2) #此處二維陣列有個小坑,前面加逗號,以免被合併成一維陣列 if($units[$k][1]){ #反過來的情況 $sum1 = ([decimal[]]($units[$k][1]|Where-Object{$_.方向 -eq "+"}|Select-Object -Property "金額").金額 | Measure-Object -Sum).Sum $sum2 = ([decimal[]]($units[$k][1]|Where-Object{$_.方向 -eq "-"}|Select-Object -Property "金額").金額 | Measure-Object -Sum).Sum $otherU,$ownerU = $k -split "\|" #轉義 $info += ,@($ownerU,$otherU,$sum1,$sum2) }else{ #加一個金額為0的配對 $info += ,@($otherU,$ownerU,0,0) } } $oldU1,$oldU2 = $info[0][0],$info[0][1] #設一個預設值 $tol1,$tol2 = 0 #合計量 $wholeTol1,$wholeTol2 = 0 #最後的合計 #輸出 $output = New-Object System.Text.StringBuilder $output.AppendLine("序號,掛賬單位,對方單位,應收(+),應付(-),差異") | Out-Null $index = 1 $info | ForEach-Object{ if(-not (($oldU1 -eq $_[0] -and $oldU2 -eq $_[1]) -or ($oldU1 -eq $_[1] -and $oldU2 -eq $_[0]))){ $output.AppendLine(",,小計,$tol1,$tol2,"+($tol1-$tol2)) | Out-Null $oldU1,$oldU2 = $_[0],$_[1] $wholeTol1 += $tol1 $wholeTol2 += $tol2 $tol1,$tol2,$allTol = 0 #重置 $index ++ } $output.AppendLine("$index,"+$_[0]+","+$_[1]+","+$_[2]+","+$_[3]+","+($_[2]-$_[3])) | Out-Null $tol1 += $_[2] $tol2 += $_[3] } #再加最後一次 $output.AppendLine(",,小計,$tol1,$tol2,"+($tol1-$tol2)) | Out-Null $wholeTol1 += $tol1 $wholeTol2 += $tol2 $output.AppendLine(",,合計,$wholeTol1,$wholeTol2,"+($wholeTol1-$wholeTol2)) | Out-Null $outputFile = (Split-Path -Path $filePath).ToString()+"\result.csv" $output.ToString() | Out-File -FilePath $outputFile -Encoding default Write-Host "完成!!生成檔案:$outputFile" } else { write-host "無內容!" } } else { write-host "找不到檔案!" } } #csv路徑 #$path = "D:\powershell\tt.csv" #Main-Do -filePath $path Main-Do -filePath $args[0]

以上程式碼另存為.ps1檔案(此處筆者存為D:\powershell\myscript01.ps1)。在DOS視窗中輸入如下命令後回車等待:

powershell.exe -file "D:\powershell\myscript01.ps1" "D:\powershell\tt.csv" 

指令碼執行完成會有提示,生成結果result.csv檔案,格式如圖:
在這裡插入圖片描述
如果指令碼不能執行,參考【此處】解決。

03 後記

有條件可以自己修改指令碼。
其他複雜一點的情況,也可以留言交流。