ACCESSのようなRDBで階層構造を管理する場合のテーブル構造の定石ってあるんでしょうか。
「部品表」のようなものをデーベース化したいのですが、イマイチしっくりきません。
例えばAという部品はBとCという部品で構成されています。BはDとEとF。
FはAとEで成り立っているというようなものです。
この階層がどれくらい続くかは、任意に決定されねばなりませんし、もちろん各部品の親子関係もどこからでもできるだけ解かり易い形で表示可能にしなければなりません。
Windowsのエクスプローラーのような表現が理想なのですが、各階層毎には表現できても、全体の繋がりがどうも・・・
こういう場合によく使われる基本的なテーブル構造というのがあれば教えて下さい。
No.3ベストアンサー
- 回答日時:
>特にコレクションのゴミ掃除の部分なんかはチンプンカンプンです。
あんまり気にしなくても良いんですが(「ゴミ掃除」に関してはそのまま書き写すだけで動作しますんで)、ちょっとだけ解説します。
えと、まず、一つの部品に付きフォームが1枚ですんで、複数の部品を同時に表示するためには、それだけの枚数のフォームを用意しなければならない。
あらかじめフォームを10個も20個も作っておくのはあまりにも非現実的ですんで、最初に汎用的なフォームを1枚作っておいて、必要に応じてその複製を画面に表示するようにしよう、と。
で、フォームの複製を作る(*1)のは良いんですが、どこかにそれを保存しなくちゃならないんですよね。
そこで、BuhinWins って名前を付けたコレクションを作成(*2)し、新しくウインドウを作るごとにそこに登録(*3)するようにしたわけです。
*1 Set frmBuhin = New Form_F部品
*2 Public BuhinWins As New Collection
*3 BuhinWins.Add frmBuhin
ここまではいいんですが、そのウインドウを×して閉じた後でも BuhinWins 内のデータは勝手に消えてくれず、無効なウインドウのデータがゴミとして残ってしまうのです。
例えば、10枚のウインドウを開いたとすると、BuhinWinsには10枚分のデータが登録されます。
そのあと4枚のウインドウを閉じた場合、画面上に表示されているウインドウは6枚でも、BuhinWinsには有効なデータ6枚分に加えて無効なデータが4枚分が登録されています。
ってことで、「ゴミ掃除」の部分で無効なデータを見つけては、これを削除するってことをやってるわけです。
>ところでVBのツリービューコントロールというのは、手に入れさえすれば、初めてでも割と簡単に使えるものなのでしょうか?
んーと、VB(A)初級者には若干キツイ部分もあるかもしれません。
TreeViewの取り扱い自体が多少複雑なのに加えて、これに関するヘルプの項目もあんまり親切じゃないんですよね~。
ヘルプの読み方のコツが身についてないと、概要を理解するだけでも苦労するかもしれないです。
ただ、他の方法で同種のインターフェースを作るのに比べたら、遥かに楽な方法であることは断言できます。
VBについての市販本はたくさん出版されているので、まずは大型の本屋を物色して、TreeViewについて詳しく書かれている本を買ってきて、それを見ながら勉強するのがいいのではないかと思います。
>ある製品を指定することで、その製品の全部品を一括でレポートにすることは可能でしょうか?
可能ですが、こっちもVBAの世話になる必要があります。
印刷用の一時テーブルを作っておいて、そこに部品一覧をぶち込みます。
アルゴリズムの概要だけ書くと、
(テーブルの構成)
一時テーブル
コード(テキスト型)
親部品ID
部品ID
:
dim RS as Recordset '一時テーブル
Dim RSParts '構造テーブル
'一時テーブルの中身をクリア(略)
:
SET RS=OpenRecordset("一時テーブル")'一時テーブルを開く
'カレーうどん自体を、RSに追加
RS.AddNew
RS![コード]="01"
RS![親部品ID]=null
RS![部品ID]="カレーうどん"
RS.Update
RS.MoveFirst
Do Until RS.EOF'レコードの末尾に達するまで繰り返す
BuhinID=RS![部品ID] '現在のレコードに書かれている部品IDを取得
Code=RS![コード]
'BuhinIDで指定された部品の構成部品を検索する
Set RSParts=OpenRecordset("SELECT * FROM 構造テーブル WHERE 部品ID=" & BuhinID)
counter=1
do until RSParts.eof
RS.AddNew
RS![コード]=code & format$(counter,"00")
RS![親部品ID]=BuhinID
RS![部品ID]=RSParts![構成部品ID]
RS.Update
RSParts.MoveNext
Counter=Counter+1
loop
RS.MoveNext'次のレコードに移動
Loop
こんな感じですね。
[コード]フィールドで並べ替えを行ったり、階層の深さを測ったりします。
うまく動いたとすると、以下のように[コード]が生成されているはずです。
コード 部品ID
01 カレーうどん
0101 うどん
0102 カレー
010101 水
010102 うどん玉
010201 カレー粉
:
01020101 ターメリック
01020102 ガラムマサラ
相変わらず長文だ~
すっばらいしいです。
おかげさまでこのコードを基本に多少アレンジすれば、私の悩みはほぼ解決しそうです。
まあ、私の場合アレンジ力が問題ですが、なんとか試行錯誤でやってみます。
ツリービューコントロールについては、アドバイス頂いた通り、気長に基礎的なところからやってみます。
というかこの一括表示と前述いただいた無限階層川下りをうまく絡ませて併用すれば、ツリービューまで取り入れなくとも、十分階層表現できそうですし現状大きな問題はないと感じています。
試行錯誤の途中で挫折しました折にはまたよろしくお願いします。
ありがとうございました。
No.2
- 回答日時:
>それから、困った点は、ドライカレーも部品になり得る(中略)部品の概念と完成品の概念はやはり区別しなければなりません。
これは、[完成品]フィールド(Yes/No型)と[部品]フィールド(Yes/No型)を作ってやればいいんじゃないでしょうか。
ドライカレーは完成品でもあり、部品でもあるってことで、両方にチェックを付けるとか。
>ところがこれが三層構造くらいですと問題はないのですが、いくつも連なってくると・・・
この辺がメンドクサイんですよねぇ。
とりあえずVBのツリービューコントロールを流用すると、手っ取り早くエクスプローラライクなインタ-フェースを作れると思います。
フォームで作る場合には、メインフォーム→サブフォーム→サブサブフォーム・・・ ってな作り方はダメですね。仰るように、階層が増えると行き詰まってしまいます。
この問題は、任意の部品及びその構成要素を表示する汎用的なフォームを作っておき、構成要素をクリックするたびに、このフォームのインスタンスを新しく作成、表示する、っていうふうにして解決します。
概略だけ書きますと、
1:フォームに[部品名]等のテキストボックスと、[構成部品]サブフォームを貼り付ける。(フォーム名は[F部品]とでもしておく)
2:同フォームに
public sub RefreshData(BuhinID as long)
'指定された部品のデータをフォームに表示する
end sub
ってな感じのコードを書く。
3:標準モジュールを作成し、宣言セクションに
Public BuhinWins As New Collection
って書く。
4:F部品の構成要素クリック時に
Private Sub コマンド1_Click()
Dim i As Long, dummy As Variant
Dim frmBuhin As Form_F部品
'コレクションのゴミ掃除
On Error Resume Next
For i = BuhinWins.Count To 1 Step -1
dummy = ""
dummy = BuhinWins(i).Name
If dummy = "" Then
BuhinWins.Remove i
End If
Next i
'フォームのインスタンスを作成して、コレクションに追加
Set frmBuhin = New Form_F部品
frmBuhin.RefreshData Me.構成部品ID
frmBuhin.Visible = True
BuhinWins.Add frmBuhin
End Sub
ってな感じのコードを書く。
以上。
このようにすると、構成部品をクリックするたびに、その部品を表示するウインドウが新しく開きます。
新しく開いたウインドウに更に構成部品が含まれていたとしても、それをクリックすればまた別のウインドウが開きます。
この回答への補足
早速のご回答ありがとうございます。
残念ながら、私はコードを自在に駆使できるレベルにないので、このコードをそっくりそのままコピーして使うことはできても、応用がききません。
おおよその組立は理解できるのですが、特にコレクションのゴミ掃除の部分なんかはチンプンカンプンです。
でも、VBAを駆使すれば無限階層表示も可能ということがわかっただけでも大きな収穫です。
挫折中だったコードのお勉強を再開せねばと痛感しました。
ところでVBのツリービューコントロールというのは、手に入れさえすれば、初めてでも割と簡単に使えるものなのでしょうか?
それと甘えついでにもう一つ。
ある製品を指定することで、その製品の全部品を一括でレポートにすることは可能でしょうか?
レポートの表記としては、例えばカレーうどんを指定すると
階層 親部品ID 部品ID 重量
1 カレーうどん うどん 200
1 カレーうどん カレー 100
2 うどん 水 100
2 うどん うどん玉 100
2 カレー カレー粉 50
2 カレー 肉 20
2 カレー 水 30
3 カレー粉 ターメリック 40
3 カレー粉 ガラムマサラ 10
というような一括表形式が理想です。これができれば、部品の所用量計算が容易になりますし、ある部品から一直線に製品までさかのぼることもできると思うのですが。
No.1
- 回答日時:
部品テーブル
部品ID
部品名
:
構造テーブル
部品ID
構成部品ID
数量
:
のようなテーブルを作ればいいのでは?
例えば、ドライカレーのレシピなら
部品テーブル
部品ID 部品名 単位
1 ドライカレー 皿
2 ご飯 合
3 カレー粉 g
4 植物油 cc
5 米 cc
6 水 cc
7 コリアンダー g
8 ターメリック g
9 チリパウダー g
構造テーブル
部品ID 構成部品ID 数量
1 2 1
1 3 30
1 4 15
2 5 180
2 6 270
3 7 0.2
3 8 0.3
3 9 0.5
として表現可能です。
ドライカレー1皿は{ごはん1合, カレー粉30g, 植物油15g}で出来ていて、ごはん1合は{米180cc, 水270cc}、カレー粉1gは{コリアンダー0.2g, ターメリック0.3g, チリパウダー0.5g}で出来ていることが見て取れると思います。
ちなみに分量は滅茶苦茶です(^^;
部品にどれだけ階層が増えようと上記の二つのテーブルだけで表現できますし、任意の部品の構成部品を調べることも容易です。
この回答への補足
やっぱりこれっきゃないですよね。
実は、私も基本構造はこの考え方でやってはいるのですが、どうもですね。
何がどう悪いのかはっきり説明のつかない点が、一番問題ですね。
考えが整理できてなくて申し訳ないです。
えーとまず、この構造ですとおっしゃる通り何層構造になろうが、任意の部品の親子構成は簡単に表現できます。クエリー一つ作るだけです。
ところがこれが三層構造くらいですと問題はないのですが、いくつも連なってくると親子関係のそのまた親子関係そのまた親子関係というように系列で表現せなばならず、縦横無尽に系列をさかのぼる、下る、あるいは一度に頭から尻尾まで系列を表示するというような必要が出てきました。
これを表現するために、部品一覧フォームからある部品を選択すると、その子部品構成を表示するポップアップを作り、このポップアップのある部品を選択するとさらに孫部品を表示するポップアップが開くというような仕掛けを作って四苦八苦しているのですが、いくら作っても正直きりがありません。
さらに系列を一度に表示させようとすると、サブフォームやサブリポートを無理矢理駆使しまっくって余計混乱させている有り様です。
それから、困った点は、ドライカレーも部品になり得ることで、例えば「ハンバーグドライカレーうどん」になってしまうのです・・
にもかかわらず、部品の概念と完成品の概念はやはり区別しなければなりません。
というような問題が山積みしてまして、頭はパニック。うまく説明できなくてごめんなさい。
テーブル構造は問題ないとすると、やはり私のユーザーインターフェイス作成能力の部分が問題ですね。
このテーブル構造で系列を表現するのにいい仕掛けがありましたらぜひご教授下さい。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
10代と話して驚いたこと
先日10代の知り合いと話した際、フロッピーディスクの実物を見たことがない、と言われて驚きました。今後もこういうことが増えてくるのかと思うと不思議な気持ちです。
-
大人になっても苦手な食べ物、ありますか?
大人になっても、我慢してもどうしても食べれないほど苦手なものってありますよね。 あなたにとっての今でもどうしても苦手なものはなんですか?
-
これ何て呼びますか Part2
あなたのお住いの地域で、これ、何て呼びますか?
-
牛、豚、鶏、どれか一つ食べられなくなるとしたら?
牛肉、豚肉、鶏肉のうち、どれか一種類をこの先一生食べられなくなるとしたらどれを我慢しますか?
-
ギリギリ行けるお一人様のライン
おひとり様需要が増えているというニュースも耳にしますが、 あなたが「ギリギリ一人でも行ける!」という場所や行為を教えてください
-
ACCESS ツリービューの作り方
その他(データベース)
-
Access サブフォームでの選択行の取得
その他(データベース)
-
ExcelのVBAでデータをツリー構造にしたい
Excel(エクセル)
-
-
4
Access 同じデータをたくさんのレコード(同一列)に一度に入力するには
Access(アクセス)
-
5
ACCESSで条件によってフォーム上のフィールドの色を変更
Access(アクセス)
-
6
有無、要否、賛否、是非、可否、当否…これらの言葉について
その他(教育・科学・学問)
-
7
新規レコード行を非表示にしたい
Access(アクセス)
-
8
選択したチェックボックスのみチェックを入れたいのですが
その他(データベース)
-
9
部品表
Visual Basic(VBA)
-
10
VBA エンターキーでイベントに入りたい。
PowerPoint(パワーポイント)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Accessでテーブル名やクエリ名...
-
2つのテーブルAとBをマージ...
-
デザインビューで、連結式 を...
-
ODBCで接続するとDBに変更/追加...
-
テキストファイルの内容を、フ...
-
SQL: SELECT UNIONすると文字数...
-
ファイルメーカー8.5
-
ACCESSに同時アクセス(編集)を...
-
2つのテーブルを比較して一致し...
-
3つの表を1つに縦に連結する
-
Accessでテーブルをデータシー...
-
INSERT時にデータ登録とmaxの発...
-
accessのマクロでODBC接続で外...
-
Accessの追加クエリで既存のテ...
-
ACCESS97で作成したものをACCES...
-
テーブル作成クエリで主キーを設定
-
Accessレコードの追加や変更が...
-
ACCESS2000での円グラフ作成
-
リンクテーブルを CopyObject ...
-
Accessで、複数のテーブルで随...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Accessでテーブル名やクエリ名...
-
Accessレコードの追加や変更が...
-
Accessクエリでの、LIKE条件
-
3つの表を1つに縦に連結する
-
Accessでvlookupみたいなことは...
-
ACCESSに同時アクセス(編集)を...
-
Accessの追加クエリで既存のテ...
-
SQLで条件指定結合をしたいがNU...
-
2つのテーブルを比較して一致し...
-
Accessでテーブルからテーブル...
-
デザインビューで、連結式 を...
-
ツリー構造をRDBで表現するには?
-
ACCESSで指定されたテーブルか...
-
テーブル作成クエリで主キーを設定
-
リンクテーブルを CopyObject ...
-
access テーブル内のレコード...
-
Accessでテーブルにパスワード...
-
ACCESS クエリ(カウント0の...
-
SQLで日付を条件に削除したい
-
時間の足し算
おすすめ情報