見出し画像

Excelファイル内シート名、セル内、テキストボックスの全角を半角に置き換えるPower sellを、Claudeでプロンプト構成してChat-4oでコードを生成

経緯はExcelの資料のカタカナ記号英数字が全角半角バラバラのチェックして修正するを自動でできないか?から始まりました。
初めはVBAでアクティブシートのみですが、生成させて使ってました。ただ誰かに使ってもらう場合は使い勝手が悪いこともあるか?からbat、VBS、Power sell?ってことで生成させてみました。全く素人なので内容はさっぱり理解できていません、、分かる人からしたら何してんの?って思うかも願わくばそこそこ機能することを祈ります
注.コード生成のための要望を伝えるのに分割する旨を伝えプロンプト
もしかして、Excelって半角全角整えるそんな機能元々あったら、、

☆以下から生成内容、4oでVBSでコード生成してから


これまでのやり取りで生成したVBSコードはメモリに残っておらず、再度PowerShellに実装する必要があります。ただし、要件や機能については把握しているので、それを元にPowerShellで再実装します。

この作業には少し時間がかかりますが、段階的に進めていきます。出力に文字数制限がある場合、続きが必要なことをお伝えしますので、その際は同様に「続けてください」とリクエストしてください。

では、PowerShellに実装する際のコードを段階的に提示していきます。

### PowerShellでの基本的な構成

まず、基本的なスクリプトの構造を示します。

#### 1. Excel COMオブジェクトの初期化

```powershell
# Excel COMオブジェクトを作成
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false  # 非表示でExcelを操作

# ファイル選択ダイアログの設定
Add-Type -AssemblyName System.Windows.Forms
$dialog = New-Object System.Windows.Forms.OpenFileDialog
$dialog.InitialDirectory = (Get-Location).Path
$dialog.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm"

# ファイル選択ダイアログの表示
if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
   $filePath = $dialog.FileName
} else {
   Write-Host "ファイル選択がキャンセルされました。"
   exit
}

# Excelファイルを開く
$workbook = $excel.Workbooks.Open($filePath)
```

#### 2. 全角→半角の変換関数

次に、全角カタカナ、全角英数字、全角記号を半角に変換する関数を作成します。

```powershell
function Convert-FullWidthToHalfWidth {
   param (
       [string]$text
   )

   # 全角カタカナを半角カタカナに変換
   $text = $text -replace 'ガ', 'ガ' -replace 'ギ', 'ギ' # すべてのカタカナを置換...

   # 全角英数字を半角英数字に変換
   $text = $text -replace 'A', 'A' -replace 'B', 'B' # すべての英数字を置換...

   # 全角記号を半角記号に変換
   $text = $text -replace '!', '!' -replace '?', '?' # すべての記号を置換...

   return $text
}
```

#### 3. Excelシート内の全テキストに対する変換処理

```powershell
foreach ($sheet in $workbook.Sheets) {
   foreach ($cell in $sheet.UsedRange) {
       $originalText = $cell.Value2
       if ($originalText -ne $null) {
           $cell.Value2 = Convert-FullWidthToHalfWidth $originalText
       }
   }
}

# Excelファイルの保存とクリーンアップ
$backupPath = "$($filePath).backup"
$workbook.SaveAs($backupPath)
$workbook.Close()
$excel.Quit()

# メモリ解放
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

Write-Host "処理が完了しました。"
```

この段階で、指定されたExcelファイル内のすべてのシートに対して全角文字を半角に変換し、ファイルを保存する基本的なPowerShellスクリプトが完成しました。

**続き**(例えばエラー処理、ログ機能、設定ファイルの読み込みなど)の実装が必要な場合は、「続けてください」とお知らせください。また、質問や調整が必要な場合もお気軽にどうぞ。
try {
   # Excelファイルを開く
   $workbook = $excel.Workbooks.Open($filePath)
} catch {
   Write-Host "ファイルを開く際にエラーが発生しました。エラーメッセージ: $_"
   $excel.Quit()
   [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
   [System.GC]::Collect()
   [System.GC]::WaitForPendingFinalizers()
   exit
}

try {
   # シートの処理
   foreach ($sheet in $workbook.Sheets) {
       foreach ($cell in $sheet.UsedRange) {
           $originalText = $cell.Value2
           if ($originalText -ne $null) {
               $cell.Value2 = Convert-FullWidthToHalfWidth $originalText
           }
       }
   }
} catch {
   Write-Host "シートの処理中にエラーが発生しました。エラーメッセージ: $_"
} finally {
   # ファイルを保存し閉じる
   try {
       $backupPath = "$($filePath).backup"
       $workbook.SaveAs($backupPath)
       $workbook.Close()
       Write-Host "処理が完了しました。バックアップファイルは $backupPath に保存されました。"
   } catch {
       Write-Host "ファイルの保存中にエラーが発生しました。エラーメッセージ: $_"
   } finally {
       # Excelオブジェクトのクリーンアップ
       $excel.Quit()
       [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
       [System.GC]::Collect()
       [System.GC]::WaitForPendingFinalizers()
   }
}
では、次に必要な機能を段階的に追加していきます。今回は、エラー処理、ログ機能、バックアップ機能などを追加します。

### 4. エラー処理の追加

エラー処理を強化して、ファイルアクセスやその他の予期しないエラーに対応します。

```powershell
try {
   # Excelファイルを開く
   $workbook = $excel.Workbooks.Open($filePath)
} catch {
   Write-Host "ファイルを開く際にエラーが発生しました。エラーメッセージ: $_"
   $excel.Quit()
   [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
   [System.GC]::Collect()
   [System.GC]::WaitForPendingFinalizers()
   exit
}

try {
   # シートの処理
   foreach ($sheet in $workbook.Sheets) {
       foreach ($cell in $sheet.UsedRange) {
           $originalText = $cell.Value2
           if ($originalText -ne $null) {
               $cell.Value2 = Convert-FullWidthToHalfWidth $originalText
           }
       }
   }
} catch {
   Write-Host "シートの処理中にエラーが発生しました。エラーメッセージ: $_"
} finally {
   # ファイルを保存し閉じる
   try {
       $backupPath = "$($filePath).backup"
       $workbook.SaveAs($backupPath)
       $workbook.Close()
       Write-Host "処理が完了しました。バックアップファイルは $backupPath に保存されました。"
   } catch {
       Write-Host "ファイルの保存中にエラーが発生しました。エラーメッセージ: $_"
   } finally {
       # Excelオブジェクトのクリーンアップ
       $excel.Quit()
       [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
       [System.GC]::Collect()
       [System.GC]::WaitForPendingFinalizers()
   }
}
```

### 5. ログ機能の追加

次に、処理の詳細をログファイルに記録する機能を追加します。ログファイルは、スクリプトが存在するフォルダに保存されます。

```powershell
# ログファイルのパスを設定
$logFilePath = Join-Path -Path (Get-Location) -ChildPath "processing_log.txt"

# ログに書き込む関数
function Write-Log {
   param (
       [string]$message
   )
   $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
   Add-Content -Path $logFilePath -Value "$timestamp $message"
}

Write-Log "スクリプトが開始されました。処理対象ファイル: $filePath"

try {
   # Excelファイルを開く
   $workbook = $excel.Workbooks.Open($filePath)
   Write-Log "Excelファイルを開きました。"
} catch {
   Write-Log "ファイルを開く際にエラーが発生しました。エラーメッセージ: $_"
   $excel.Quit()
   [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
   [System.GC]::Collect()
   [System.GC]::WaitForPendingFinalizers()
   exit
}

try {
   # シートの処理
   foreach ($sheet in $workbook.Sheets) {
       Write-Log "シート $($sheet.Name) の処理を開始します。"
       foreach ($cell in $sheet.UsedRange) {
           $originalText = $cell.Value2
           if ($originalText -ne $null) {
               $convertedText = Convert-FullWidthToHalfWidth $originalText
               if ($originalText -ne $convertedText) {
                   Write-Log "セル $($cell.Address) でテキストを変換: $originalText → $convertedText"
                   $cell.Value2 = $convertedText
               }
           }
       }
   }
} catch {
   Write-Log "シートの処理中にエラーが発生しました。エラーメッセージ: $_"
} finally {
   # ファイルを保存し閉じる
   try {
       $backupPath = "$($filePath).backup"
       $workbook.SaveAs($backupPath)
       $workbook.Close()
       Write-Log "処理が完了しました。バックアップファイルは $backupPath に保存されました。"
   } catch {
       Write-Log "ファイルの保存中にエラーが発生しました。エラーメッセージ: $_"
   } finally {
       # Excelオブジェクトのクリーンアップ
       $excel.Quit()
       [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
       [System.GC]::Collect()
       [System.GC]::WaitForPendingFinalizers()
       Write-Log "スクリプトが終了しました。"
   }
}
```

### 6. バックアップ機能の強化

バックアップ機能を強化して、オリジナルファイルのコピーを別名で保存する機能を追加します。

```powershell
# バックアップファイルの作成
$backupDir = Join-Path -Path (Get-Location) -ChildPath "Backups"
if (-not (Test-Path -Path $backupDir)) {
   New-Item -ItemType Directory -Path $backupDir
}

$backupPath = Join-Path -Path $backupDir -ChildPath ("{0}_{1}.xlsx" -f (Split-Path -Leaf $filePath), (Get-Date -Format "yyyyMMddHHmmss"))
Copy-Item -Path $filePath -Destination $backupPath
Write-Log "元のファイルのバックアップを作成しました。バックアップファイル: $backupPath"
```

### 7. 設定ファイルの読み込み

設定ファイル(INIファイルなど)を使用して、置換対象の文字やその他の設定をカスタマイズできる機能を追加します。

```powershell
# 設定ファイルの読み込み関数
function Read-Config {
   param (
       [string]$configPath
   )
   
   $config = @{}
   if (Test-Path -Path $configPath) {
       $lines = Get-Content -Path $configPath
       foreach ($line in $lines) {
           if ($line -match '^\s*([^#;].*?)\s*=\s*(.*?)\s*$') {
               $key = $matches[1]
               $value = $matches[2]
               $config[$key] = $value
           }
       }
   }
   return $config
}

# 設定ファイルのパス
$configPath = Join-Path -Path (Get-Location) -ChildPath "settings.ini"
$config = Read-Config $configPath

# 設定ファイルで指定された値に基づき、変換ロジックを変更
if ($config.ContainsKey('KatakanaConversion')) {
   # 設定ファイルに基づく変換処理
}
```

### 8. その他の機能

さらに、以下のような機能も追加できます。

- **処理の進捗状況を表示する機能**
- **キャンセル機能の実装**
- **スクリプトの動作環境チェック**
- **セキュリティ対策**

これらの機能を追加することで、より安全で柔軟なスクリプトを作成できます。

もし、これらの機能の詳細な実装が必要であれば、具体的に指示をいただければ対応します。また、その他の質問や調整も遠慮なくどうぞ。

### 9. 処理の進捗状況を表示する機能

大きなExcelファイルを処理する場合、進捗状況を表示することで処理の進行具合を把握しやすくなります。以下のコードは、各シートやセルの処理進捗をコンソールに表示する例です。

```powershell
# 処理の進捗状況を表示する関数
function Show-Progress {
   param (
       [string]$message,
       [int]$percentComplete
   )
   Write-Progress -Activity "Excelファイルの処理中" -Status $message -PercentComplete $percentComplete
}

try {
   $totalSheets = $workbook.Sheets.Count
   $sheetIndex = 0

   foreach ($sheet in $workbook.Sheets) {
       $sheetIndex++
       Show-Progress -message "シート $($sheet.Name) を処理中" -percentComplete (($sheetIndex / $totalSheets) * 100)

       $totalCells = $sheet.UsedRange.Count
       $cellIndex = 0

       foreach ($cell in $sheet.UsedRange) {
           $cellIndex++
           $originalText = $cell.Value2
           if ($originalText -ne $null) {
               $convertedText = Convert-FullWidthToHalfWidth $originalText
               if ($originalText -ne $convertedText) {
                   $cell.Value2 = $convertedText
               }
           }

           # 各セルの処理後に進捗を更新
           Show-Progress -message "セル $($cell.Address) を処理中" -percentComplete (($cellIndex / $totalCells) * 100)
       }
   }
} catch {
   Write-Log "進捗状況の表示中にエラーが発生しました。エラーメッセージ: $_"
}
```

### 10. キャンセル機能の実装

処理中にユーザーがキャンセルできるようにするために、キャンセルのトリガーをチェックする機能を追加します。以下は、ユーザーが「Ctrl+C」を押したときに処理を中断する方法です。

```powershell
# キャンセルをチェックする関数
function Check-Cancellation {
   if ($host.ui.RawUI.KeyAvailable -and $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyDown").Character -eq "c") {
       throw "ユーザーによってキャンセルされました。"
   }
}

try {
   foreach ($sheet in $workbook.Sheets) {
       foreach ($cell in $sheet.UsedRange) {
           Check-Cancellation

           $originalText = $cell.Value2
           if ($originalText -ne $null) {
               $convertedText = Convert-FullWidthToHalfWidth $originalText
               if ($originalText -ne $convertedText) {
                   $cell.Value2 = $convertedText
               }
           }
       }
   }
} catch [System.Exception] {
   Write-Host "キャンセルされました: $_"
   $excel.Quit()
   [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
   [System.GC]::Collect()
   [System.GC]::WaitForPendingFinalizers()
   exit
}
```

### 11. スクリプトの動作環境チェック

スクリプトが実行される環境に依存する場合があるため、事前に動作環境をチェックし、必要な環境が整っているかを確認します。

```powershell
# PowerShellバージョンのチェック
$requiredVersion = [version]"5.1"
$currentVersion = $PSVersionTable.PSVersion
if ($currentVersion -lt $requiredVersion) {
   Write-Host "このスクリプトを実行するにはPowerShellバージョン $requiredVersion 以上が必要です。現在のバージョン: $currentVersion"
   exit
}

# Excelのインストールを確認
if (-not (Get-Command "Excel.Application" -ErrorAction SilentlyContinue)) {
   Write-Host "Microsoft Excelがインストールされていません。スクリプトを終了します。"
   exit
}
```

### 12. セキュリティ対策

スクリプトが安全に実行されるようにするために、必要なセキュリティ対策を講じます。たとえば、ユーザーからの入力を検証し、不正な入力が処理に影響を与えないようにするなどです。

```powershell
# ファイルパスの検証
if (-not (Test-Path -Path $filePath -PathType Leaf)) {
   Write-Host "指定されたファイルパスが無効です。スクリプトを終了します。"
   exit
}

# 文字列の入力をサニタイズ
function Sanitize-Input {
   param (
       [string]$inputString
   )
   return $inputString -replace '[^a-zA-Z0-9_\-]', ''
}

# ファイル名のサニタイズ
$sanitizedFileName = Sanitize-Input (Split-Path -Leaf $filePath)
$backupPath = Join-Path -Path $backupDir -ChildPath "$sanitizedFileName.backup"
```

### まとめ

これまでに説明した機能を統合することで、強力で柔軟なExcel処理スクリプトを作成できます。作成したスクリプトを実行する前に、実行環境で十分なテストを行い、必要に応じてさらなるカスタマイズや調整を行ってください。

このスクリプトの各部分がどのように組み合わされるかや、他に必要な機能があれば、遠慮なくお知らせください。

いいなと思ったら応援しよう!