【VBAリファレンス】VBA技術解説Excelのバージョンを判断して「名前を付けて保存」

スポンサーリンク

VBAにおけるExcelバージョン判別と「名前を付けて保存」の最適解

Excel VBAを用いた開発において、避けて通れない課題の一つが「環境依存」です。特に企業内では、最新のMicrosoft 365を利用しているユーザーと、いまだにOffice 2016などのレガシー環境を利用しているユーザーが混在しているケースが珍しくありません。

本記事では、実行環境のExcelバージョンを動的に判別し、それぞれの環境に適したファイル形式で「名前を付けて保存」を安全に実行するための技術的アプローチを詳説します。単なるコードの提示にとどまらず、なぜその実装が必要なのか、そして保守性の高いコードを書くためのベストプラクティスをプロの視点で解説します。

なぜバージョン判別が必要なのか

Excel 2007を境に、ファイル形式は従来のバイナリ形式(.xls)から、XMLベースのOpenXML形式(.xlsx, .xlsm等)へと刷新されました。この変更は単なる拡張子の違いではなく、内部構造やサポートされる機能、さらにはVBAの記述方法にまで影響を及ぼします。

例えば、古い環境では「FileFormat」引数に指定する定数が正しく認識されなかったり、特定のファイル形式(例:Excel 97-2003ブック)を強制的に保存させる必要があったりと、互換性を維持するための工夫が求められます。特に、マクロ付きブック(.xlsm)とマクロなしブック(.xlsx)を動的に切り替えて保存するようなシステムでは、バージョンに応じた適切な定数管理が不可欠です。

Application.Versionプロパティによる判定

Excelのバージョンを判定するには、ApplicationオブジェクトのVersionプロパティを使用します。このプロパティは「16.0」や「14.0」といった文字列を返します。

主要なバージョン番号と対応するExcelの名称は以下の通りです。
・16.0:Excel 2016 / 2019 / 2021 / Microsoft 365
・15.0:Excel 2013
・14.0:Excel 2010
・12.0:Excel 2007
・11.0:Excel 2003

この数値を数値型(Double)として取得し、条件分岐を行うのが最も標準的かつ安全な手法です。

実務で活用する堅牢な保存処理コード

以下に、現在のバージョンを判定し、適切な形式でファイルを保存する汎用的なプロシージャを示します。このコードは、ファイルが既に存在する場合の上書き確認を抑制し、エラーハンドリングを組み込んだ実務レベルの構成となっています。


Sub SaveWorkbookByVersion()
    Dim targetPath As String
    Dim fileFormat As Long
    Dim currentVersion As Double
    
    ' 保存先のパスを設定(例としてデスクトップ)
    targetPath = CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\OutputData.xlsm"
    
    ' 現在のExcelバージョンを取得
    currentVersion = Val(Application.Version)
    
    ' バージョンに応じたファイル形式定数の設定
    ' 12.0以上であればOpenXML形式をサポート
    If currentVersion >= 12# Then
        fileFormat = 52 ' xlOpenXMLWorkbookMacroEnabled
    Else
        ' 12.0未満(Excel 2003以前)の場合はバイナリ形式を指定
        fileFormat = -4143 ' xlNormal
    End If
    
    ' 画面更新と警告を停止して高速化
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    
    On Error GoTo ErrorHandler
    
    ' 名前を付けて保存
    ActiveWorkbook.SaveAs Filename:=targetPath, FileFormat:=fileFormat
    
    MsgBox "保存が完了しました:" & vbCrLf & targetPath, vbInformation
    
ExitProc:
    Application.DisplayAlerts = True
    Application.ScreenUpdating = True
    Exit Sub
    
ErrorHandler:
    MsgBox "保存中にエラーが発生しました。" & vbCrLf & Err.Description, vbCritical
    Resume ExitProc
End Sub

コードの詳細解説と設計のポイント

上記のコードには、ベテランエンジニアが実務で必ず意識する「3つの防衛策」が組み込まれています。

1. 定数のハードコーディングを避ける工夫
本来であれば、Excelの定数(xlOpenXMLWorkbookMacroEnabledなど)をそのまま利用すべきですが、開発環境と実行環境の参照設定が異なる場合、コンパイルエラーを引き起こすリスクがあります。あえて数値(52や-4143)で指定することで、どのバージョンのExcelでも参照設定の不一致によるエラーを回避できます。

2. DisplayAlertsの制御
「名前を付けて保存」を行う際、同名のファイルが存在すると「上書きしますか?」というダイアログが表示されます。自動化処理においてこのダイアログはユーザーの操作を阻害するため、DisplayAlerts = Falseで一時的に抑制するのが鉄則です。ただし、処理終了後には必ずTrueに戻すことを忘れてはなりません。

3. エラーハンドリングの徹底
ファイルが読み取り専用で開かれている場合や、保存先に書き込み権限がない場合など、ファイル操作には予期せぬエラーがつきものです。On Error GoTo構文を用いて、万が一エラーが発生しても、Applicationの設定(画面更新や警告設定)を強制的に復旧させる仕組みを構築しています。

互換性問題を解決するための実務アドバイス

実務現場では、バージョンだけでなく「bit数(32bit vs 64bit)」の違いによるトラブルも頻発します。特にAPI呼び出しを行う場合、PtrSafe属性の付与が必要ですが、バージョン判定と同様に、コンパイル条件付きコンパイル定数(#If VBA7 Then …)を活用することで、1つのソースコードで両方の環境をカバーできます。

また、保存形式に関して、「どの形式で保存すべきか」という要件定義も重要です。例えば、CSV形式での保存が必要な場合、Excel 2007以降では「xlCSVUTF8(62)」という定数が使用できますが、これは非常に新しい定数であるため、古いExcel環境ではエラーになります。このように、特定の機能を利用する際は「その機能が実装された最小バージョン」をMicrosoftのドキュメントで確認し、if文でガードをかける習慣を身につけてください。

さらに、保存先のパス指定についても注意が必要です。SharePointやOneDriveなどのクラウドストレージ上に保存する場合、ローカルパス(C:\…)ではなく、URL形式のパスが必要になることがあります。ActiveWorkbook.PathがURLを返しているかどうかを判定するロジックを組み込むことで、より現代的な環境に適応したツールに昇華させることができます。

まとめ

Excel VBAにおけるバージョン判定とファイル保存は、単なるコード記述のテクニックではなく、システム全体の「安定性」を左右する重要な基盤です。

・Application.Versionで環境を特定する。
・定数は数値で管理し、参照設定の依存を排除する。
・DisplayAlertsとエラーハンドリングで安全な終了を保証する。

これら3点を守るだけで、あなたの作成するVBAツールは、異なるバージョンのExcelが混在するオフィス環境においても、極めて高い信頼性を発揮するようになります。技術者として、常に「どの環境で動かしても壊れないコード」を目指す姿勢こそが、真のプロフェッショナリズムであると私は確信しています。

日々の業務効率化において、こうした「環境への配慮」を積み重ねることで、メンテナンス性の高い、長く愛されるシステムを構築してください。VBAは古くて新しい言語です。正しい知識と設計思想があれば、現代のクラウド時代においても強力な武器となるはずです。

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