質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

Q&A

解決済

1回答

3885閲覧

Windows Excel [最近つかったもの] を取得したいです

shigeru

総合スコア38

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

0グッド

1クリップ

投稿2018/10/06 02:42

環境

Windows10
Excel2010

実現したいこと

あるデータベースアプリケーションから開いたExcelデータをVBAで取得したいのですが、別のExcelApplicationとして開くため最初から開いているExcelApplicationから取得することができず困っております。(Application クラスが別のため)

試してみた事

[最近使用したファイル]のCollection からフルパスを取得できないかと思い下記のコードを試しましたが、やはり別のExcelApplicationは取得できませんでした。

VBA

1Debug.Print Application.RecentFiles(1).Name

教えて頂きたいこと

下図のようにタスクバーから[最近つかったもの]であれば、別のExcelApplication であっても表示されることが分かりました。これを取得する方法をご教示願います。API も検索はしてみたのですが見つからず困っております。
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

質問の回答とは少し反れますが、別のインスタンスのエクセルでもGetObjectを使えば取得できますよ。

複数Excelが立ち上がっている場合は、もうちょっと厄介なコードが必要になりますが、Excelを2つ開いているわけでは無いようなのでこれでも対応出来ませんか?

エクセルが1つしか起動していない場合

VBA

1'起動中のエクセルのアクティブブック名を返す関数の例 2Function GetExcelBookName() As String 3 Dim xlAp As Object 'Excel.Application 4 Dim xlBk As Object 'Excel.Workbook 5 6 Set xlAp = GetObject(, "Excel.Application") 7 Set xlBk = xlAp.ActiveWorkbook 8 9 GetExcelBookName = xlBk.Name 10 11 Set xlBk = Nothing 12 Set xlAp = Nothing 13End Function

複数のエクセルプロセスに対応する場合

モジュール側(適当なモジュール名で保存)

VBA

1Option Explicit 2 3Private Declare Function EnumWindows Lib "user32.dll" _ 4 (ByVal lpEnumFunc As Long, _ 5 ByVal lParam As Long) As Long 6Private Declare Function GetClassName Lib "user32.dll" _ 7 Alias "GetClassNameA" _ 8 (ByVal hWnd As Long, _ 9 ByVal lpClassName As String, _ 10 ByVal nMaxCount As Long) As Long 11Private Declare Function EnumChildWindows Lib "user32.dll" _ 12 (ByVal hWndParent As Long, _ 13 ByVal lpEnumFunc As Long, _ 14 ByVal lParam As Long) As Long 15Private Declare Function GetWindowText Lib "user32.dll" _ 16 Alias "GetWindowTextA" _ 17 (ByVal hWnd As Long, _ 18 ByVal lpString As String, _ 19 ByVal nMaxCount As Long) As Long 20Private Declare Function SendMessage Lib "user32" _ 21 Alias "SendMessageA" _ 22 (ByVal hWnd As Long, ByVal Msg As Long, _ 23 ByVal wParam As Long, lParam As Any) As Long 24Private Declare Function IIDFromString Lib "ole32" _ 25 (lpsz As Any, lpiid As Any) As Long 26Private Declare Function ObjectFromLresult Lib "oleacc" _ 27 (ByVal lResult As Long, riid As Any, _ 28 ByVal wParam As Long, ppvObject As Any) As Long 29Private Declare Function IsWindow Lib "user32" _ 30 (ByVal hWnd As Long) As Long 31Private Const OBJID_NATIVEOM = &HFFFFFFF0 32Private Const OBJID_CLIENT = &HFFFFFFFC 33 34Private Const IID_IMdcList = "{8BD21D23-EC42-11CE-9E0D-00AA006002F3}" 35Private Const IID_IUnknown = "{00000000-0000-0000-C000-000000000046}" 36Private Const IID_IDispatch = "{00020400-0000-0000-C000-000000000046}" 37 38Private Const WM_GETOBJECT = &H3D& 39 40Private Type WbkDtl 41 hWndAp As Long 42 hWndWb As Long 43 xlAP As Excel.Application 44 xlWB As Excel.Workbook 45End Type 46Private wD() As WbkDtl 47 48' コールバック関数 49Private Function EnumWindowsProc(ByVal hWnd As Long, _ 50 ByVal lParam As Long) As Long 51 52 Dim strClassBuff As String * 128 53 Dim strClass As String 54 Dim lngRtnCode As Long 55 Dim lngThreadId As Long 56 Dim lngProcesID As Long 57 58 ' クラス名取得 59 lngRtnCode = GetClassName(hWnd, strClassBuff, Len(strClassBuff)) 60 strClass = Left(strClassBuff, InStr(strClassBuff, vbNullChar) - 1) 61 If strClass = "XLMAIN" Then 62 ' 子ウィンドウを列挙 63 lngRtnCode = EnumChildWindows(hWnd, _ 64 AddressOf EnumChildSubProc, lParam) 65 End If 66 ' 列挙を継続 67EnumPass: 68 EnumWindowsProc = True 69End Function 70 71' コールバック関数 - 子ウィンドウを列挙 72Private Function EnumChildSubProc(ByVal hwndChild As Long, _ 73 ByVal lParam As Long) As Long 74 Dim strClassBuff As String * 128 75 Dim strClass As String 76 Dim strTextBuff As String * 516 77 Dim strText As String 78 Dim lngRtnCode As Long 79 80 ' クラス名取得 81 lngRtnCode = GetClassName(hwndChild, strClassBuff, Len(strClassBuff)) 82 strClass = Left(strClassBuff, InStr(strClassBuff, vbNullChar) - 1) 83 If strClass = "EXCEL7" Then 84 ' テキストをバッファに 85 lngRtnCode = GetWindowText(hwndChild, strTextBuff, Len(strTextBuff)) 86 strText = Left(strTextBuff, InStr(strTextBuff, vbNullChar) - 1) 87 88 If InStr(1, strText, ".xla") = 0 Then ' 89 If Sgn(wD) = 0 Then 90 ReDim wD(0) 91 wD(0).hWndWb = hwndChild 92 Else 93 ReDim Preserve wD(UBound(wD) + 1) 94 wD(UBound(wD)).hWndWb = hwndChild 95 End If 96 End If 97 End If 98 ' 列挙を継続 99EnumChildPass: 100 EnumChildSubProc = True 101End Function 102 103Private Sub GetExcelBook(wDl As WbkDtl) 104 Dim IID(0 To 3) As Long 105 Dim bytID() As Byte 106 Dim lngResult As Long 107 Dim lngRtnCode As Long 108 Dim wbw As Excel.Window 109 110 If IsWindow(wDl.hWndWb) = 0 Then Exit Sub 111 lngResult = SendMessage(wDl.hWndWb, WM_GETOBJECT, 0, ByVal OBJID_NATIVEOM) 112 If lngResult Then 113 bytID = IID_IDispatch & vbNullChar 114 IIDFromString bytID(0), IID(0) 115 lngRtnCode = ObjectFromLresult(lngResult, IID(0), 0, wbw) 116 If Not wbw Is Nothing Then 117 Set wDl.xlWB = wbw.Parent 118 Set wDl.xlAP = wbw.Application 119 wDl.hWndAp = wbw.Application.hWnd 120 End If 121 End If 122End Sub 123 124'起動中のエクセルのApplicationオブジェクトの配列を返す 125Public Function GetExcelApplications() As Variant 126 Dim lngRtnCode As Long 127 Dim i As Long 128 Dim DicApp As Dictionary 129 Dim Key As Variant 130 Dim Apps() As Excel.Application 131 132 Set DicApp = New Dictionary 133 134 Erase wD 135 lngRtnCode = EnumWindows(AddressOf EnumWindowsProc, ByVal 0&) 136 For i = 0 To UBound(wD) 137 Call GetExcelBook(wD(i)) 138 If Not DicApp.Exists(wD(i).hWndAp) Then 139 DicApp.Add wD(i).hWndAp, wD(i).xlAP 140 End If 141 Next 142 143 If DicApp.Count > 0 Then 144 ReDim Apps(1 To DicApp.Count) 145 i = 0 146 For Each Key In DicApp.Keys 147 i = i + 1 148 Set Apps(i) = DicApp(Key) 149 Next 150 End If 151 152 GetExcelApplications = Apps 153End Function

呼び出し側(任意のモジュールに記載)

VBA

1'Excel Applicationごとのアクティブワークブックの名前をイミディエイトウィンドウに出力 2Sub Test_ExcelApps() 3 Dim App As Variant 4 For Each App In GetExcelApplications 5 Debug.Print App.ActiveWorkbook.Name 6 Next 7End Sub

投稿2018/10/06 04:26

編集2018/10/06 07:32
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shigeru

2018/10/06 05:12

Excelは2つ開いている状態のため困っております。説明が足りておらずすいません。 状況は下記の通りです ①  [ Book_A ] を開いている (これにコードを書きます) ② 別のExcel Application から [ Book_B ] が開く(システム上勝手に別のExcelApplicationとして開いてしまう) この状態で [ Book_A ] から [ Book_B ] のデータを取得したい
shigeru

2018/10/06 06:55

ありがとうございます。 コードの実行をしてWorkbookのオブジェクトを取得できることは確認しました。 Windows API を使用してWindowハンドルから検索をして取得する。ということでしょうか。まずはゆっくりコードを確認してみたいと思います。(私ではこのコード全て理解するのは無理かもしれませんが…) もし整えたものを追記頂けましたら助かります。
退会済みユーザー

退会済みユーザー

2018/10/06 07:20

夜に・・・と言いましたが時間が出来たので追記しました。関数化したので中身は理解しなくても大丈夫だと思います。
shigeru

2018/10/06 07:57

早速ありがとうございます! コード実行をしてそれぞれのExcelを取得できることを確認しました!学習のために夜にもう一度じっくりコードを読みたいと思いますのでまた書込みさせて頂きます。
shigeru

2018/10/06 13:15

コードを理解しようとしましたがやはり今の私では理解しきれませんでした・・・。コードの質問をするとキリがなさそうなので、すいませんが1点だけご教示いただけますでしょうか。 下記の関数は何を取得しているのですか? ’ コールバック関数 Private Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Long
退会済みユーザー

退会済みユーザー

2018/10/06 14:48

コールバック関数については調べましたか? Win32APIの関数では引数に関数へのポインタを持つものがあります。 今回で言うとEnumWindows関数ですね。 https://msdn.microsoft.com/ja-jp/library/cc410851.aspx EnumWindows(AddressOf EnumWindowsProc, ByVal 0&)の部分で、EnumWindowsにEnumWindowsProcのアドレスを渡しています。 その後F8でステップしていくと何度も何度もEnumWindowsProcが呼び出されるのが分かると思いますが、これは(VBEでは閲覧出来ないが)EnumWindows関数の中から呼び出されているのです。 「何を取得しているのですか?」の解は「トップレベルウィンドウ(のウィンドウハンドル)」ですね。 コールバック関数やAddressOfは普通にVBAを使っているうちは見かけることは無いのですが、APIでは時々見かけるので注意してくださいね。
shigeru

2018/10/07 12:28

とてもご丁寧にありがとうございます。一つずつ調べながら学習したいと思います。今回は助かりました、業務の様々な場面で役立てることができそうです。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問