powershell 简单实现核算单位往来(对账)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HoKis/article/details/84196604

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 后记

有条件可以自己修改脚本。
其他复杂一点的情况,也可以留言交流。

猜你喜欢

转载自blog.csdn.net/HoKis/article/details/84196604