Files
Pier_v1/수량산출/tools/verify-native.ps1
T

18 lines
1.9 KiB
PowerShell

param([string]$Source,[string]$Destination,[string]$Expected,[string]$Report)
$ErrorActionPreference='Stop'
if(Test-Path -LiteralPath $Destination){throw '검증 대상 파일이 이미 있습니다.'}
Copy-Item -LiteralPath $Source -Destination $Destination
function Invoke-ExcelCall([scriptblock]$Action){for($attempt=0;$attempt -lt 30;$attempt++){try{return & $Action}catch{if($_.Exception.HResult -notin @(-2147418111,-2147417846)){throw};Start-Sleep -Milliseconds 300}};throw 'Excel COM 호출 대기시간 초과'}
$excel=$null;$book=$null
try{
$excel=New-Object -ComObject Excel.Application
Invoke-ExcelCall {$excel.Visible=$false;$excel.DisplayAlerts=$false;$excel.AskToUpdateLinks=$false;$excel.AutomationSecurity=3}
$book=Invoke-ExcelCall {$excel.Workbooks.Open($Destination,0,$false)}
Invoke-ExcelCall {$excel.CalculateFullRebuild()}
$checks=Get-Content -LiteralPath $Expected -Raw -Encoding utf8 | ConvertFrom-Json
$errors=@();$count=0
foreach($item in $checks){$sheet=Invoke-ExcelCall {$book.Worksheets.Item($item.sheet)};$v=Invoke-ExcelCall {$sheet.Range($item.cell).Value2};$count++;if($v -isnot [double] -and $v -isnot [int]){$errors+="$($item.sheet)!$($item.cell): $v"}elseif([Math]::Abs([double]$v-$item.value) -gt 1e-8*[Math]::Max(1,[Math]::Abs($item.value))){$errors+="$($item.sheet)!$($item.cell): $v != $($item.value)"};[void][Runtime.InteropServices.Marshal]::ReleaseComObject($sheet)}
Invoke-ExcelCall {$book.Save()}
@{engine='Microsoft Excel';checked=$count;differences=$errors;worksheets=$book.Worksheets.Count}|ConvertTo-Json -Depth 4|Set-Content -LiteralPath $Report -Encoding utf8
}finally{if($book){try{Invoke-ExcelCall {$book.Close($false)}}catch{};[void][Runtime.InteropServices.Marshal]::ReleaseComObject($book)};if($excel){try{Invoke-ExcelCall {$excel.Quit()}}catch{};[void][Runtime.InteropServices.Marshal]::ReleaseComObject($excel)};[GC]::Collect();[GC]::WaitForPendingFinalizers()}