親excelからShellで子excelを起動し、子excelが処理した後、親excelの処理を継続したい
お助けください
excel2010で上手く動いたマクロが、excel2016だと上手く動きません。
親excelから、子excelを自動起動し、子excelのマクロが動き自動終了し、
その後、親マクロの処理を継続したいと考えています。
再現方法
1つのフォルダの中にmother.xlsm(親excel)とchild.xlsm(子excel)を作成し、
それぞれのファイルに下のプログラムを設定します。
その後、親excelのマクロを実行します。
■caseA
Windows7+Excel2010環境だと、親excelから子excelを起動することに問題ない。
・子でApplication.Quitすると、子ブックだけ閉じて、親のマクロは継続する(finを表示する)
■caseB
Windows10+Excel2016環境だと、親excelから子excelを起動すると問題ある。
・子でApplication.Quitすると、親子のブックが同時に閉じる
・子でApplication.QuitせずにThisWorkbook.Closeすると、子ブックだけ閉じて、
親のブックは閉じないけど親のマクロが止まる(finが表示されない)
・本当は、caseAの様に、子ブックだけ閉じて、親のマクロを継続したい(finを表示したい)
▼mother.xlsm(標準モジュール)
Private Declare PtrSafe Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As LongPtr
Private Declare PtrSafe Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As LongPtr, lpExitCode As Long) As Long
Sub MotherExec()
Dim W_Instance As Long, W_Process As LongPtr, ret As Long, OFF_CODE As Long
childbook = "child.xlsm"
cmd = """" & Application.Path & "\excel.exe""" & " /r """ & ThisWorkbook.Path & "\" & childbook & """"
Set shl = CreateObject("WScript.Shell")
W_Instance = shl.Run(cmd, 1, True)
W_Process = OpenProcess(&H400 Or &H100000, True, W_Instance)
Do
ret = GetExitCodeProcess(W_Process, OFF_CODE)
DoEvents
Loop Until OFF_CODE <> &H103&
MsgBox "fin"
End Sub
▼child.xlsm(ThisWorkbookモジュール)
Sub workbook_open()
MsgBox "workbook_open"
If ThisWorkbook.ReadOnly = False Then Exit Sub
Application.Quit
'コメントアウト ThisWorkbook.Close
End Sub
補足
- 実際の子excelでは、重い処理が走るため、メモリリーク対策で、この構成になってます
- /rは、readonlyにしたい訳ではなく、workbook_openの実行/抑制を制御するためのトリックです
- 子excelにてworkbook_openの代わりにauto_openを試したところ、caseAでは動いたけど、caseBだと動かなかったのも不思議です
どなたか、お分かりになれば、よろしくお願いします。m(_ _)m