「Web出版サイト」ベータ公開

Q&A集[?]

当サイトでのご質問の受付は終了しました

すべてのコンテンツを読み込み専用としたため、回答欄からも投稿できません

Apache OpenOffice/LibreOfficeのご質問はそれぞれのフォーラムへご投稿ください

質問コーナー

サイト内検索

分類メニュー

関連サイト


本日:1
昨日:0
総数:3016
現在:4


複数のテーブルからちょっとづつレコードを選択して、別のテーブルへ転記したい

ページOpenOffice.org FAQの登録ページ
投稿者gorodoku
分類
edit/refer
優先順位
edit/refer
状態
edit/refer
カテゴリー
edit/refer
投稿日2009-05-19 12:19:54 (火)
OSVISTA
依存するページfaq/4/1671
バージョン
edit/refer

メッセージ

回答ページでは行末に「~」を付加する必要はありません

faq/4/1671より、引き続き材料集計表の作成を行っています。
baseのフォームを用いてできないか検討中ですが、出だしから躓いてます。素人ですみません<(_ _)>

重量計算の基礎となる値を鋼材の材質・種別ごとに複数のテーブル(仮に基礎テーブル群と呼ぶことにします)に蓄積してあります。
新しい製品を作るのに必要な鋼材を基礎テーブル群から選択し、別のテーブル(仮に材料表テーブルと呼ぶことにします)へ転記したいのです。

踏みたい手順としては以下のような感じです。

1.まずリストボックスから材質・種別を選択する(=基礎テーブル群のうちの一つを選択)
2.選択した基礎テーブルをもとに、さらにその鋼材のサイズを選択し、候補を1つに絞り込む
3.これを材料表テーブルに転記する

といった感じです。
基礎テーブル群のフィールド構成はすべて同じです。
材料表テーブルのフィールドは、基礎テーブルのフィールドと同じものに加え、それぞれの部材に個別の名称を与えるフィールドや、部材の長さを入力するフィールド、基礎テーブルから引用したデータに部材の長さをかけた計算結果フィールドなどがあります。

データベースファイルの構成は以下のようなものです。

[mat-sample.odb]-------SSH形鋼
                  |   |-------[primaly key]フィールド
                  |   |-------[calculation type]フィールド
                  |   |-------[shape]フィールド
                  |   |-------[material standard]フィールド
                  |   |-------[weight for each unit]フィールド
                  |   |-------[outer length]フィールド
                  |   |-------[inner length]フィールド
                  |           (以降、基礎テーブル群は同じフィールド構成)
                  |---SSI形鋼
                  |---SS角鋼
                  |---SS丸鋼
                  |---SS溝形鋼
                  |---SS等辺山形鋼
                  |---SS平鋼
                  |---SS六角鋼
                  |---SUSH形鋼
                  |---SUS角鋼
                  |---SUS丸鋼
                  |---SUS溝形鋼
                  |---SUS等辺山形鋼
                  |---SUS平鋼
                  |---SUS六角鋼
                  |   (ここまでが基礎テーブル群)
                  |---材料表
                      |-------[primaly key]フィールド
                      |-------[calculation type]フィールド
                      |-------[shape]フィールド
                      |-------[material standard]フィールド
                      |-------[weight for each unit]フィールド
                      |-------[outer length]フィールド
                      |-------[inner length]フィールド
                      |       (ここまで、基礎テーブル群と同じ)
                      |-------[name]フィールド
                      |-------[length]フィールド
                      |-------[require]フィールド
                      |-------[weight for piece]フィールド
                      |-------[weight]フィールド
                      |-------[outer painting area]フィールド
                      |-------[inner painting area]フィールド
                              (ここまで、材料テーブル独自のフィールド)



(そもそも、基礎テーブル群のように細分して複数のテーブルで管理することがマズいから、フィールド増やしてひとつのテーブルで管理すべしという指摘もあるかもしれませんが、一度に基礎データを用意できないので仕事の暇を見つつ、ちまちまテーブルごとに整理・追加していってます。なので今後基礎データ自体も増えていきます)

大変雑駁な質問の仕方で申し訳ないですが、こういったことがどうすれば実現可能か、ご助言お願いいたします


とりあえず

gorodoku (2009-05-19 12:52:11 (火))

今のところ入力してあるデータのサンプルです。

要件確認

M.Kamataki (2009-05-19 21:25:37 (火))

>1.まずリストボックスから材質・種別を選択する(=基礎テーブル群のうちの一つを選択)

「材質・種別を選択する」というのは、「SSH形鋼」とか「SSI形鋼」を選べばよいのでしょうか。単純に考えれば、「SSH形鋼」から「SUS六角鋼」まで15までのボタンを選ぶと、それぞれのテーブルをグリッド表示(テーブル表示)させたフォームを呼び出すようなメニューフォームならできそうです。ただし、サブのフォームが15必要です。

(これが複数のテーブルではなくひとつのテーブルなら、ひとつのフォームにまとめることは可能でしょう。)

>2.選択した基礎テーブルをもとに、さらにその鋼材のサイズを選択し、候補を1つに絞り込む

これは、各テーブルの中のひとつのレコードを選ぶという作業ですか。

>3.これを材料表テーブルに転記する

[name]フィールド以下ですが、基礎テーブルから転記するフィールド、新たに入力が必要なフィールド、計算で求められるフィールドはどれでしょう。計算で求められるフィールドは、基礎テーブルのどのフィールドをどのように計算すると求められますか。

シミュレーションしてください

M.Kamataki (2009-05-19 21:28:32 (火))

最終的な材料表を求める過程を仮定のデータでシミュレーションしていただくと、流れがつかめると思います。ご検討ください。

無題

gorodoku (2009-05-19 23:47:35 (火))

おおむねKamatakiさんのおっしゃるイメージで良いと思います。仮にプロセスを示すと、

・基礎テーブル群の中から【SS溝形鋼】を選ぶ
・【SS溝形鋼】テーブルの中の2番目のレコード(shapeフィールドが[100×50×5×7.5のレコード)を選ぶ
・このレコードの各フィールドを材料表テーブルの同じフィールドに転記
・新たな入力が必要なフィールドはname,length,requireフィールド
・その他のフィールドは計算をして求める。

       weight for piece     =    weight for each unit × length
       weight               =    weight for piece × require
       outer painting area  =    outer length × length
       inner painting area  =    inner length × length


なるほど、基礎データを細分すると、やはり扱いが難しくなるんですね。
15個のテーブルで確定だとボタンを15個用意できますが、今後まだまだ基礎テーブルは増える予定ですので、、、

基礎データ群をすべてユニオンクエリで結合(基礎テーブルが増えたらその分ユニオン文を増やせば良い?)して、ここからデータを参照する、ということもできるんでしょうか。可能であればフォームのほうはあまり複雑なならないで済むでしょうか。

無題

gorodoku (2009-05-20 00:01:28 (水))

実際今までエクセル等で作っていた材料表を見ていただくとイメージがつかみやすいかもしれませんね。
参考までにPDF化したファイルを提示しておきます。

ユニオンクエリでフォームの可能

M.Kamataki (2009-05-20 10:36:21 (水))

ユニオンクエリを基にしたフォームの場合は、それぞれの基礎テーブルへのデータ登録はできませんが、確かにフォームはひとつで済むかもしれません。その方向でアイデアを出します。

サンプルのPDF提供ありがとうございます。なるほど、複数レコード必要ですか。当初、材料表テーブルは一時的な使い方かと考えていましたが、レコードが蓄積されるテーブルのようです。材料表を印刷する場合も考えると、レコード範囲を指定するキーとなるフィールドも必要です。

無題

gorodoku (2009-05-20 11:07:11 (水))

ユニオンクエリはあくまで材料表テーブルからの参照用に用意する、ということでよいと思います。

基礎テーブル群を追加するときは直接テーブルを作成、もしくは表計算ソフトで作ったテーブルをインポートするなどで対応できますし、この追加分のユニオン文をクエリーのほうにも追加するということで良いのではないかとと思います。
いったんデータを蓄積すれば、基本的に後から編集することはほとんどないと思いますので、、、

材料表テーブルのほうは、、、そうですね、確かにどのレコードがどういったグループに属するかを識別するフィールド(たとえば製品ごとの識別とか、さらにその製品がどの工事案件のものなのかを識別する)が必要な気がしてきました。

とはいえ、話が広がるとちょっと収拾がつかなくなりご迷惑をお掛けすると思うので、必要になったらその時点で別の質問をさせていただきたいと思います。

まずは(基本的なことなのかもしれませんが)
・あるテーブルやクエリーから、これと共通のフィールドを持つ別のテーブルへデータを転記
・転記先のテーブルが持つ固有のフィールドにデータを追加・計算させレコードを追加する
というところにしぼって(これでも絞りきれてませんが(汗))お願たいと思います。

ユニオンクエリーでは制約がありました

M.Kamataki (2009-05-20 23:44:05 (水))

とっかかりとして、ユニオンクエリーを基にした「1.まずリストボックスから材質・種別を選択する(=基礎テーブル群のうちの一つを選択)」フォームの作成を検討してみましたが、結論を先に書くとユニオンクエリーをフォームの対象にはできませんでした。まず、サンプルを添付します。

filefaq4_1680_1.odb

上記1.のフォームですが、とりあえずBaseのフォームで実現可能なものを作成してみました。サンプルの「材料テーブル選択フォーム」はサブフォームというもので、メインフォームの内容が変われば、リンクされたフィールドを持つサブフォームの内容が絞り込まれるというものです。メインフォームに新たにテーブル一覧というテーブルを作成しています。その内容を「SSH形鋼」、「SSI形鋼」と順に選んでいけば、そのテーブルの内容がサブフォームに表示されます。リストボックスは使っていませんが、ほぼ目的のフォームに近いと思います。

当初、サブフォームの対象を「全材料テーブル結合クエリー」としたところ、うまく絞り込まれませんでした。そこで、「全材料テーブル結合クエリー」をマウスの右ボタンで表示されるメニューで「ビューとして作成」を選んで作成した「全材料テーブル結合ビュー」にサブフォームの対象を切り替えました。それがサンプルの「材料テーブル選択フォーム」です。

データベースの場合、テーブルにはインデックスが付加されます。ビューにもインデックスが付加されるのか、今ひとつ自信がありませんが、テーブルとして見せかけることで抽出が可能になったことは確かです。また、インデックスは抽出・検索のパフォーマンスにも影響するので、これから抽出・検索のフォームを作成することを考えると、フォームの基にする場合、やはりテーブルであるほうが有利だと思った次第です。

サンプルのようなフォーム(もちろんデータ追加可能なものを作成しないといけませんが)なら、今までのようにテーブルごとにデータを追加するイメージと変わらないのではないでしょうか。

このフォームをステップに、リストボックスで絞り込む方法は、faq/4/976「フォームベースの検索・絞込み」、テーブルへの書き込みは、faq/4/1328「テーブルへの書込み/読出しマクロ」を参考にしてください。いずれもマクロの実現方法を紹介しています。なお、マクロでクエリーを発行するメソッドとして、executeUpdateもあります。

なかなか難しいです。

gorodoku (2009-05-21 14:40:21 (木))

サンプル提供ありがとうございます。朝から本業そっちのけで悪戦苦闘してます(^^;

作っていただいたサンプルですが、メインフォームのテキストボックスの内容をenterまたはshift+enterで切り替えると、これに伴いサブフォーム上の候補が変わる動作をします、、、でよいですよね?

サンプルを元にを自分なりに変更を加えたものを作ってみました。が、
メインフォームのテキストボックス部分をコンボボックスに変えてみたいんですが、うまくいきません。フォームナビゲーター上で置換→コンボボックスとしてもコンボボックスに変わりません、、、何かやり方を間違えていますか?

とりあえず途中経過を添付します。材料テーブル選択フォームrev1が自分で作ってみたものです。


サブフォームはテーブルコントロールからテキストボックスに変えてあります。
(また、サブフォームの下にさらに材料表のサブフォームを作ってますが今のところ関係ないのでとりあえず無視してください)

同様にサブフォーム上のshapeをコンボボックスに置換え、faq/4/976のようなマクロを割り当てると候補を絞り込めると思うのですが、うまくいきません。
どうもまだ自分はフォームの概念や編集の仕方をわかってないようです(^^;

連結コントロールと非連結コントロール

M.Kamataki (2009-05-21 18:29:14 (木))

テキストボックス、コンボボックスなどのコントロールには連結コントロールと非連結コントロールの2種類あります。

連結コントロールとは、DBのテーブルと連携しています。つまりテーブルへデータを入力する際に利用します。この連結コントロールのままだと、テーブルにデータを入力しに行くので、抽出・検索には利用できません。

サンプルのメインフォームのテキストボックスやサブフォーム上のshapeフィールドは連結コントロールですから、そのままの変更では動きません。

faq/4/976のもっともシンプルなマクロの例 business_sample3.odb のコンボボックスコントロールは非連結コントロールです。コントロールのプロパティをご覧になるとわかりますが、データフィールド欄は空欄です。連結コントロールなら、ここは入力先のテーブルのフィールドが設定してありますが、かわりにSQLが設定されているので非連結コントロールなのです。このSQLは、新規にコンボボックスを設置すると起動する「コンボボックスウィザード」で設定できます。

今のところ、2つのフィールドを対象に絞込みをされるわけですね。このあたりは参考ページをアレンジしてください。コンボボックスを2つ置いて、ボタンでフィルターを実行するとか。。。余計に混乱されるかもしれませんが、faq/4/1280「フォームの検索結果をレポート化し印刷したい」のサンプルも面白いです。

補足します

M.Kamataki (2009-05-21 18:33:52 (木))

>メインフォームのテキストボックスの内容をenterまたはshift+enterで切り替えると、これに伴いサブフォーム上の候補が変わる動作をします

普通は、フォームのナビゲーションバーの「次のレコード」「前のレコード」でオペレーションすると思います。

解説ありがとうございます

gorodoku (2009-05-22 08:28:21 (金))

基本的なところからいろいろ解説していただきありがとうございます<(_ _)>
(オープンガイドブックも買っていないので、売り上げに貢献しないと駄目ですね^^)
今朝もこれからいろいろいじってみます。絞り込むところまでうまくいったらまたファイル添付させていただきます。

1段目の絞込み

gorodoku (2009-05-22 10:56:40 (金))

参考ページを見ながら1段目の鋼種での絞り込みは何とかできました。


・コントロールフォームナビゲータ上でメインフォームのテキストボックスをコンボボックスに置き換え、そのプロパティで「ドロップダウン」を「はい」に。
・コントロールのプロパティで「データフィールド」を空欄に。
・「リストの内容の種類」を「sql」、「リストの内容」を「SELECT DISTINCT "テーブル名" FROM "テーブル一覧"」に。
・「テキストを変更したときに」イベントに以下のマクロを割り当て(すみません、ほぼそのまんま参考ページどおりのコードです)。

Sub NewTitleSelected(oEvent)
Dim oForm
oForm = oEvent.Source.getModel().getParent()
oForm.Filter = """テーブル名""='" & oEvent.Source.getText() & "'"
oForm.ApplyFilter = True
oForm.reload()
End Sub


これで、メインフォームのドロップダウンリストで鋼種を選択すると、サブフォームのレコードが選択した鋼種のみに絞り込まれるようになりました。

さて、次は形状・寸法(shapeフィールド)をドロップダウンリストから選択し、候補をひとつに絞り込む、、、ですね。
非連結コントロールのコンボボックスをひとつ追加し、これの「リストの内容」に、1段目で絞り込んだ後のレコードの「shape」フィールドを渡してあげればよいんですね。あとは一段目と同様に、テキストが変更されたときにデータを更新、、、
これは、、、簡単にいきそうにないのでbasicで記述ですかね?とりあえずいろいろ検討してみます。

1段絞り込んだ後の結果の渡し方ですが

gorodoku (2009-05-22 14:05:37 (金))

ただいまbasicの構文勉強したり、参考ページ見たりしながら検討中なんですが、たぶんやりたいこととしては、1段目の絞込みマクロの後ろに

【「形状・寸法を選ぶ為の非連結コントロールコンボボックス」の「リストの内容」プロパティ】=Statement.executeQuery("SELECT DISTINCT "shape" FROM "全材料テーブル結合ビュー" AS "全材料テーブル結合ビュー" WHERE "NAME" =【メインフォームのコンボボックスの値】")

見たいな事ができれば良いのかな、と思います。

これかも

M.Kamataki (2009-05-22 16:08:32 (金))

動作は検証していませんが、使えそうな気がします。

OpenOfficeのプログラミング:コンボボックスのリストを変更
http://samakui.at.webry.info/200810/article_2.html

当ページのマクロ入りサンプルについて

M.Kamataki (2009-05-22 18:17:23 (金))

OpenOffice.org 3.1からBaseのマクロの格納場所が、odbファイル自身に変更されています。そのため、3.1以外のBaseではマクロを実行できませんし、マクロの中味も見られません。当ページのサンプルをご覧になりたい方は、OpenOffice.org 3.1以降をお使いください。

経過報告・2段目のコンボボックスのリストは絞り込めました

gorodoku (2009-05-23 09:38:25 (土))

参考ページの提示ありがとうございます。
取り合えず2段目の候補をコンボボックス化し、1段目の選択によってリストの内容を変えることができましたが、今度は2段目のコンボボックスから選択をしたら、途中でエラーが出るようになってしまいました。


どうもデータを探しに行ってる先を間違えているようです。(「全材料テーブル結合ビュー」にデータを探しに行きたいのに「テーブル一覧」にデータを探しに行ってるようです)

原因ですが

M.Kamataki (2009-05-23 11:23:52 (土))

select1マクロに以下の箇所があります。

oForm = oDoc.getDrawPage().getForms().getByName("MainForm")

MainFormの内容は「テーブル一覧」ですから、ここで取得したオブジェクトがselect2マクロでもそのまま使われてしまっていますね。

ここをなんとかすれば良いと思いますが、まだわからなかったりします。どなたかわかる方いらっしゃいますか。

サブフォーム

gorodoku (2009-05-23 11:33:05 (土))

select2で改めてサブフォームのテーブルを取得しないとならないようですね、、、

ちなみにサブフォームを使わない方法(すべてのコントロールをメインフォームに入れ、「全材料テーブル結合ビュー」のみで選択していく)だとうまくいきました。
ビュー作ったときに「NAME」フィールドが生成されているので、これを利用して2段絞りにしてみました。

Re: サブフォーム

M.Kamataki (2009-05-23 11:48:07 (土))

そうですね。MainFormが「全材料テーブル結合ビュー」であれば、問題はありませんね。

雛形

ike@九州 (2009-05-24 12:27:05 (日))

内容をまだ把握できていないので不十分ですが、土台らしきもの作成

・calculation type を単位とみてます
・メインフォーム、サブフォーム共テーブルコントロールを入れてます
・メインフォームのテーブルでデータ行を選択します
・材料表転記ボタンでデータ行を材料表2に転記します
・サブフォーム上で、名称、長さ、数量を入力してレコード保存ボタンを押すと更新されます。
・変更できるのは名称、長さ、数量のみ、レコードの削除は出来ます。
・材料表2から意図したレポートファイルが作成できるのかはやってみないと分かりませんね。(集計欄その他の挿入)


追記修正、メインフォームの参照元は"結合ビュー"でなく"全材料テーブル結合クエリー"でも問題ないようでした。修正してください
新規材料テーブルの追加はビューへのUNION追加が最も簡単ですね。

faq4_1680.png

異テーブル間の転記

gorodoku (2009-05-25 11:41:49 (月))

ikeさん、サンプル作成ご協力ありがとうございます。
異テーブル間のデータ転記する部分のコーディングなど大変参考になります。

名称や長さ、個数などを入力するコントロールをメインフォームに作り、他のメインフォームのテーブルのデータとまとめてサブフォームのテーブルに転記するなどして、かなり自分の望む形に近いフォームになると思います。
(ちなみに追記の件は、参照元をクエリにしたら絞込みの動作がうまくいきませんでした。こちらの設定がおかしいのかもしれないので自分なりにもうちょっと検討してみますね。)

ここから先は塗装をする/しないとか、材料の重量計算を尺物(長さあたり重量 × 長さ)だけでなく板物(面積あたり長さ × 面積)にするなど、いろいろ改変を加えていくことはありますが、基本となる部分はこれでかなり形になったと思います。

今回のようにすでに基礎となるデータから候補を絞り込んで、別テーブルに転記していく、という作業は材料集計表だけでなくほかの業務にも応用が利くと思います。

と、いうことで本件はいったん完了とさせていただきたいと思います。
何かありましたらまた改めて質問させていただきます。また、勉強してそのうち回答のほうでもご協力できるようになれば、、、と思います。
長くまた面倒な質問でしたが、協力いただいたKamatakiさんikeさん本当にありがとうございました、お礼申し上げます<(_ _)>。

完了にします

M.Kamataki (2009-05-25 15:17:22 (月))

どうもお疲れ様です。わたしも調べ方がだいぶうまくなりまして、2、3年前は実現が難しく感じた質問も、かなりの確率で参考になるサイトを見つけることができるようになりました。

なお、バージョンを「3.0.1」から「3.1.0」へ変更しておきます。

補足

gorodoku (2009-05-25 16:57:48 (月))

完了時の成果ということで一応添付します。
とりあえずサブフォームに材料表テーブルを読み込んでます。


(本来はikeさんの例のようにサブフォーム用クエリーを用いて計算する部分が出てくるんですがちょっと間に合わないので割愛します、ごめんなさい)
メインフォームの各コントロールから値を取得してサブフォームのテーブルに書き込む例、ということで。

Re: 補足

M.Kamataki (2009-05-27 01:05:19 (水))

感想:良い感じですねぇ。 :) 具体的な成果物を添付していただき、ありがとうございます。

訂正

ike@九州 (2009-05-27 08:05:44 (水))

直接ビューのSQL編集も出来たんですね。

新しいテーブルの追加はビューへのUNION追加でOKなのが分かりました
不要なのは結合クエリの方でした ごめんなさいです。

色々試していたところ、
メインフォームのフィルタ更新でサブフォームも更新されますが、その際サブフォームの更新は必要ないですよね、余計な再描画がわずらわしいです。

いっその事、メインフォームには何も置かないで、もう一つサブフォームを新設してメインフォーム配置のコントロールを移動し記述を適宜変更したら

サブフォーム毎の更新で、全く他のサブフォームの余計な再描画がされないのを gorodoku さんの最終サンプルで確認できました。
画面のチラチラが削減できて、今後この方法がお勧めだと思います。

アイデアですね。

gorodoku (2009-05-27 16:34:08 (水))

まだ試してませんが、入力側はそれ用のコントロールを集めたサブフォームに纏めてしまえば、フィルター更新時にそのフォーム内だけが更新される、という感じですね。
画面のチラツキ防止のみならず、おそらく処理的負荷も減ると思うので良いアイデアと思います^^。

お名前:
題名:


添付ファイル: filefaq4_1680.png 952件 [詳細] filefaq4_1680_7.odb 1434件 [詳細] filefaq4_1680_6.odb 1287件 [詳細] filefaq4_1680_5.odb 1283件 [詳細] filefaq4_1680_4.odb 1338件 [詳細] filefaq4_1680_3.odb 1239件 [詳細] filefaq4_1680_2.odb 1285件 [詳細] filefaq4_1680_1.odb 1269件 [詳細] file材料表サンプル.pdf 4624件 [詳細] filemat-sample.odb 1298件 [詳細]