VBAを使ってA5SQLで自動生成したエンティティ定義書を一括書式変換する

### 前提
- ER図をA5SQLで作成していること。
- A5SQLを通してER図からExcelのエンティティ定義書を自動生成していること。
![サンプルER図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881444/29357a51-b7c7-03a4-539b-656f73641aee.png)
![サンプルエンティティ定義書.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881444/497561be-f351-91d1-bc3e-7cab408370ec.png)


### 経緯

システム移行に伴いDBの桁数拡張を行うこととなり、ER図及びエンティティ定義書の更新が必要になりました。
その際、エンティティ定義書について更新箇所が分かるように下記の書式を適用するよう指示されたのですが、更新対象のテーブルと行が多すぎてとても手動入力できなかったため、VBAを組みました。

- バイト数拡張を行ったカラムの背景色をイエローに変更する
- バイト数拡張を行ったカラムのデータ型(`CHAR`, `VARCHR`)を赤字に変更する
- バイト数拡張を行ったカラム行のH列に文字列「バイト数拡張対応」を赤字で表示させる

### VBAの実行
```vb
Sub CHAR_TO_YELLOW_1()

    Dim ws As Worksheet
    Dim i As Long
    Dim keyword As String
    
    keyword = "CHAR"
    
    For Each ws In ThisWorkbook.Worksheets
        ' カラム定義が始まる14行目から開始
        i = 14
        Do While ws.Cells(i, 1).Value <> ""
            ' セル_列D,行iが指定した語句を含む場合
            If InStr(ws.Range("D" & i).Value, keyword) > 0 Then
                ' G列までの行を黄色にする
                ws.Range("A" & i & ":G" & i).Interior.Color = RGB(255, 255, 0)
                ws.Range("D" & i).Font.Color = RGB(255, 0, 0) 
                ws.Range("H" & i).Value = "バイト数拡張対応"
                ws.Range("H" & i).Font.Color = RGB(255, 0, 0) 
            Else
                ' 条件に合わない場合は元に戻す
                ws.Range("A" & i & ":G" & i).Interior.ColorIndex = xlNone ' A列からG列の色を元に戻す
                ws.Range("D" & i).Font.ColorIndex = xlAutomatic ' D列の文字色を元に戻す
                ws.Range("H" & i).Value = "" ' H列の内容をクリア
            End If
            i = i + 1 
        Loop
    Next ws

End Sub
```
### 解説

#### 変数の定義
```vb
    Dim ws As Worksheet ' データ型の列
    Dim i As Long ' ループ処理開始位置(行)
    Dim col As String ' データ型の列
    Dim keyword As String ' 検索文字列

    col = "D"
    keyword = "CHAR"
```
変数を定義します。\
シートをまたいで実行したいので、ワークシート型の変数`ws`を用意します。\
A5SQLのエンティティ定義書はD列にデータ型の情報が設定されるため、"D"を`col`に設定します。


#### シート内での書式変換処理
```vb
    i = 14
    Do While ws.Cells(i, 1).Value <> ""
        ' セル_列D,行iが指定した語句を含む場合
        If InStr(ws.Range(col & i).Value, keyword) > 0 Then
            ws.Range("A" & i & ":G" & i).Interior.Color = RGB(255, 255, 0) ' G列までの行を黄色にする
            ws.Range(col & i).Font.Color = RGB(255, 0, 0) ' D列のセルを赤字にする
            ws.Range("H" & i).Value = "バイト数拡張対応" ' H列に文字列を表示
            ws.Range("H" & i).Font.Color = RGB(255, 0, 0) ' H列の文字を赤字にする
        Else
            ' 条件に合わない場合は元に戻す
            ws.Range("A" & i & ":G" & i).Interior.ColorIndex = xlNone ' A列からG列の色を元に戻す
            ws.Range(col & i).Font.ColorIndex = xlAutomatic ' D列の文字色を元に戻す
            ws.Range("H" & i).Value = "" ' H列の内容をクリア
        End If
        i = i + 1 ' 次の行に移動
    Loop
```

- `Do While ws.Cells(i, 1).Value <> ""`\
テーブルによってカラムの数が異なるので、行の1列目(=A列)に値が入っている行まで処理をループさせます。
カラム情報の開始位置は決まって14行目であるため、`i`には`14`を設定します。

- `InStr(ws.Range(col & i).Value, keyword) > 0`\
i行目のD列のセルに文字列"CHAR"が含まれているかどうかを判定します。

- `ws.Range("A" & i & ":G" & i).Interior.Color = RGB(255, 255, 0)`
書式の指定をします。


### 実行後
シートをまたいで、書式が適用されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881444/b4eed5be-9eab-c0d0-b26c-a8b6da457925.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881444/37e57010-d29e-90a5-c1f1-573842be4c64.png)

### 最後に
更新対象のテーブルが200個くらいあり、途方に暮れていたので自動で書式変換できてよかったです。\
データベースの定義を考え直すにあたってA5SQLをよく触っているのですが、このツールは本当に便利だなあと思う日々です。\
まだまだ使えていない機能もあると思うので、いろいろ試してみたいです。

### 参考
[[VBA]特定列が指定した語句であればその行に色を付ける](https://note.com/kawamura_/n/nc5efc1171045)