18 lines
1.9 KiB
PowerShell
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()}
|