powershell 簡單實現核算單位往來(對賬)
阿新 • • 發佈:2018-12-22
01 前言
核算單位(或部門)之間往來賬,也說對賬,是很多財務或者審計工作中都會涉及的。下面用powershell
簡單實現一把,需要的可以拿去用,格式有要求。
02 正文
1、準備CSV檔案
格式說明
- 檔案編碼為
ASCII
(一般系統預設)- 列名要求至少包含
掛賬單位
、對方單位
、金額
、方向
四個(名字不要改),其他列可選。取值的時候要注意的是:
金額——可以含逗號
方向——簡單說,這筆賬對於掛賬單位
來說是收入還是支出,+
表示收入,-
表示支出
如圖:
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 後記
有條件可以自己修改指令碼。
其他複雜一點的情況,也可以留言交流。