Excel VBAでデータを突合し、変更になったデータだけを更新したいケースは非常によくあります。特にDictionaryを使った高速検索では便利な反面、空白データまで上書きしてしまう問題に悩まされることがあります。
今回のように、「変更後の住所が入力されている場合のみ更新したい」という処理では、“空白チェック”をどこに入れるかが重要になります。この記事では、Dictionaryを使った住所更新処理の考え方と、空白セルを除外する正しいVBAコードの書き方を解説します。
今回のVBAで起きている問題
現在のコードでは、以下の部分で無条件に転記しています。
wSB.Cells(sR2, "C") = wSA.Cells(sR1, "G")
そのため、G列が空白でもC列へ空白が転記され、既存住所が消えてしまいます。
つまり、「変更後住所がある場合だけ転記する」という条件が不足している状態です。
最も簡単な修正方法
解決方法は非常にシンプルで、G列が空白かどうかを判定してから転記すればOKです。
以下のように修正します。
If Dic.Exists(Key) = True Then
sR1 = Dic(Key)
If wSA.Cells(sR1, "G").Value <> "" Then
wSB.Cells(sR2, "C") = wSA.Cells(sR1, "G")
End If
End If
これにより、G列に値がある場合だけ住所更新されます。
修正後のコード全体
実際には以下のようになります。
Sub fewege()
Dim MR1 As Long
Dim MR2 As Long
Dim Key
Dim Dic As Object
Set Dic = CreateObject("Scripting.Dictionary")
Dim wSA As Worksheet
Set wSA = Worksheets("A")
MR1 = wSA.Cells(Rows.Count, "A").End(xlUp).Row
Dim wSB As Worksheet
Set wSB = Worksheets("A")
MR2 = wSB.Cells(Rows.Count, "E").End(xlUp).Row
Dim sR1 As Long
Dim sR2 As Long
Application.ScreenUpdating = False
For sR1 = 2 To MR1
Key = Val(wSA.Cells(sR1, "E").Value)
If Key <> "" Then
Dic(Key) = sR1
End If
Next
For sR2 = 2 To MR2
Key = Val(wSB.Cells(sR2, "A").Value)
If Dic.Exists(Key) = True Then
sR1 = Dic(Key)
If wSA.Cells(sR1, "G").Value <> "" Then
wSB.Cells(sR2, "C") = wSA.Cells(sR1, "G")
End If
End If
Next
Application.ScreenUpdating = True
Set wSA = Nothing
Set wSB = Nothing
Set Dic = Nothing
End Sub
なぜ空白判定が重要なのか
VBAでは「空白もデータ」として扱われるため、条件を書かないと空文字列もそのまま転記されます。
特に以下のような更新処理では注意が必要です。
- 住所変更
- マスタ更新
- CSV取り込み
- 差分更新
- データ同期
実務では「空白で既存データが消える事故」が非常に多いため、空白チェックはほぼ必須と考えてよいです。
さらに安全にする方法
実務では、単純な空白だけでなく「スペースだけ入力されている」ケースもあります。
その場合はTrim関数を使うとより安全です。
If Trim(wSA.Cells(sR1, "G").Value) <> "" Then
wSB.Cells(sR2, "C") = wSA.Cells(sR1, "G")
End If
これなら、半角スペースや全角スペースだけのセルも空白扱いできます。
Dictionaryを使うメリット
今回のコードではDictionaryを使っていますが、これは非常に良い方法です。
Dictionaryを使うと検索速度が大幅に向上します。
| 方法 | 速度 |
|---|---|
| For文で総当たり | 遅い |
| Dictionary検索 | 高速 |
行数が数千〜数万になる場合、Dictionaryを使うだけで処理時間が大きく変わります。
今回のコードで気になる点
今回のコードでは以下の記述があります。
Set wSB = Worksheets("A")
これだとAシートを2回参照しています。
もし本当に別シートBを使う場合は、以下のように修正する必要があります。
Set wSB = Worksheets("B")
添付画像では1シート化しているとのことですが、実際のブックでは確認しておくと安心です。
まとめ
今回の問題は、「変更後住所が空白でも転記していた」ことが原因でした。
解決方法は非常にシンプルで、G列が空白でない場合だけ転記する条件を追加すればOKです。
If wSA.Cells(sR1, "G").Value <> "" Then
また、実務ではTrim関数を使った空白判定や、Dictionaryによる高速検索も非常に重要です。
VBAの更新処理では「空白上書き事故」が本当によく起きるため、今回のような条件分岐を習慣化しておくと、かなり安全なコードになります。


コメント