【入門編】【実務】フィールドのデータ型を動的に変更する際のデータ消失リスク回避策 – Access VBA解析バイブル

スポンサーリンク

こんにちは!Access VBAの世界へようこそ。チーフアーキテクトの私です。

現場でバリバリとシステムを作っていると、「既存のテーブルにあるフィールドのデータ型を、後から変更したい!」というリクエストに必ず直面します。例えば、「短いテキスト(Text)」で受けていた商品コードを、桁数の大きいものに変えたり、数値型に変えたりするようなケースですね。

ここで、マクロの記録から脱却したばかりの方がやりがちなのが、デザインビューで直接型を変えたり、VBAでいきなり `TableDef` をいじって `Type` プロパティを書き換えたりすることです。

……ちょっと待ってください。それをやると、「データが切り捨てられたり、最悪の場合はエラーで消え去ったり」という、実務で冷や汗をかく大惨事(データ消失)を引き起こします。Accessのエンジン(ACE/Jet)は、型変更の際にデータ溢れが発生すると容赦なくデータを削ぎ落とすからです。

今回は、プログラミング初学者の方でも安心して実務で使える、「一時テーブルを経由した安全な型変換の極意」を、優しく、そして本質的な部分まで徹底解説します。ここをクリアすれば、あなたのAccess VBAのスキルは一段上のステージに行けますよ!

なぜ、そのまま型を変更すると危険なのか?

Accessのテーブル構造(TableDef)をVBAで操作する場合、フィールドのデータ型(`Type` プロパティ)やサイズ(`Size` プロパティ)はプログラムから変更可能です。

しかし、考えてみてください。
すでに「5文字」しか入らないと定義されていたフィールドに、実は「10文字」のデータが無理やり入っていたとします(Accessの古いバージョンやインポートの仕様によっては、こういうことが起こり得ます)。これを、プログラムがいきなり「短いテキスト(サイズ5)」から「数値型」や「短いテキスト(サイズ20)」に変更しようとすると、Accessはパニックを起こし、入らなくなったデータを勝手に切り捨てるか、変換エラーで処理を中断させます。

このリスクを回避するためのプロの定石が、「安全な避難所(一時テーブル)を作る」というアプローチです。

安全な型変換の全体像(4つのステップ)

今回実装するVBAのアルゴリズムは、以下の4ステップで構成されています。

1. 退避(バックアップ): 現在のデータをそのまま別の一時テーブルへコピーする。
2. 構造破壊と再構築: 元のテーブルの該当フィールドを一度削除し、新しい正しい型・サイズで作り直する。
3. 復元: 一時テーブルからデータを元に戻す。この時、データ型が正しくなっているので安全に戻せる。
4. 後片付け: 用事が済んだ一時テーブルを削除する。

言葉で書くと難しそうに見えますが、VBAのDAO(Data Access Objects)を使えば、驚くほどスマートに記述できます。さあ、実際のコードを見ていきましょう!

【実践コード】データ消失を防ぐ安全な型変換プロシージャ

以下のコードは、開発現場でそのままコピペして使える実用的なVBAコードです。今回は例として、`T_社員` テーブルにある `ShainName` フィールドのサイズや型を変更するシナリオを想定しています。

Sub SafeChangeFieldType()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Dim strTableName As String
Dim strTempTableName As String
Dim strFieldName As String

‘ — 設定エリア —
strTableName = “T_社員” ‘ 対象のテーブル名
strFieldName = “ShainName” ‘ 型を変更したいフィールド名
strTempTableName = “W_Temp_Data” ‘ 一時退避用テーブル名

Set db = CurrentDb

On Error GoTo ErrorHandler

‘ トランザクションを開始(万が一の時にロールバックできるようにするプロの技)
DBEngine.BeginTrans

‘ ==========================================
‘ ステップ1: 一時テーブルを作成してデータを退避
‘ ==========================================
‘ すでに一時テーブルが残っていれば削除しておく
On Error Resume Next
db.TableDefs.Delete strTempTableName
On Error GoTo ErrorHandler

‘ SELECT INTO文を使って、現在のテーブル構造とデータをそっくり一時テーブルにコピー
db.Execute “SELECT INTO [” & strTempTableName & “] FROM [” & strTableName & “];”, dbFailOnError

‘ ==========================================
‘ ステップ2: 元テーブルのフィールドを削除して再作成
‘ ==========================================
Set tdf = db.TableDefs(strTableName)

‘ 古いフィールドを削除
tdf.Fields.Delete strFieldName

‘ 【重要】ここで新しい型・サイズのフィールドを作成する
‘ 例:dbText型で、サイズを「50」に変更する場合
Set fld = tdf.CreateField(strFieldName, dbText, 50)

‘ フィールドの属性を追加(必要に応じて。例:値必填をFalseに)
fld.Required = False

‘ テーブル定義に追加
tdf.Fields.Append fld

‘ テーブル定義の変更を反映させるためにリフレッシュ
db.TableDefs.Refresh

‘ ==========================================
‘ ステップ3: データを元に戻す
‘ ==========================================
‘ 一時テーブルからデータを再投入
db.Execute “UPDATE [” & strTableName & “] AS T INNER JOIN [” & strTempTableName & “] AS W ” & _
“ON T.ID = W.ID SET T.[” & strFieldName & “] = W.[” & strFieldName & “];”, dbFailOnError
‘(※注: テーブルが一意に特定できる主キー「ID」が存在する前提のSQLです)

‘ ==========================================
‘ ステップ4: 一時テーブルの後片付け
‘ ==========================================
db.TableDefs.Delete strTempTableName

‘ トランザクションを確定(コミット)
DBEngine.CommitTrans

MsgBox “フィールドのデータ型変更が安全に完了しました!”, vbInformation, “成功”

Exit Sub

ErrorHandler:
‘ エラーが発生した場合は、変更をすべてなかったことにする(ロールバック)
DBEngine.Rollback
MsgBox “エラーが発生したため、変更をキャンセルしました。” & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “エラー”

‘ 念のため一時テーブルが残っていたら削除
On Error Resume Next
db.TableDefs.Delete strTempTableName

End Sub

コードの注目すべきポイントとプロの知見

初心者の方に向けて、このコードに込めた「エンジニアとしてのこだわり」をいくつか解説します。

1. トランザクション(`BeginTrans` / `CommitTrans`)の活用

データベース操作において、途中でエラーが起きたときに「途中の状態」で放置されるのが最悪のシナリオです。「テーブルのフィールドは消えたけど、データが戻せなかった」という絶望的な状況を防ぐため、「すべて成功するか、すべて元に戻すか」の全か無か(トランザクション)の仕組みを組み込んでいます。これがあるだけで、プロとしての信頼性がグッと上がります。

2. DAO(Data Access Objects)の採用

Access VBAにはADOとDAOという2つのデータ操作ライブラリがありますが、テーブル定義(TableDef)やフィールド(Field)の構造変更は、Accessのローカルエンジンに最も最適化されたDAOを使うのが鉄則です。
`CurrentDb` を使ってサクッとDAOのデータベースオブジェクトを取得し、安全に操作しています。

3. 一意に特定するキー(主キー)の存在

ステップ3のデータ復元(`UPDATE` 文)では、行がズレないように主キー(ここでは `ID` フィールドを想定)で結合しています。実務でテーブルを操作する際は、必ず主キーが設定されているテーブル構造であることを確認してくださいね。

まとめ:ここをクリアすれば、Access VBAの基本はバッチリ!

いかがでしたでしょうか?
「フィールドの型を変える」という一見シンプルな操作の裏にも、データ消失のリスクを防ぐためのロジックや、安全地帯を作るアーキテクチャの思想が隠されています。

マクロの記録や、UIからの手動操作に頼っているうちは、大規模なシステム改修で必ず壁にぶつかります。しかし、今回のような「リスクを予測し、プログラムで安全網を張る技術」を身につければ、どんなに複雑なデータベース案件が来ても怖くありません。

ぜひご自身の開発環境でテスト用のテーブルを作って試してみてください。
あなたのAccess開発ライフが、より安全でスマートなものになることを応援しています!

タイトルとURLをコピーしました