| | タイトル | : Re: 既に開いてあるExcelのPathを取得 |  | 記事No | : 13821 |  | 投稿日 | : 2009/07/07(Tue) 15:32 |  | 投稿者 | : YK | 
 こんにちは。起動中のワークブックオブジェクトを取得できます。
 リストボックスにワークブックオブジェクトのフルネームを表示します。
 
 Form にコマンドボタンとリストボックスを各一個貼り付けて
 実行してみて下さい。
 
 参照設定 Microsoft Excel XX.X Object Libray
 Accessibility  は OLEACC.DLL を参照する
 
 ******************* Standard Module ********************
 
 Option Explicit
 Private Declare Function EnumWindows Lib "user32.dll" _
 (ByVal lpEnumFunc As Long, _
 ByVal lParam As Long) As Long
 
 Private Declare Function GetClassName Lib "user32.dll" _
 Alias "GetClassNameA" _
 (ByVal hWnd As Long, _
 ByVal lpClassName As String, _
 ByVal nMaxCount As Long) As Long
 
 Private Declare Function EnumChildWindows Lib "user32.dll" _
 (ByVal hWndParent As Long, _
 ByVal lpEnumFunc As Long, _
 ByVal lParam As Long) As Long
 
 Private Declare Function GetWindowText Lib "user32.dll" _
 Alias "GetWindowTextA" _
 (ByVal hWnd As Long, _
 ByVal lpString As String, _
 ByVal nMaxCount As Long) As Long
 
 Private Declare Function IIDFromString Lib "ole32" _
 (lpsz As Any, lpiid As Any) As Long
 
 Private Declare Function ObjectFromLresult Lib "oleacc" _
 (ByVal lResult As Long, _
 riid As Any, _
 ByVal wParam As Long, _
 ppvObject As Any) As Long
 
 Private Declare Function AccessibleObjectFromWindow Lib "oleacc" _
 (ByVal hWnd As Long, _
 ByVal dwObjectID As Long, _
 ByRef riid As Any, _
 ByRef ppvObject As Any) As Long
 Private Type GUID
 Data1 As Long
 Data2 As Integer
 Data3 As Integer
 Data4(0 To 7) As Byte
 End Type
 
 Private Enum NVADIRConstants
 NAVDIR_MIN
 NAVDIR_UP
 NAVDIR_DOWN
 NAVDIR_LEFT
 NAVDIR_RIGHT
 NAVDIR_NEXT
 NAVDIR_PREVIOUS
 NAVDIR_FIRSTCHILD
 NAVDIR_LASTCHILD
 NAVDIR_MAX
 End Enum
 Private Declare Function IsWindow Lib "user32" _
 (ByVal hWnd As Long) As Long
 
 Private Const CHILDID_SELF As Long = 0&
 Private Const OBJID_NATIVEOM = &HFFFFFFF0
 Private Const OBJID_CLIENT = &HFFFFFFFC
 
 '固有の型を指定しても問題無さそうなのですが
 'その場合は、EXCEL.EXEをOleView.Exe(Platform SDKに付属)で開いて
 'IIDを調べて指定した方が無難かも知れません。 ↓
 Private Const IID_IDispatch = "{00020400-0000-0000-C000-000000000046}"
 
 Private Const WM_GETOBJECT = &H3D&
 
 Type WbkDtl
 hWnd        As Long
 wkb         As Excel.Workbook
 End Type
 Public wD()     As WbkDtl
 
 ' コールバック関数
 Private Function EnumWindowsProc(ByVal hWnd As Long, _
 ByVal lParam As Long) As Long
 Dim strClassBuff    As String * 128
 Dim strClass        As String
 Dim lngRtnCode      As Long
 Dim lngThreadId     As Long
 Dim lngProcesID     As Long
 
 ' クラス名取得
 lngRtnCode = GetClassName(hWnd, strClassBuff, Len(strClassBuff))
 strClass = Left(strClassBuff, InStr(strClassBuff, vbNullChar) - 1)
 If strClass = "XLMAIN" Then
 ' 子ウィンドウを列挙
 lngRtnCode = EnumChildWindows(hWnd, AddressOf EnumChildSubProc, lParam)
 End If
 ' 列挙を継続
 EnumPass:
 EnumWindowsProc = True
 End Function
 
 ' コールバック関数 - 子ウィンドウを列挙
 Private Function EnumChildSubProc(ByVal hwndChild As Long, _
 ByVal lParam As Long) As Long
 Dim strClassBuff    As String * 128
 Dim strClass        As String
 Dim strTextBuff     As String * 516
 Dim strText         As String
 Dim lngRtnCode      As Long
 
 ' クラス名取得
 lngRtnCode = GetClassName(hwndChild, strClassBuff, Len(strClassBuff))
 strClass = Left(strClassBuff, InStr(strClassBuff, vbNullChar) - 1)
 If strClass = "EXCEL7" Then
 ' テキストをバッファに
 lngRtnCode = GetWindowText(hwndChild, strTextBuff, Len(strTextBuff))
 strText = Left(strTextBuff, InStr(strTextBuff, vbNullChar) - 1)
 If InStr(1, strText, ".xla") = 0 Then     '
 If Sgn(wD) = 0 Then
 ReDim wD(0)
 wD(0).hWnd = hwndChild
 Else
 ReDim Preserve wD(UBound(wD) + 1)
 wD(UBound(wD)).hWnd = hwndChild
 End If
 End If
 End If
 ' 列挙を継続
 EnumChildPass:
 EnumChildSubProc = True
 End Function
 
 '***********   OLEACC.DLL を参照すること  *************
 
 Private Sub GetExcelBookDObj(wDl As WbkDtl)
 Dim IID(0 To 3) As Long
 Dim bytID()     As Byte
 Dim lngResult   As Long
 Dim lngRtnCode  As Long
 Dim wbw         As Excel.Window
 Dim objAcc      As IAccessible
 Dim wb          As Workbook
 If IsWindow(wDl.hWnd) = 0 Then Exit Sub
 bytID = IID_IDispatch & vbNullChar
 IIDFromString bytID(0), IID(0)
 lngRtnCode = AccessibleObjectFromWindow(wDl.hWnd, OBJID_NATIVEOM, IID(0), objAcc)
 If Not objAcc Is Nothing Then Set wDl.wkb = objAcc.Parent
 End Sub
 
 
 Sub Main_Proc()
 Dim lngRtnCode  As Long
 Dim i           As Long
 Erase wD
 '   ワークブックのウィンドウハンドルを取得 WorkBook->EXCEL7
 lngRtnCode = EnumWindows(AddressOf EnumWindowsProc, ByVal 0&)
 If Sgn(wD) <> 0 Then
 For i = 0 To UBound(wD)
 Call GetExcelBookDObj(wD(i))
 Next
 End If
 End Sub
 
 
 ************ Form Module ********************
 Option Explicit
 
 Private Sub Command1_Click()
 Dim i   As Long
 Me.List1.Clear
 Call Main_Proc
 If Sgn(wD) <> 0 Then
 For i = 0 To UBound(wD)
 If Not wD(i).wkb Is Nothing Then
 Me.List1.AddItem wD(i).wkb.FullName
 End If
 Next
 End If
 End Sub
 
 |