お世話になります。
今回もツリービューについて質問させてください。
最上位のキーのみを取得したいのですが
ループの仕方がわかりません。
どなたか、お教え願います。
哺乳類
|---- うさぎ
|---- いぬ
鳥類
|---- はと
|---- インコ
の「哺乳類」と「鳥類」のキーのみ取得したい
VB4〜6 の TreeView ですか? VB.NET 2002〜2005 の TreeView ですか?
> ループの仕方がわかりません。
こんな感じで。
For Each N In TreeView1.Nodes
If N.Parent Is Nothing Then
'処理
End If
Next
魔界の仮面弁士さん、ありがとうございます。
出来ました。
で、新たなレスをたてるべきかも知れませんが、
追加質問です。
①上記のようなツリーで子供で処理を行いたい場合、
うさぎ→いぬ とデータを送るのはインデックスでしか
出来ないのでしょうか?
.SelectedItem.Child.Next.Key では旨くいきませんでした。
②Do Until 開始インデックス = 最終インデックス
'処理A
stIndx = .Nodes(stIndx).Next.Index
Loop
処理A
Nextで行うと最後の1件分の処理をLoopの外へ出さなければ
エラーになってしまいます。同じ処理を書きたくないのですが
何かよい評価方法はあるでしょうか?
以上 よろしくお願いいたします。
追伸:
「VB6」 です。
すみません。よろしくお願いします。
> うさぎ→いぬ とデータを送るのは
哺乳類ノードのChildプロパティは、うさぎノードを返します。
うさぎノードのNextプロパティは、いぬノードを返します。
> インデックスでしか出来ないのでしょうか?
そんな事は無いでしょう。
Child、FirstSibling、LastSibling、Previous、Parent、Next、Root を
使ってアクセスする事もできますし、For Each での列挙もできますよね。
> .SelectedItem.Child.Next.Key では旨くいきませんでした。
この時のSelectedItemは、何を指していましたか?
(SelectdItem、または Child や Next が、Nothing になっていませんか?)
> Nextで行うと最後の1件分の処理をLoopの外へ出さなければ
> エラーになってしまいます。
いや、コードだけ書かれても。(^_^;)
何をやりたいのかが書かれていないので、改善案が出せません。
1:
魔界の仮面弁士さんの
>> .SelectedItem.Child.Next.Key では旨くいきませんでした。
>この時のSelectedItemは、何を指していましたか?
>(SelectdItem、または Child や Next が、Nothing になっていませんか?)
とかぶりますが、不都合な条件での処理を変更してないからでしょう?
もしくはループの終了条件が間違っているのでしょう。子供
の数を Children プロパティで取得しても解決できそうです。
2:
一般的なループの話で
Do
'処理A
stIndx = .Nodes(stIndx).Next.Index
Loop Until 開始インデックス = 最終インデックス
とか
Do ’無限ループ
'処理A
stIndx = .Nodes(stIndx).Next.Index
If 開始インデックス = 最終インデックス Then
Exit Do '好きなタイミングでループ脱出
End If
Loop
とか の方法があります。(TreeView 関係なし)
…でも、結局 Next の終了条件が解決してないと同じことでしょうが。
???→???(子ノードが存在しない) ’ループ開始時に不都合な処理
???→うさぎ ’ループ開始時に不都合な処理
うさぎ→いぬ
いぬ→??? ’ループ終了時に不都合な処理
ループは同じ処理を繰り返します。開始条件と終了条件、その時の
各オブジェクトの対象をよく考えて不都合な処理に対応して下さい。
お二人ともご指導ありがとうございます。
①は解決しました。
魔界の仮面弁士さんのおっしゃる通り、nothingでした。
②なのですが、
Do Until stIndx > 終了インデックス
If KeyA = KeyB Then
'処理
End If
stIndx = .Nodes(stIndx).Next.Index
Loop
とすると、ノードがなくなった時、
「オブジェクト変数または With ブロック変数が設定されていません。」の
エラーがでるので、
Do Until stIndx = 終了インデックス
If KeyA = KeyB Then
'処理
End If
stIndx = .Nodes(stIndx).Next.Index
Loop
If KeyA = KeyB Then
'処理
End If
と、しているのですが、同じ処理を2回書くことに
抵抗があります。
特攻隊長まるるうさんのお教えくださったのも
最後1件は Loopを抜けて処理できないのではないでしょうか?
ちょっと処理が長いので・・・というだけの理由なのですが。
初歩の初歩な質問で申し訳ございません。
> とすると、ノードがなくなった時、
コードだけ書くのではなく……そのコードが、何を目的として
書かれた物なのかを説明していただけるとありがたいです。
コードから意味を読み取ろうかとも思ったのですが、KeyA, KeyB の
意味がわからなかったので、断念してしまいました。(汗)
(これらの値を、ループ中で変化させているような記述もありませんし…)
とりあえず、特定のノードの子供のテキストを列挙するような場合には、
Set N = 検索対象となる親ノード
Set N = N.Child
Do Until N Is Nothing
Debug.Print N.Text
Set N = N.Next
Loop
のように書けたりしますが、参考になりますでしょうか。
たびたび申し訳ありません。
このような形での質問のやり取りが始めてなもので・・
言い訳になりませんね。
処理は keyAと同じ keyが存在しないか重複チェックを
しようとしています。
キーの値を変化させている箇所が抜けていました。
Do Until stIndx = 終了インデックス
If KeyA = KeyB Then
'重複フラグ = 'ON'
End If
stIndx = .Nodes(stIndx).Next.Index
KeyB = .Nodes(stIndx).Key
Loop
If KeyA = KeyB Then
'重複フラグ = 'ON'
End If
お願いします。
> 処理は keyAと同じ keyが存在しないか重複チェックを
> しようとしています。
それは、どのノードに対する重複チェックですか?
処理を見る限り、「すべてのノード」を検索対象にしているわけでも
なさそうですし、「特定のノードの子供だけ」を検索対象に
しているわけでも無いようですが……。
少し確認させてください。Nextプロパティは、最初のツリー構造の例でいえば、
哺乳類.Next → 鳥類
うさぎ.Next → いぬ
いぬ.Next → (Nothing)
鳥類.Next → (Nothing)
はと.Next → はと
はと.Next → インコ
インコ.Next → (Nothing)
という構成になりますが、ここまでは良いでしょうか?
また、indexによるノード指定は、画面に表示されている順番とは
必ずしも一致しませんが、それも大丈夫でしょうか?
ホント説明不足ですね。申し訳ない気持ちでいっぱいです。
見捨てずに付き合ってくださり、ありがとうございます。
【ツリービューとリストボックスがあり、リストボックスの内容を
ドロップ&ドラッグでツリービューに追加したい。】
というのが大きな流れです。
で、ここは
リストボックスで「うさぎ」をドラッグしてきて、「哺乳類」を
クリックした場合、「哺乳類」以下に「うさぎ」がいなければ
ツリービューに「うさぎ」を追加する。
ということがしたいのです。
なので、「特定のノードの子供だけ」が検索対象です。
必ず2階層で、必ずクリックできるのは親という前提です。
インデックスが一致しないのは大丈夫です。
問題ないとは思うけど
>はと.Next → はと
回答者もその場でコメントしてるので間違ってる部分はあります。
軽くツッコミしてさらっと流してくださいm(__)m
>リストボックスで「うさぎ」をドラッグしてきて
なるほど。だから重複チェック1回通りで良いのかぁ。
哺乳類
|---- うさぎ
|---- いぬ
|---- いぬ
ってなってたら重複チェックできないじゃんって思ってました。
…で、答えは既に4通りくらい今までのやり取りの中で出てますがw
>魔界の仮面弁士 2005/11/29(火) 13:50:41
のサンプルを利用させてもらえば
[VB6.0]
Dim n As Node
Dim 重複フラグ As Boolean
Dim wKeyStr As String 'これは適当な型で
wKeyStr = "うさぎKey" 'リストボックスより
Set n = 検索対象となる親ノード '(TreeView1.SelectedItem?)
Set n = n.Child
Do Until n Is Nothing
If n.Key = wKeyStr Then
重複フラグ = True
End If
Set n = n.Next
Loop
では?
> 軽くツッコミしてさらっと流してくださいm(__)m
ツッコミ多謝。
コードについても、特攻隊長まるるう殿のそれで、仕様を満たせそうですね。
>> リストボックスで「うさぎ」をドラッグしてきて、「哺乳類」を
>> クリックした場合、「哺乳類」以下に「うさぎ」がいなければ
>> ツリービューに「うさぎ」を追加する。
リストボックスにある「うさぎ」を、ツリービュー上の
「哺乳類」ノードにドロップするような状況において…
OLEDragOver イベントで、HitTest でノードを判定して、
それがルートノードでなければ、Effect = vbDropEffectNone 、
登録済みの場合も、Effect = vbDropEffectNone 、
未登録ならば Effect = vbDropEffectCopy に設定。
という状況だと認識しましたが……違うかな。(^^;
> なので、「特定のノードの子供だけ」が検索対象です。
> 必ず2階層で、必ずクリックできるのは親という前提です。
Keyプロパティを見ているのですよね?
Keyはツリービュー全体で一意な値ですから、哺乳類ノードに登録済みの
キーならば、そのキーは、鳥類ノードにも使えない事になりますよね。
そうすると、全てのノードを検索する必要があるような気もします。
>哺乳類ノードに登録済みのキーならば、
>そのキーは、鳥類ノードにも使えない事になりますよね。
かものはしパターンっすね(☆ー☆)
(…哺乳類らしいですが卵を産むので鳥類として処理したい場合もある)
哺乳類コードを"001"
鳥類コードを"002"
として子の Key は親コード始まりとする。
つまり親ノードが違えば Key は必ず違う約束。
哺乳類かものはしは"001-KAMONO"
鳥類かものはしは"002-KAMONO"
…という運用レベルで逃げる方法が1つ。
Key で判断しないで Tag で判断するってのも
よくある方法ですか。
ま、最上位ノード見つけるのに全ノード検索
で問題ないなら、重複チェックで全ノード検索
しても問題ないはずですが。っつーかサンプル
通りの処理なら絶対 Text で判断しちゃうよw。
ま、あくまでサンプルなんで実際は問題あるんで
しょうが。
お二人とも長い間のお付き合いありがとうございました。
親ノードかどうかは、初期時に画面へセットする時に
imageで分けており、ドロップした値のimageが何かで判断しております。
で、キー設定は特攻隊長まるるうさんのおっしゃっているとおり、
「哺乳類コードを"001"
鳥類コードを"002"
として子の Key は親コード始まりとする。」
でやっております。
VB初心者でツリービューを言い渡され、困っております。
きっとお二人が見たら驚くよなロジックを組んでるんだと思います(^_^;
(赤ペン先生してもらいたい・・・)
今度はもう少し明確に質問するように心がけますので「くま太郎」を
見かけたらよろしくお願いします。
ありがとうございました。
お二人とも長い間のお付き合いありがとうございました。
親ノードかどうかは、初期時に画面へセットする時に
imageで分けており、ドロップした値のimageが何かで判断しております。
で、キー設定は特攻隊長まるるうさんのおっしゃっているとおり、
「哺乳類コードを"001"
鳥類コードを"002"
として子の Key は親コード始まりとする。」
でやっております。
VB初心者でツリービューを言い渡され、困っております。
きっとお二人が見たら驚くよなロジックを組んでるんだと思います(^_^;
(赤ペン先生してもらいたい・・・)
今度はもう少し明確に質問するように心がけますので「くま太郎」を
見かけたらよろしくお願いします。
ありがとうございました。
あっ!!解決です。
ツイート | ![]() |