症状
Access VBA から ShellExecuteEx を使って .accdb を開くと,
特定の端末だけ程度フリーズしたようになる現象が発生しました。
With SHINFO
.cbSize = Len(SHINFO)
.nShow = 1
.lpFile = "C:\App\UT.accdb"
End WithCall ShellExecuteEX(SHINFO)
現象:
| 方法 | 結果 |
|---|---|
| Explorer でダブルクリック | すぐ起動 |
| Shell “MSACCESS.EXE db.accdb” | すぐ起動 |
| ShellExecuteEx(.accdb) | 非常に遅い |
調査
最初は次の原因を疑いました。
- DDE
- ShellExecuteEx の構造体
- Shell拡張
- Access の COM
しかし原因は レジストリのファイル関連付けでした。
原因
このキーの 既定値が存在していませんでした。
[HKEY_CLASSES_ROOT\.accdb] @="Access.Application.16"
なぜ遅くなるのか
ShellExecuteEx は .accdb を開くとき次の処理を行います。
.accdb
↓
ProgID 取得
↓
Access.Application.16
↓
shell\open\command
↓
MSACCESS.EXE
しかし ProgID が無い場合 Windows は
OpenWithList
OpenWithProgIDs
UserChoice
Shell拡張
などを 順番に探索します。
この探索が 非常に遅くなることがあります。
なぜ Explorer は速いのか
Explorer は
- ファイル関連付け
- ProgID
を キャッシュしているため高速です。
そのため
| 方法 | 挙動 |
|---|---|
| Explorer ダブルクリック | 速い |
| ShellExecuteEx(API) | 遅い |
という差が出ます。
解決方法
レジストリに 値をセットします。
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.accdb]
@="Access.Application.16"
確認方法
コマンドプロンプトにて下記を実行
assoc .accdb
正常なら,下記の値が返される
.accdb=Access.Application.16
どうしてこのレジストリ値が消えるのか?
HKEY_CLASSES_ROOT\.accdb の既定値Access.Application.16 が消える原因は,主に **「既定アプリの変更」または「Office の再登録処理」**です。
Windows の仕組み上,いくつかの操作でこの値が書き換わったり消えることがあります。
主な要因を重要度順に挙げます。
1. 既定アプリの変更(最も多い)
Windows の「既定のアプリ」設定を変更すると,内部では
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.accdb
の UserChoice が更新されます。
この過程で
HKEY_CLASSES_ROOT\.accdb
の既定値が 空になることがあります。
よくある操作
- 「このファイルを開く方法を選んでください」
- 右クリック → プログラムから開く
- 既定のアプリ設定
2. Office 修復 / 更新
Office Click-to-Run の更新や修復で
Access.Application.16
の ProgID 再登録が走ります。
このとき
.accdb
の関連付けが 一時的に外れるケースがあります。
特に
- Office 自動更新
- Office 修復
- Access 再インストール
で発生します。
3. Access Runtime のインストール
Access Runtime を入れると
Access.Application.16
ではなく
Access.RuntimeApplication
などに関連付けが変更されることがあります。
その際 .accdb の既定値が空になることがあります。
まとめ
Access VBA で ShellExecuteEx が遅い場合,.accdb の ProgID が壊れている可能性があります。
確認するレジストリ HKEY_CLASSES_ROOT\.accdb
補足
今回の環境
- Windows 11
- Access 2019 (Click-to-Run)
- 32bit VBA

コメント