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

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

ただいまの
回答率

90.52%

  • VBA

    1798questions

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

  • Excel

    1535questions

    Excelは、マイクロソフト社が開発しているデータ集計や分析を行う表計算ソフトの一つです。文書作成や表計算、資料作成などの多彩な機能を備えており、統合パッケージであるMicrosoft Officeに含まれています。

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

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 304

dewdtm

score 2

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

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

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

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

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

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

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


とするとか。

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/11 09:37

    ttyp03様

    とても参考になるご回答をいただきまして、誠にありがとうございます。
    大変感謝いたします。

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

    何とぞご教示の程、宜しくお願いいたします。

    キャンセル

  • 2018/07/11 09: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自体使わなくて出来るはずです。

    キャンセル

  • 2018/07/11 09:57

    あ、TreeViewに登録する値はハンドル値だけにしておく必要がありますね。

    ' 取得した情報を配列に設定
    Dim strDa(2) As Variant
    strDa(0) = hWnd
    ’strDa(1) = strClass 要らない
    'strDa(2) = strTitle 要らない

    キャンセル

  • 2018/07/11 11: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)

    あと一歩、お付き合い願えましたら大変幸いに思います。
    不甲斐ない質問者と思って、どうかご教示の程、宜しくお願いいたします。

    キャンセル

  • 2018/07/11 11:40

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

    キャンセル

  • 2018/07/11 12:10

    ttyp03様

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

    宜しくお願いいたします。

    キャンセル

  • 2018/07/11 13: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

    キャンセル

  • 2018/07/11 14:35

    ttyp03様

    見事に実現できました!
    素晴らしいです!

    サンプルコードのノード構築部分から改変しなければならなかったのですね。
    クラス名とタイトル名を切り離してハンドルのみになった16進数のデータを
    10進数に置換した値が、しっかりhWndChildに格納されておりました。

    一人で頭を抱えていたら一体何ヶ月かかったことか分かりません。
    心から感謝申し上げます。

    また別件で質問することがあると思いますので、
    ご縁がありましたら、何とぞ次回も宜しくお願いいたします。
    今回は本当にありがとうございました。

    キャンセル

  • 2018/07/11 14:37

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

    キャンセル

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

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • VBA

    1798questions

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

  • Excel

    1535questions

    Excelは、マイクロソフト社が開発しているデータ集計や分析を行う表計算ソフトの一つです。文書作成や表計算、資料作成などの多彩な機能を備えており、統合パッケージであるMicrosoft Officeに含まれています。