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

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

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

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

Q&A

解決済

1回答

1676閲覧

ExcelVBAにおけるTreeViewのindexプロパティについて

dewdtm

総合スコア8

VBA

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

0グッド

0クリップ

投稿2018/07/10 08:44

ExcelVBAにおけるTreeViewのindexプロパティについて質問です。
http://nonsoft.la.coocan.jp/SoftSample/SampleEnumWindows.html
上記サイトのコードを用いることで
現在実行中のハンドル情報(親・子含む)をすべてTreeViewに列挙することができます。

今回お訊ねしたいのが、
親ウインドウハンドルのクラス名とタイトル名は取得できるものの
目当ての子ウィンドウらがテキストボックスのためタイトル名が取得できず、
座標指定もシステム上、不可能(ターゲットがフルスクリーン非対応)であり、
残るはindexプロパティで、指定の子ウィンドウハンドルが上から何番目に該当するのか取得するほかありません。

しかし、ExcelVBAにおけるindexプロパティの使用方法が検索してもなかなか見つけられず、
唯一、載っていた下記のサイトも、肝心のindexプロパティの説明は省いています。
http://officetanaka.net/excel/vba/treeview/06.htm

どうにか、Excelの特定のセルに配置されたデータを
外部アプリの子ウィンドウであるテキストボックスに送信したいのですが、
何か方法はありますでしょうか。

分かりにくい説明で申し訳ございません。
何とぞ、宜しくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

まずindexですが、上位ノードから子も含めて順番に振られるようです。
こんな感じ(括弧内はindex)

親1(1) +- 子1(2) +- 子2(3) 親2(4) +- 子1(5) +- 子2(6)

で本題ですが、リンク先のサンプルを活用する前提でしょうか。
利用シーンが見えないので、例えばツリービューから対象とするテキストボックスを選択してからボタンを押すと送信するとか。
であるなら、選択されているアイテムのIndexを取得すれば、そのノードを直接参照することができます。

VBA

1Debug.Print TreeView1.Nodes(TreeView1.SelectedItem.Index)

親だけ指定して何番目というのは固定にするなら、

VBA

1childnum = 5 2Debug.Print TreeView1.Nodes(TreeView1.SelectedItem.Index + childnum)

とするとか。

ツリービューをそのまま使うのか、使わないのか、もう少し詳しい情報があるとよりよい回答が得られると思います。

投稿2018/07/10 10:12

ttyp03

総合スコア16998

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

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

dewdtm

2018/07/11 00:37

ttyp03様 とても参考になるご回答をいただきまして、誠にありがとうございます。 大変感謝いたします。 やはり私の説明が粗雑で不十分でした、申し訳ございません。 上記サイト様のサンプルは使用するという前提で、TreeViewは不可視にし裏で列挙させ、 アイテムのSelectはしないという状況下で走らせたいと思っております。 .SelectedItemを使わずに、該当の親ウインドウを指定するには、 どのように記述すれば実現できますでしょうか。 何とぞご教示の程、宜しくお願いいたします。
ttyp03

2018/07/11 00:55

TreeViewは使用する(但し不可視)という前提ですと、あらかじめFindWindowか何かで親ウィンドウのハンドルを取得しておく。 TreeViewを構築した後、全ノードから親ウィンドウのハンドルと同じ値を持つノードを探す。 そのノードから目的のテキストボックスの位置までIndexをインクリメントすればよろしいかと思います。 ざっくりコードを書いておくと(引数とかは適当です) hWndParent = FindWindow(親ウィンドウタイトル) TreeView構築 For idx = 1 To TreeView1.Nodes.Count If TreeView1.Nodes(idx) = hWndParent Then hWndChild = TreeView1.Nodes(idx + n) ' nはテキストボックスが何番目にあるかを表す Exit For End If Next hWndChild にテキスト送信 TreeViewを活かす場合はこんな感じになると思います。 たぶんTreeViewの構築処理で同じようなことをすれば、TreeView自体使わなくて出来るはずです。
ttyp03

2018/07/11 00:57

あ、TreeViewに登録する値はハンドル値だけにしておく必要がありますね。 ' 取得した情報を配列に設定 Dim strDa(2) As Variant strDa(0) = hWnd ’strDa(1) = strClass 要らない 'strDa(2) = strTitle 要らない
dewdtm

2018/07/11 02:34

ttyp03様 早急にご回答いただきまして、誠にありがとうございます。 早速試してみましたところ、仰るようにハンドル値のみにしなければ、TreeView1.Nodes(idx)部分で 型の不一致エラーが出てしまい、その後に頂いた情報をあれこれ考えていたのですが、 なに分、私の能力不足から、せっかくいただいた配列のコードを活かすことができずにおります。 外部アプリのテキストボックスへの送信自体は、下記のコードで行っておりますので、ご指摘のあったTreeViewを使わずに実現させる方向でいく場合、頂いたコードを用いてlnghWndTargetに子ハンドルの値を入れてあげれば完成いたします。 lnghWnd = FindWindowEx(0, 0, "WindowsForms10.Window.8.app.0.1a0e24_r12_ad1", "タイトル名") '親ウィンドウハンドル lnghWndTarget = FindWindowEx(lnghWnd, 0, "WindowsForms10.EDIT.app.0.1a0e24_r12_ad1", "") '子ハンドル_テキストボックス strDt = "test" lngRc = SendMessageAny(lnghWndTarget, WM_SETTEXT, 0, strDt) あと一歩、お付き合い願えましたら大変幸いに思います。 不甲斐ない質問者と思って、どうかご教示の程、宜しくお願いいたします。
ttyp03

2018/07/11 02:40

なんか色々混ざっているようなので、一旦整理させてください。 ・Nodes(idx)の型不一致エラーは解消できたのか ・配列のコードを活かすとは? ・TreeViewは使うのか(非表示で) ・TreeViewは使わない(非表示でも)場合のやり方を聞いているか
dewdtm

2018/07/11 03:10

ttyp03様 色々とフラフラしてしまって申し訳ございません。 まず、Nodes(idx)の不一致エラーですが、それが解消できていないためご質問させていただきました。 配列コードとは、ttyp03様がコメントされたDim strDa(2) As Variantのコードです。 どう利用すればよいのか分かりませんでした。 TreeViewを使わない方向で考えを巡らせ、 前回のコメントのような形で、直接外部へ送信するコードを示しました。 宜しくお願いいたします。
ttyp03

2018/07/11 04:46

すみません、昨日動いたはずのサンプルコードが今日は動かなくて回答が遅れました(結局動かなかった…) 配列の件はすみません、私の間違いです。 とりあず忘れてください。 サンプルコードが動かないので動作確認はできていないのですが、型の不一致の件は次のようにすればいけるような気がします。 Formのループ箇所を次のように変えます。 クラス名やタイトルも登録していたのを、ハンドルだけに変更しています。 ' 子コントロール毎のコレクションループ For j = 1 To colChilds.Count If j = 1 Then ' 親ウィンドウの情報をツリービューへ追加 Call TreeView1.Nodes.Add(, , _ "R" & Right$("00000000" & Hex(colChilds.Item(j)(0)), 8), _ "&H" & Right$("00000000" & Hex(colChilds.Item(j)(0)), 8)) Else ' 子コントロールの情報をツリービューへ追加 Call TreeView1.Nodes.Add("R" & Right$("00000000" & Hex(colChilds.Item(1)(0)), 8), _ tvwChild, _ "C" & Right$("00000000" & Hex(colChilds.Item(j)(0)), 8), _ "&H" & Right$("00000000" & Hex(colChilds.Item(j)(0)), 8)) End If Next j で、例の不一致の箇所は、次のようなコードにすればエラーは解消できると思います。 If CLng(TreeView1.Nodes(idx)) = hWndParent Then
dewdtm

2018/07/11 05:35

ttyp03様 見事に実現できました! 素晴らしいです! サンプルコードのノード構築部分から改変しなければならなかったのですね。 クラス名とタイトル名を切り離してハンドルのみになった16進数のデータを 10進数に置換した値が、しっかりhWndChildに格納されておりました。 一人で頭を抱えていたら一体何ヶ月かかったことか分かりません。 心から感謝申し上げます。 また別件で質問することがあると思いますので、 ご縁がありましたら、何とぞ次回も宜しくお願いいたします。 今回は本当にありがとうございました。
ttyp03

2018/07/11 05:37

動作確認できてなかったので心配でしたが、なんとか動いたようで安心しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問