[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『TreeViewのチェックボックスのチェック状態を親階層と子階層で連動させる方法』(あみ)
VBA初心者です。
調べてはみたんですが全く分かりませんでした・・・
下記の情報を知りたいです。ご存知の方がいらっしゃいましたら教えて頂きたいです。
・TreeViewのチェックを付けた、外した時のイベント
・親階層がチェックされた時子階層のチェックを全て外す方法
・子階層のチェックが全て外れたときに親階層のチェックを外す方法(できれば全て外れたときの親階層の子階層をみて全て外れていたらチェックが外れるような処理を付けたいかなとは思っています)
・ノードのチェック状態の取得
結構インターネットでvbaの事を調べようとするとC#とかの他の言語では解説されているけどvbaには書いていないことが多いです。。。私の検索の仕方が悪いのもあると思いますが。。。
どこかに細かい情報まで記載してあるサイトとかがありました教えて頂きたいです。よろしくお願いいたします。
< 使用 Excel:unknown、使用 OS:unknown >
コメントがつかないようなので、前座で。
VBAにおけるTreeViewについては http://officetanaka.net/excel/vba/treeview/ が参考になりますが、当然、すでに閲覧されているでしょう。
# でも、これはちょっと古い記事なんでしょうか。 # 私の環境(Excel2010、これも十分古いですが)では、 # 参照設定も違いますし、ImageListコントロールは使えませんでした。
TreeViewコントロールだけなら、下記を参考に表示はできました。 http://www.tetsuexcelvba.com/article/430892561.html
ただし、書かれているニーズに関連して、 「TreeViewの親ノードのチェックボックスをダブルクリックすると、 子ノードに親ノードのチェック状態が反映されない場合がある」 https://support.microsoft.com/ja-jp/help/2781622 などという悲報もあり、雲行き怪しい感じですね。
世の中的にそうしたニーズをお持ちの方が少なく、 いらっしゃってもVB C#方面に転進されることが、 記事の少ない理由なんでしょうか。
オブジェクトブラウザーから辿ると、 TreeViewのプロパティ、メソッド、イベントが解りますから、 他の言語の仕様も考慮し、それで類推していくしかないかも知れませんね。
(γ) 2019/10/17(木) 21:39
下記を参考にTreeViewを表示してみました」。 http://www.tetsuexcelvba.com/article/430892561.html
オブジェクトブラウザを見ながら、下記の(1)(2)(4)について、 下記コードを作成してみました。参考にしてみてください。
| (1)TreeViewのチェックを付けた、外した時のイベント | (2)親階層がチェックされた時子階層のチェックを全て外す方法 | (3)子階層のチェックが全て外れたときに親階層のチェックを外す方法 | (できれば全て外れ たときの親階層の子階層をみて全て外れていたら | チェックが外れるような処理を付けたい かなとは思っています) | (4)ノードのチェック状態の取得
(3)については、NextやPrevious,Parentなどを使うとできるんじゃないでしょうか。 トライしてみてください。
Option Explicit
Private Sub UserForm_Initialize() Dim i As Long Dim Rltiv As Variant Dim Rltsp As TreeRelationshipConstants Dim WS As Worksheet Dim TV As TreeView
Set WS = Worksheets(1) Set TV = Me.TreeView1 TV.CheckBoxes = True Me.TreeView1.Nodes.Clear ' TreeView
Rltiv = Null Rltsp = 0 '変数Rltspの型がTreeRelationshipConstantsなので、tvwFirstでもよ い
With WS For i = 2 To .Cells(.Rows.Count, 1).End(xlUp).Row TV.Nodes.Add(Relative:=Rltiv, Relationship:=Rltsp, _ Key:="A" & .Cells(i, 1), Text:=.Cells(i, 2)).Expanded = True '■ここだけExpandするよう変更しています。 Rltiv = "A" & .Cells(i + 1, 3) '3列目,親ノード(ParentID)を取得 Rltsp = tvwChild Next i End With Set WS = Nothing Set TV = Nothing End Sub
'■以下はノードのチェックをつけたときの対応例です。 Private Sub TreeView1_NodeCheck(ByVal Node As MSComctlLib.Node) Dim ch As Node
If Node.Checked Then If Node.Children > 0 Then Set ch = Node.Child ch.Checked = False Do If Not ch.Next Is Nothing Then Set ch = ch.Next ch.Checked = False Else Exit Do End If Loop End If End If End Sub # 再帰的にさらに子供に影響することはない仕様のようです。
(γ) 2019/10/17(木) 22:34
ついでに、(3)についても書いて見ました。 全体を少し修正しています。
<<UserFormモジュール>> Private Sub UserForm_Initialize() Dim ws As Worksheet Dim tv As TreeView Dim rltiv As Variant Dim rltsp As TreeRelationshipConstants Dim i As Long
Set ws = Worksheets(1) Set tv = Me.TreeView1 tv.CheckBoxes = True '■ここも追加していました。 tv.Nodes.Clear
With ws rltiv = Null rltsp = tvwFirst i = 2 tv.Nodes.Add(Relative:=rltiv, Relationship:=rltsp, _ Key:="A" & .Cells(i, 1), Text:=.Cells(i, 2)).Expanded = True
For i = 3 To .Cells(.Rows.Count, 1).End(xlUp).Row rltiv = "A" & .Cells(i, 3) rltsp = tvwChild tv.Nodes.Add(Relative:=rltiv, Relationship:=rltsp, _ Key:="A" & .Cells(i, 1), Text:=.Cells(i, 2)).Expanded = True Next i End With Set ws = Nothing Set tv = Nothing End Sub
Private Sub TreeView1_NodeCheck(ByVal Node As MSComctlLib.Node) Dim nd As Node Dim flag As Boolean
If Node.Checked Then 'checkをつけた時 '子階層のチェックをすべて外す If Node.Children > 0 Then Set nd = Node.Child '先頭の子 nd.Checked = False Do If Not nd.Next Is Nothing Then Set nd = nd.Next nd.Checked = False Else Exit Do End If Loop End If Else 'checkを外したとき '■同階層のnodeのチェックがすべて外れていたら、親のチェックを外す。 flag = False Set nd = Node.FirstSibling '同階層の先頭node If nd.Checked = True Then flag = True Exit Sub End If Do If Not nd.Next Is Nothing Then Set nd = nd.Next If nd.Checked = True Then flag = True Exit Sub End If Else Exit Do End If Loop If flag = False Then If Not nd.Parent Is Nothing Then nd.Parent.Checked = False End If End If End If End Sub # 必要なのはコードではなく、参考情報ということなら、 # オブジェクトブラウザです。 (γ) 2019/10/18(金) 10:12
ただし、古いものなので、貴方のPC環境がXP以前なら良いのですが、最近のWINDOWS10、特に64bit版だと、コントロールのレジストリ登録が不完全なのか、ツリーに表示するアイコン指定するためのImageListのプロパティページが使えませんでした。 Excel標準の技術ではないし、MSが既に対応を止めたものだし、上級者でも使えるか判らないコントロールなので、初心者を自称するなら手を出さないのが良いと思います。(もし完成しても、他のPCで使おうとすると、コントロールのエラーになって動かない、とかあり得ます)
それよりも、なぜツリー表現がしたいのでしょうか? Excelに拘らないなら、例えばHTMLならjquery.treeview.cssというJavaScriptのフレームワークを使えば、簡単にツリー表現できます。(アイコンクリックでサブの展開とかアイコン変更とか、勝手にやってくれます) TreeView以外の実現を考えた方が良いと思いますよ。(もしツリー内容が可変ならば、ExcelでHTMLファイルを出力することは可能)
(???) 2019/10/18(金) 10:25
たしかに古い技術のようですね。
まあ、それ言うと、ExcelVBAそのものが全体としてはそういう傾向がありますね。 でも、今や、ユーザーインターフェイスとしてExcelは不可欠です。 金融(工学)の世界などでは、速度を要するところは他の言語でDLL化しておいて、 Excelからそれを利用するというのが、全体の80%〜90%なんだそうです。 Excelはそれだけ世の中で使われているという話。分野が特殊ですけど。
TreeViewを利用するかどうは、質問者さんのご判断ですね。
ちなみに、私の挙げた例でも >アイコンクリックでサブの展開 はできています。 というか、元々、そういう機能が組み込まれていますね。 チェックボックスのON,OFFのつど、特定の動作をすることも一応実現できています。 データの読み込みあたりは知らないけど。 (なお、既定では備わっていないchildNodesを返すメソッドなども、 Collectionを使えば可能ですし、.Nextがあるので現階層、子階層を traverseすることもツール化できるでしょう。)
===== ところで、ネット検索していてすごいなと思ったのをご紹介。【余談につき失礼】
Common controls treeではなく、MSForms2.0のうえでTreeViewを自作してしまったというもの。
https://jkp-ads.com/Articles/treeview.asp
Excel 2000〜Excel 2016 (32 and 64 bit)までは動作を確認してます、とのこと。 初回公開は2013年。今でも利用者からのコメントがあるようです。
上記サイトからExcelファイルがダウンロードできます。 デモがありますし、ドキュメントもしっかりできています。 パスワードとかは施してないので、クラスモジュールのコードなどもすべて読めます。 これはすごいなあ。ここまでやっちゃうんだ、というのが感想。 世間で使うかどうかは別。ダウンロードは3.5万件ほど。
ご参考まで。
(γ) 2019/10/19(土) 22:41
???さんへ
要件定義をよくしておらず、VBAでも頑張れば不可能はないと思ってやっていたからだと思います。。。
ちゃんと考えてから行動するようにします!!!
(あみ) 2019/10/24(木) 18:10
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.