Access (VBA)

Access VBAに関するフォーラムです。
  • 掲示板への投稿には会員登録(無料)が必要です。会員登録がまだの方はこちら
  • 掲示板ご利用上のお願い」に反するご記入はご遠慮ください。
  • Q&A掲示板の使い方はこちらをご覧ください
トピックに返信
質問

 
(Windows 7 Professional : Access 2007)
複数のEXCELが混在するPCでバージョンを使い分ける
投稿日時: 17/11/21 13:36:08
投稿者: 真冬

お世話になります。
 
AccessのVBAからEXCELを起動して処理を行いたいのですが
現在使用しているPC上にはバージョンの異なるEXCELがインストールされています。
(2003,2007,2010,2013がインストールされています)
 
上記のバージョンのうちExcel2007を使用したいのですが
以下のように記述したところ、最後にインストールされたExcel2013が起動されているようです。
 
Set objExcel = CreateObject("Excel.Application.12")  …@
 
Set objBook01 = objExcel.Workbooks.Open("D:\xxx\Book01.xlsx", , True)



(以下略)
 
呼び出しているファイルが多いため、Shell関数でのオープンは避けたく、
上記の@部分のみを別の指定方法で対応できるようにならないでしょうか。
フルパスからの指定でも構いませんので、よろしくお願いいたします。
 
 

回答
投稿日時: 17/11/21 14:46:23
投稿者: sk

引用:
現在使用しているPC上にはバージョンの異なるEXCELがインストールされています
(2003,2007,2010,2013がインストールされています)

引用:
上記のバージョンのうちExcel2007を使用したいのですが
以下のように記述したところ、最後にインストールされた
Excel2013が起動されているようです。

引用:
Set objExcel = CreateObject("Excel.Application.12")

それは Office オートメーションにおける
仕様通りの動作です。
 
MS サポート より:
https://support.microsoft.com/ja-jp/help/292491/office-automation-when-multiple-versions-of-office-are-installed
 
引用:
呼び出しているファイルが多いため、Shell関数でのオープンは避けたく、
上記の@部分のみを別の指定方法で対応できるようにならないでしょうか。

例えば Shell 関数によって(ファイルを開くのではなく)
Office12 フォルダ内の EXCEL.EXE 単体を起動させて、
そのインスタンスへの参照を GetObject 関数によって
取得する、という方法が考えられますが、コードを実行した時点で
既に起動済みの Excel のプロセスが存在する可能性がある以上、
お奨めは出来ません。
 
(そもそも MS 社自身が、複数のバージョンの Office を
 1 台のコンピュータに共存させることを推奨していない)

投稿日時: 17/11/21 15:58:06
投稿者: 真冬

sk様
 
ご回答ありがとうございます。
 
ただオートメーションの仕様についてやMS推奨うんぬんの話がしたいのではありません。
その点は私も重々承知しておりますが、業務上、2007まで動いていたVBAが
2010以降ではエラーとなるため仕方なく複数のバージョンをインストールしている次第です。
週次業務のため平行して改修作業も行っています。
 
先週までは2007が起動していたので問題なかったのですが、
今日に限って2013が起動するようになっておりました。
 
どこかのサイトで起動したいバージョンのエクセルを直接フルパスから起動すればいいと
書いている方がいらっしゃったので、ご教授いただければと思いご質問いたしました。
朝から色々と検索しているのですが、未だに見つけられていない状況です。
 
ご理解いただけると幸いです。
 
Shell関数からのExcel起動については試してみたいと思います。
ありがとうございます。
 
その他にございましたら、教えてくださいませ。
よろしくお願いいたします。
 
 

投稿日時: 17/11/21 16:43:03
投稿者: 真冬

Shell関数は連続して処理を行う場合は不向きのようですね。
私のVBAでは残念ながら使えないようです。

回答
投稿日時: 17/11/21 17:21:27
投稿者: sk

引用:
Shell関数は連続して処理を行う場合は不向きのようですね。

(実際にどのようなコードを記述されたのか不明ですが)
1 つの Excel アプリケーションのインスタンス上で
複数の Excel ブックを開いてそれぞれを編集するような
自動処理を実行なさろうとしているのであれば、
Shell 関数と GetObject 関数の呼び出しは
1 回ずつで充分であるはず。
 
(標準モジュール)
-----------------------------------------------------------------------
Option Compare Database
Option Explicit
 
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
 
Private Sub subTest()
On Error GoTo Err_subTest
     
    Const ExcelAppPath As String = "C:\Program Files\Microsoft Office\Office12\EXCEL.EXE"
 
    Dim xlsApp As Object
    Dim xlsWorkbook As Object
     
    Dim lngRet As Long
    Dim lngCnt As Long
    Dim strFolderPath As String
    Dim strFileName As String
     
    strFolderPath = CurrentProject.Path & "\"
     
    strFileName = Dir(strFolderPath & "*.xlsx", vbNormal)
     
    If strFileName = "" Then
        MsgBox strFolderPath & " フォルダに .xlsx ファイルはありません。", _
               vbInformation, _
               "エラー"
        Exit Sub
    End If
     
    lngRet = Shell("""" & ExcelAppPath & """", vbHide)
     
    If lngRet = 0 Then
        MsgBox "Excel を起動できませんでした。", vbExclamation, "エラー"
        Exit Sub
    End If
     
    Sleep 2000
     
    Set xlsApp = GetObject(, "Excel.Application")
    xlsApp.DisplayAlerts = False
     
    lngCnt = 0
    Do Until strFileName = ""
        Set xlsWorkbook = xlsApp.Workbooks.Open(strFolderPath & strFileName)
        lngCnt = lngCnt + 1
        Debug.Print xlsWorkbook.Name & " のシートの数は " & _
                    xlsWorkbook.Sheets.Count & " 個です。"
         
        xlsWorkbook.Close False
        Set xlsWorkbook = Nothing
        strFileName = Dir()
    Loop
     
    MsgBox strFolderPath & " フォルダ内の" & lngCnt & " 個のブックを開いて閉じました。", _
           vbInformation, _
           "実行完了"
     
Exit_subTest:
On Error Resume Next
     
    xlsWorkbook.Close False
    Set xlsWorkbook = Nothing
    xlsApp.Quit
    Set xlsApp = Nothing
     
    Exit Sub
 
Err_subTest:
         
    MsgBox Err.Number & ": " & Err.Description, _
           vbCritical, _
           "実行時エラー(subTest)"
         
    Resume Exit_subTest
End Sub
-----------------------------------------------------------------------

投稿日時: 17/11/21 17:48:51
投稿者: 真冬

sk様
 
ご返信ありがとうございます。
 
shell関数は何とかネットを検索して使い方が分かったのですが
getobjectの使い方を勘違いしておりました。
こうやって使うのですね
丁寧な説明をありがとうございました。
 
早速、試してみたいと思います。
 
取り急ぎお礼まで
 
後程、改めて結果をご報告いたします。

回答
投稿日時: 17/11/25 01:26:54
投稿者: MMYS

真冬 さんの引用:

ただオートメーションの仕様についてやMS推奨うんぬんの話がしたいのではありません。
その点は私も重々承知しておりますが、

MSの仕様をご存知ならその旨書くべきです。無駄なやり取りや時間が発生します。
その上で、他に方法はないですか。と尋ねるべきかと。
 
複数のブックを開く処理はAccessVBAで行う必要はありませんよね。
Excel2007でマクロ付ブックを開き、そのブック内で処理すれば良いはず。
つまり、マクロ付ブックをExcel2007で開けば良い。
 
以下は参考までに WSH (VBS) のExcelバージョンを指定して起動するコードです。
起動する際、引数にブックを指定して起動しています。
実行パスはレジストリから取得します。
Version指定方法は直接レジストリを参照して下さい。
 
Dim WShell 
Dim sKeyValue 
Dim sVer 
Const xlsfile = "D:\Book1.xls"
 
str1 = "HKLM\Software\Microsoft\Office\" 
str2 = "\Excel\InstallRoot\Path" 
  
' ここでExcel Versionを指定 ... 
' 例えば、Excel2000 = 9.0, Excel2007 = 12.0
sVer = "12.0" 
 
Set WShell = CreateObject("WScript.Shell") 
  
On Error Resume Next 
sKeyValue = WShell.RegRead(str1 & sVer & str2) 
On Error GoTo 0 
  
If Len(sKeyValue) Then 
  WShell.Run Chr(34) & sKeyValue & "Excel.exe" & Chr(34) & " " & xlsfile, 1 
Else 
  MsgBox "Error" 
End If 

 

トピックに返信