はじめに
今回は、以前投稿した下記の記事について、条件次第では問題が解決しない可能性があるようなので、追加で対応方法を書いていきます。

参照不可の問題が起きる原因
そもそも、Microsoft Excel *.* Object Library への参照不可の問題が起きる原因としては、新しいバージョンのOfficeがインストールされている端末で起動した際に自動で新しいバージョンのライブラリに切り替えられることによって、その後、古いバージョンのOffice端末で起動した時に新しいバージョンのライブラリがインストールされていないために起きる不具合となります。
このとき、古いバージョンのライブラリに切り替われば問題ないのですが、Officeの仕様上切り替わらないようになっているようです。
Office 2010 で開くと、Office 2016用のExcel Library(Ver.16.0)が参照不可になっていることわかります。
これは、Office 2010ではVer.14.0のみインストールされているために起きる現象です。
パスを見るとOffice 16のフォルダを参照しようとしています。
これらの問題を解決するため、以前にいくつかの手法を試し、私が持っている環境で不具合なく稼働したのを確認したのが下記の記事でした。

しかしながら、この記事で紹介した参照不可になっているライブラリを解除する方法ではバージョンによってライブラリを解除する際にエラーが発生することがわかりました。(Office 2000以降)
その後、いくつかの方法でライブラリを解除する方法を探りましたが、全て失敗し完全なる解決には至りませんでした。
対策
・・・が、このままではいけないと思い、ようやく時間に余裕ができてきたこともあって、問題を解決するためにさらにいくつか試行錯誤したところ、最終的には参照設定をせずにCreateObjectでExcelを呼び出すという選択をしました。(参照設定することを諦めた。
とはいえ、多くのプロシージャでいくつものExcelファイルを操作する時に、繰り返しで何回も呼び出していたらタスクに多くのExcelプロセス(Excel.exe)が溜まってしまいます。頑張れば全てのプロセスを開放できることも可能ですが、毎回毎回プロセスを開放するコードを書くのが手間なので、ただ単に呼び出すという手法はやめました。
上記問題を考慮した結果、CreateObjectでExcelを呼び出す処理をクラスとしてまとめ、標準モジュール等でインスタンスを生成することにしました。
クラスにまとめることで、プロシージャ内にてクラスをインスタンスを生成した時は、プロシージャの処理が終わった際にプロセスを自動で開放できるようになります。
コード
では実際にコードを載せます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
Option Compare Database Option Explicit 'どのようなExcelのバージョンでも動くようにするおまじない Private Application_ As Object Private ErrFlag As Boolean '_________________________________________________ Public Property Get Workbooks() As Object Set Workbooks = Application_.Workbooks End Property '_________________________________________________ Public Property Get Application() As Object Set Application = Application_ End Property '_________________________________________________ 'クラスを呼び出したとき Private Sub Class_Initialize() Dim Win64Flag As Boolean Dim ErrMsg As String ErrFlag = False 'Excelを呼び出す。 On Error GoTo Err: Set Application_ = CreateObject("Excel.Application") On Error GoTo 0 Exit Sub 'エラーの時 Err: ErrFlag = True ErrMsg = Err.Description #If Win64 Then Win64Flag = True #Else Win64Flag = False #End If MsgBox "Microsoft Office Excel がインストールされていない、" & vbLf & "または予期せぬエラーが出力されています。" & vbLf & vbLf & _ "Access Version : " & Access.Application.Version & vbLf & _ "Access WinAPI : " & IIf(Win64Flag, "64bit", "32bit") & vbLf & _ "Error Message : " & vbLf & ErrMsg, vbCritical On Error GoTo 0 End End Sub '_________________________________________________ 'クラスが解放されるとき Private Sub Class_Terminate() 'クラスを呼び出したときにエラーになっていなければ If Not ErrFlag Then 'Excelを終了しプロセスを開放する。 Application_.Quit Set Application_ = Nothing End If End Sub '_________________________________________________ |
このコードを新しく作ったクラスモジュールに張り付けて、Excelを使いたいプロシージャ内でインスタンス化(型宣言)してください。
そうすると、ApplicationメソッドとWorkbooksメソッドが利用できるようになります。(この二つがあれば大抵のメソッドは使える
例) Dim clsExcel As New クラスモジュール名 : Msgbox clsExcel.Application.Version
プロシージャ内で宣言することでプロシージャの処理が完了したら自動でプロセスが解放されます。(Staticは不明)
上記プログラムの全てのExcel系オブジェクト(Workbook等)の型宣言がObjectになっている理由は、Excelを読み込むまでは実行時エラーが発生するからです。
本当はExcelの型で宣言したいけど我慢しました。
以上。今回はここまでとなります。
---コメント---