プログラム中のツリー形式のデータの保存方法について

このQ&Aのポイント
  • ツリー形式のデータの保存方法について知りたい。データの保存はDataSetクラスではなく、別の方法があるのか。
  • TreeViewコントロールで表示するようなツリー形式のデータの保存方法について教えてください。
  • 3階層以上のツリー形式のデータを効果的に保存する方法を教えてください。深いツリー形式のデータにも対応した保存方法を知りたい。
回答を見る
  • ベストアンサー

プログラム中のツリー形式のデータの保存方法について

こんにちは。 趣味で、VC#2010を使ってウィンドウズプログラミングを行なっております。 カテゴリは、VBが最もVC#に近そうだったので、 VBとさせていただきました。 今回は、データの保存方法について質問させてください。 .NETでは、2次元の表に表せるようなデータであれば、 DataSetクラスで保存するのが便利だと思いますが、 ツリーになっているようなデータはどのように保存するのが定石でしょうか? ツリーになっているデータというのは、 TreeViewコントロールで表示するようなデータで、 このサイトのカテゴリもそれの一つだと思います。 ライフ ├恋愛・人生相談 |├恋愛相談 |├夫婦・家族 |… … このような3階層のものに限らず、より深いツリーのデータの保存形式の定石もあればご指導頂けると幸いです。 以上です。 よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.4

>「保存」の定義がプログラムの中の保存か外の保存か曖昧でした。 ああ、なるほど。すみません。質問サイトでは色々な表現を される方がいますので。 「ファイルに保存」という表現だったら間違わなかったと思います。 > 今回は、プログラム外での保存の質問のつもりだったので、 > Xmlの保存を行うメソッドがあるDataSetを出しました。 オブジェクトの内容をファイルに保存するような情報も 色々あります。DataSet 以外でもそれなりの手段が用意 されており、DataSet が特別便利だという意識はありません でした。 # 既存のコントロールの保存を調べた事は無かったですが。。。 ・DOBON.NET Tips ファイル、フォルダ編メニュー http://dobon.net/vb/dotnet/file/index.html > ・オブジェクトの内容をXMLファイルに保存、復元する > ・ArrayListオブジェクトの内容をXMLファイルに保存する > ・オブジェクトの内容をバイナリファイルに保存する

aniline
質問者

お礼

はい、表現は詳しく書くよう、 より一層気をつけたいと思います^^ > http://dobon.net/vb/dotnet/file/index.html > > ・オブジェクトの内容をXMLファイルに保存、復元する > > ・ArrayListオブジェクトの内容をXMLファイルに保存する > > ・オブジェクトの内容をバイナリファイルに保存する ありがとうございます! このサイト便利ですね。 挙げていただいた方法が、理想にかなり近いものなので、 これも試してみようと思います! 予期していたもの以上の回答が得られましたし、 自分なりに指針が固まってきたので、 以上でこの質問については締め切ろうと思います。 回答してしただいた方に、 重ねてお礼申し上げます。 ありがとうございました!

その他の回答 (3)

  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.3

非表示で TreeView コントロールをそのまま使うとか? Node の管理はそのまま TreeView.Nodes プロパティ のコレクション。データは TreeViewItem クラスで。 多少の機能追加なら継承コントロールでも作れば 良いでしょう。 > .NETでは、2次元の表に表せるようなデータであれば、 > DataSetクラスで保存するのが便利だと思いますが、 DataSet は DataTable を複数格納する入れ物だと思い ますが? 検索や、データを表形式で管理なら、DataTable の事だと 思います。確かに便利ですし、使えばいいと思います。 親の Node 情報をフィールドに持つだけでとりあえずは 木にできそうかな? 後々の検索処理などで必要なら、階層などの情報も付加 すればいいと思います。 定石も何も、そんな大した内容では無いと思います。 データを並べて、そこから木を作れるようにするだけ ですので、特別なロジックが必要と捉えていません でした。情報も必要最小限なのは1つだけでしょうし。

aniline
質問者

お礼

回答ありがとうございます^^ 今回は、プログラム外での保存の質問のつもりだったので、 Xmlの保存を行うメソッドがあるDataSetを出しました。 「保存」の定義がプログラムの中の保存か外の保存か曖昧でした。 伝わっていなかったら僕の書き方が悪いです。すいません。 今まで、複数のDataTableを使って、 DataRelationを作り管理していたのですが、 ファイルから呼び出すたびに関係を作り直したりと 色々とめんどうだったので今回質問するに至りました。 ただ、今までは先祖全ての名前をフィールドに持っていたので、 それがめんどうな原因だったのかもしれません^^; 親のIDのみを持てば確かにもっともっとスマートに書けますね。 独自クラスを書くときは参考にDataTableでも作ってみようと思います^^ ありがとうございました。

  • 0909union
  • ベストアンサー率39% (325/818)
回答No.2

ツリーデーターは、基本的に全ての階層の羅列に過ぎません。 これをテキストで持つか、オブジェクトで持つかの違いです。 問題になるのは、用途で、例題にしている3階層程度で、しかも固定されているなら、はたして、No1さんの言うとおり、DOMや他のオブジェクト構造を使う必要があるかです。 動的に、この階層の下に、別ツリーのこの部分を切り取って、貼り付ける。なんて操作するのであれば、DOMなどのオブジェクトが最も会うのでしょう。 いい例題があります。会社組織などのユーザー管理です。これをRDBで構築してしまうと(通常そうだが)、かなり大規模なスキーマになります。 しかし、LDAPのように、DOM階層で扱うと、かなりシンプルに構築できます。 結局、どのように検索し、検索できるアイテムが自由自在に存在しているかです。 質問者が提示したツリーなら、ほぼ固定ですよね。単にテキストで持つほうが、シンプルに作れませんか。 しかもDOMなら、別言語やシステムでも使え移植性が高い(もちろんXML DOM)。

aniline
質問者

お礼

お礼が遅くなりました。 すいません。 RDBやLDAPという言葉を始めて知ったので、 正確に理解できているか不安ですが、 今回の質問の例のような3階層で固定されているようなデータであれば、 データベースを用いるよりもXMLで管理した方が良いということでしょうか。 > 単にテキストで持つほうが、 というのは、データベースと比較したときのXMLということですよね。 昔テキストファイルで独自に区切り文字を使ってデータを保存していたので、「テキスト」がどこまで意味するのか曖昧で…^^; とりあえず、頂いた回答から、 System.Xml.XmlDocumentクラスを使ってXMLで管理するよう 書き換えてみようと思います^^ 今回も大変勉強になりました。 またよろしくお願い致します^^ ありがとうございました! これから数日置いて、 回答は締め切らせていただきます。 何かお礼内にて勘違いや理解不足などありましたら ご指摘頂けると幸いです。

noname#212058
noname#212058
回答No.1

ツリー構造にはDataSet ほど 定石(というかMicrosoft お勧め)という方法は無いかと。 ツリー構造でよくあるサンプルは以下のようなものでしょうか ・System.Windows.Forms.TreeNode クラスを使う ・System.Xml.XmlDocument クラス シリーズを使う ・独自にノードクラスを定義する どれも利用シーンによって一長一短で、『どれがベスト!』 とは紹介しにくいです。ちなみに私は、『UI とデータは分離したい』『XmlDocument は単純にツリー構造だけ扱うには高機能すぎてわかりにくい』 という理由で、大抵の場合独自にクラスを定義します。

aniline
質問者

お礼

お礼が遅くなりました。 すいません。 > ツリー構造にはDataSet ほど 定石(というかMicrosoft お勧め)という方法は無いかと。 そうなんですね。 結構使う形だと思うので、ちょっと意外です。 いくつかの提示ありがとうございます。 提示いただいた中で System.Xml.XmlDocumentというのは始めて知りました^^; これについて調べてみましたが、 求めていたものに一番近そうです。 とりあえず勉強もかねて System.Xml.XmlDocumentを調べながら触ってみようと思います。 高機能でわかりにくい、と思ったら 独自にノードクラスを定義する方法に移ろうと思います^^ ありがとうございました。

関連するQ&A

  • 3次元データを3D表示

    3Dプログラミング初心者です。 3次元データ(X,Y,Z)が多数あり、これらの点を3次元散布図のように表示させたいと考えてます。 3次元のデータは不規則ではなく、実物から3次元計測をして取得したデータです。 また、3次元の画像はマウスで回転させて見る方向を変えれるようにしたいです。 画像表示プログラムを、VC++もしくはVB.NETで作成したいのですが、 作成するにあたり、どのように作っていけばいいのかわかりません。 大まかな作成の流れ、もしくは参考になるサイトなどありましたら、 教えてください。 尚、プログラミングに必要な数学の知識は勉強しました。

  • TreeView と DOMツリー

    C# WPF でプログラミングをしています。 TreeView に XML の階層構造を表示させて、ある項目を選択し、ボタンをクリックするとその項目の子ノードが追加されるようにするプログラムを作っています。 選択した項目(TreeView.SelectedItem(Object型)) を、DOMツリーの要素ノード (XmlElement型) にキャストし、それに新しく作った要素ノード(XmlElement型)をつなげるといったようにしているのですが、その際「挿入するノードは、異なるドキュメント コンテキストのものです。」のエラーが発生してしまいます。 XmlElement tvi = treeView.SelectedItem as XmlElement; XmlElement item = doc.CreateElement("item"); tvi.PrependChild(item); // エラー発生箇所 ※ doc は XmlDocument のインスタンスです。 解決策を教えてください。よろしくお願いします。

    • ベストアンサー
    • XML
  • VB2005 ツリービューに子ノードを追加

    VB2005 ExpressEditionにて開発しています。 フォームロード時にデータセットからツリービューにデータをセット しようとしています。 ルートノードには  Dim Node As TreeNode  Node = TreeView2.SelectedNode  TreeView2.Nodes.Add("追加したい名前") で追加できます。 子ノードを追加する時はどうしたらいいのでしょうか。 ご存知の方がいらっしゃいましたら教えて下さい。 よろしくお願いします。

  • 3次元rawデータの保存方法を教えてください

    プログラミング初心者の大学生です。 現在C++ Builder XEでプログラミングを行っています。 さまさまな画像処理を処理を施した256×256×256の3次元MRIのrawデータをそのままrawデータとして保存する方法が全く分からず、困っています。 画像はImage J等で開く際に、unsigned shortで開けるようにしろと言われました。 プログラミングをほとんど教わっていないのに、先生からいきなりやれと言われて非常に困っています。 よろしくお願いします。

  • TreeViewの内容を出力する方法

    VB6.0でコントロールTreeViewを使って、 親子関係を持つデータをツリー表示する フォームを作っています。 TreeViewに表示された内容をビットマップに出力 したいのですが、いい方法が見つかりません。 PrintFormメソッドでフォーム全体をPDF形式で出力 させることは出来たのですが、ツリー情報が多岐に 渡る場合、情報が欠けてしまいます。 出来ればフォーム全体ではなく、ツリーの内容を全て出力させたいです。 ビットマップが無理ならば他の方法でも構わないので ご存知の方がいましたら是非教えて下さい。

  • VB2010 DataSet Dataの初期化

    VB2010のDataGridViewを使ってアドレス帳を作ってます。 登録データを初期化したいのですが、次のようにコードを書いても、初期化されません。エラーも出ません。DataSetを初期化して、保存する方法をとろうとしています。 DataSet.登録.clear() 登録TableAdapter.Update(DataSet.登録) お手上げの状況ですので、対処方法をご存知の方はご教授をお願いします。

  • TreeViewについて

    いつも大変お世話になっております。福島です。 TreeViewのことで教えて頂きたいのですが・・・ 社員登録で3階層(部・課・社員)のツリー構造をなす TreeViewを作成しましたが、1社員の情報を変更したときに 状態を反映するためにTreeView全体を消去してから書き直しています。 (例えば)課や部を移動したとき しかし表示する数が多くなってきた為に再構築に非常に時間が かかってしまい実用的でなくなってしまいました。 あるノードの下だけ変更(削除)する方法はありますか? 今は、「treeView.Nodes.Clear」を使用して全体を削除して 再度ツリーを作成しています。 aNode(部) bNode(課) cNode(社員) のようになっています。 宜しくお願い申し上げます。 Windows2000SP2 + VB6.0SP4

  • DBから取得した値を配列へ代入する

    VB.NETの2003 OdbcDataAdapterのコマンドとDataSetで処理を行っています。 コードを入力して目的のデータを取得するところまでは出来ていますが その結果取得したものを配列へ保存したいのですがどうすればいいのかが わかりません。

  • エクスプローラのツリーの中身

    カテゴリーの選択が間違っているかもしれませんが、ご容赦下さい。先ほどこの操作をしていて分からなくなったのでお聞きします。たとえばOutlook Expressの保存場所である C:\Documents and Settings\tateyan****\Local Settings\Application Data\Identities\{E9AF79BA-7D4C-4D42-8443-A53C79466834}\Microsoft\Outlook Express を開こうとしたのですが、「スタート」から右クリックでエクスプローラのツリーの中に\tateyan****以下の\Local Settingsがないのですが、どうしてでしょうか。 「ファイル名を指定して実行」から上記を入力して実行するとツリーの中にちゃんとあります。 何故でしょうか。宜しくお願いいたします。

  • TreeViewに重複する値をセット

    VB2005Expressで開発しています。 TreeViewにデータテーブルの値をセットして表示しています。 セットする値に重複する値がある場合、ツリーの構造が崩れてしまいます。左図のようにしたいのですが、右図のようになってしまいます。 あ あ |-い |-い | | | | | -う | -う お | -え |-い お | | | -え ツリーの値に非表示のキーを持たせる等、何か対応法をご存知の方が いらっしゃいましたら教えて下さい。下記がPGMです。 '処理内容:TreeViewにデータテーブルの値をセット Private Function fncTreeViewSet() As Boolean Dim dTbl As DataTable Dim Node As TreeNode Dim intMenuNo As Integer Dim strMenuName1 As String Dim strMenuName2 As String Dim strMenuName3 As String Dim strMenuName4 As String Dim strMenuName5 As String Dim i As Integer Node = TreeView1.SelectedNode dTbl = dsDataSet.Tables("Mメニュー") For i = 0 To dTbl.Rows.Count() - 1 intMenuNo = 0 strMenuName1 = "" strMenuName2 = "" strMenuName3 = "" strMenuName4 = "" strMenuName5 = "" strMenuName1 = Trim$(dTbl.Rows(i)("階層1")) intMenuNo = dTbl.Rows(i)("工程番号") strMenuName2 = Trim$(dTbl.Rows(i)("階層2").ToString) strMenuName3 = Trim$(dTbl.Rows(i)("階層3").ToString) strMenuName4 = Trim$(dTbl.Rows(i)("階層4").ToString) strMenuName5 = Trim$(dTbl.Rows(i)("階層5").ToString) If strMenuName1 = "" Then Else If strMenuName2 = "" Then TreeView1.Nodes.Add(strMenuName1) '階層1をセット Else If strMenuName3 = "" Then fncSerchNode(strMenuName1) TreeView1.SelectedNode.Nodes.Add(strMenuName2) '階層2をセット Else If strMenuName4 = "" Then fncSerchNode(strMenuName2) TreeView1.SelectedNode.Nodes.Add(strMenuName3) '階層3をセット Else If strMenuName5 = "" Then fncSerchNode(strMenuName3) TreeView1.SelectedNode.Nodes.Add(strMenuName4) '階層4をセット Else fncSerchNode(strMenuName4) TreeView1.SelectedNode.Nodes.Add(strMenuName5) End If End If End If End If End If Next TreeView1.SelectedNode = Nothing End Function '処理内容:指定ノード選択 Private Function fncSerchNode(ByVal strMenuName As String) As Boolean Dim Node As TreeNode For Each Node In fncGetAllNodes(TreeView1.Nodes) If Node.Text = strMenuName Then TreeView1.SelectedNode = Node Exit For End If Next End Function '処理内容:子ノードも含んだすべてのノードを取得 Private Function fncGetAllNodes(ByVal Nodes As TreeNodeCollection) As ArrayList Dim Ar As New ArrayList Dim Node As TreeNode For Each Node In Nodes Ar.Add(Node) If Node.GetNodeCount(False) > 0 Then Ar.AddRange(fncGetAllNodes(Node.Nodes)) End If Next Return Ar End Function