param( [Parameter(Mandatory)] [ValidateScript({ Test-Path -LiteralPath $_ })] [string]$SourceA, [Parameter(Mandatory)] [ValidateScript({ Test-Path -LiteralPath $_ })] [string]$TargetB ) $outputA = $SourceA -Replace ".xls", "_diff.xls" $outputB = $targetB -Replace ".xls", "_diff.xls" $ErrorActionPreference = 'Stop' $yellow = 65535 #vbYellow $red = 255 #vbRed $cyan = 16776960 #vbCyan if (Test-Path $outputA) { Remove-Item $outputA -Force } if (Test-Path $outputB) { Remove-Item $outputB -Force } $excel = New-Object -ComObject Excel.Application $excel.Visible = $false $excel.DisplayAlerts = $false $wbA = $null $wbB = $null try { $wbA = $excel.Workbooks.Open($sourceA) $wbB = $excel.Workbooks.Open($targetB) $mapA = @{} foreach ($ws in $wbA.Worksheets) { $mapA[$ws.Name] = $ws } $mapB = @{} foreach ($ws in $wbB.Worksheets) { $mapB[$ws.Name] = $ws } $commonNames = @($mapA.Keys | Where-Object { $mapB.ContainsKey($_) } | Sort-Object -Descending) if ($commonNames.Count -eq 0) { throw "同名のシートが見つかりませんでした。" } foreach ($name in $commonNames) { $wsA = $mapA[$name] $wsB = $mapB[$name]   Write-Host "比較中 - シート名: $($name)" $endRow = [Math]::Max( $wsA.UsedRange.Row + $wsA.UsedRange.Rows.Count - 1, $wsB.UsedRange.Row + $wsB.UsedRange.Rows.Count - 1 ) $endCol = [Math]::Max( $wsA.UsedRange.Column + $wsA.UsedRange.Columns.Count - 1, $wsB.UsedRange.Column + $wsB.UsedRange.Columns.Count - 1 ) $hasDiff = $false $hasDiffAll = $false for ($r = 1; $r -le $endRow; $r++) { for ($c = 1; $c -le $endCol; $c++) { $v1 = $wsA.Cells.Item($r, $c).Value2 $v2 = $wsB.Cells.Item($r, $c).Value2    if (("$v1") -ne ("$v2")) { $addr = $wsB.Cells.Item($r, $c).Address($false, $false)      Write-Host " 不一致セル $($addr): $($v1) != $($v2)" $hasDiff = $true $hasDiffAll = $true $wsA.Cells.Item($r, $c).Interior.Color = $yellow $wsB.Cells.Item($r, $c).Interior.Color = $yellow } } } if ($hasDiff) {    Write-Host " 差分あり" $wsA.Tab.Color = $yellow $wsB.Tab.Color = $yellow } else {    Write-Host " 差分なし" $wsA.Tab.Color = $cyan $wsB.Tab.Color = $cyan } } Write-Host "比較中 - シートの有無..." foreach ($ws in $wbA.Worksheets) { $wsA = $mapA[$ws.Name] if (($wsA.Tab.Color -eq $yellow) -or ($wsA.Tab.Color -eq $cyan)) { # 確認済みシート } else { # 未確認シート(Bに存在しない) $hasDiffAll = $true $wsA.Tab.Color = $red Write-Host "'$(Split-Path -Path $SourceA -Leaf)' のシート名 '$($ws.Name)' は、'$(Split-Path -Path $TargetB -Leaf)' に存在しません。" } } foreach ($ws in $wbB.Worksheets) { $wsB = $mapB[$ws.Name] if (($wsB.Tab.Color -eq $yellow) -or ($wsB.Tab.Color -eq $cyan)) { # 確認済みシート } else { # 未確認シート(Aに存在しない) $hasDiffAll = $true $wsB.Tab.Color = $red Write-Host "'$(Split-Path -Path $targetB -Leaf)' のシート名 '$($ws.Name)' は、'$(Split-Path -Path $SourceA -Leaf)' に存在しません。" } } if ($hasDiffAll) { $xlOpenXMLWorkbook = 51 # xlsx $wbA.SaveAs($outputA, $xlOpenXMLWorkbook) $wbB.SaveAs($outputB, $xlOpenXMLWorkbook) } } finally { if ($wbA) { $wbA.Close($false) | Out-Null } if ($wbB) { $wbB.Close($false) | Out-Null } if ($excel) { $excel.Quit() | Out-Null } foreach ($o in @($wbA, $wbB, $excel)) { if ($null -ne $o) { [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($o) } } [GC]::Collect() [GC]::WaitForPendingFinalizers() } if ($hasDiffAll) { Write-Host ("差分を次のファイルに保存しました。 {0}" -f $outputA) Write-Host ("差分を次のファイルに保存しました。 {0}" -f $outputB) } else { Write-Host "差分はありません。" }