Page 455 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 通常モードに戻る ┃ INDEX ┃ ≪前へ │ 次へ≫ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ▼2つの条件が合致したら他のテーブルのデ... すみれ 03/11/28(金) 23:32 ┗Re:2つの条件が合致したら他のテーブルのデ... しのしの 03/11/29(土) 12:23 ┗Re:2つの条件が合致したら他のテーブルの... すみれ 03/12/1(月) 0:29 ┗追加の仕様確認です しのしの 03/12/3(水) 0:48 ┗フローをまとめてみました。 すみれ 03/12/3(水) 3:46 ┗試してみてください しのしの 03/12/3(水) 15:28 ┗Re:試してみてください すみれ 03/12/4(木) 5:00 ┗補足です。 しのしの 03/12/4(木) 10:40 ─────────────────────────────────────── ■題名 : 2つの条件が合致したら他のテーブルのデ... ■名前 : すみれ ■日付 : 03/11/28(金) 23:32 -------------------------------------------------------------------------
伝票明細というテーブルに伝票番号、商品名、入り数という フィールドがあり、レコードが100件近くはいっています。 ○月伝票というテーブルに同じ構造で、伝票番号、商品名、入り数という フィールドがあり、ここには10件程度のレコードがはいっています。 例えば、この○月伝票というテーブルにある 伝票番号が「A001」 商品名が「あいう」 入り数が「3」 というものがあるのですが、このレコードを伝票明細にある 伝票番号「A001」 商品名「あいう」 入り数が「1」というものに上書きしたいのです。 つまり「○月伝票テーブル」と「伝票明細テーブル」で同じ「伝票番号」、 同じ「商品名」フィールドの2つが合致したもののレコードを そっくりそのまま伝票明細テーブルに上書きしたいのです。 「○月伝票テーブル」は、それをもとにしたフォームがあります。 コマンドボタンをおすと上書きできるような方法を考えたいのですが まったく、考えが浮かびません。 どうか助けてください。 |
すみれさん、こんにちは。 まず、確認しておきたいことがあります。 >伝票明細というテーブルに伝票番号、商品名、入り数という >フィールドがあり、レコードが100件近くはいっています。 >○月伝票というテーブルに同じ構造で、伝票番号、商品名、入り数という >フィールドがあり、ここには10件程度のレコードがはいっています。 >例えば、この○月伝票というテーブルにある >伝票番号が「A001」 >商品名が「あいう」 >入り数が「3」 >というものがあるのですが、このレコードを伝票明細にある >伝票番号「A001」 >商品名「あいう」 >入り数が「1」というものに上書きしたいのです。 Q1)伝票番号「A001(半角)」、「A001(半角全角混合)」と微妙に違うのですが、 これは、単なるタイプ間違いですか?それとも仕様ですか? Q2)「入り数」フィールドは長整数型と考えてよいですか? (「3」、「1」と全角になっているので念のため) >つまり「○月伝票テーブル」と「伝票明細テーブル」で同じ「伝票番号」、 >同じ「商品名」フィールドの2つが合致したもののレコードを >そっくりそのまま伝票明細テーブルに上書きしたいのです。 >「○月伝票テーブル」は、それをもとにしたフォームがあります。 Q3)この2つのテーブルの主キーを教えてください。 Q4)このツールは、すみれさんが全て新しく作ろうとしているものですか? それとも、既に動いているものに、その機能だけを追加するものですか? ご希望は比較的簡単に実現できるとおもうのですが、 ご質問を読んでいると、少し不安なのです。 たとえば、「○月伝票テーブル」ということは、月毎のテーブルが複数存在ので しょうが、 年(数値) 月(数値) のようなフィールドを作って1つのテーブルにまとめたほうが、すっきりします。 また、ご希望の処理も、2つのテーブルを1つにまとめるだけで済む (フォーム、レポート時のレコードソースにクエリ設定で済む)ような気もします。 |
しのしのさん ありがとうございます。 初心者なので説明がゴチャゴチャで失礼しました。 >Q1)伝票番号「A001(半角)」、「A001(半角全角混合)」と微妙に違うのですが、 > これは、単なるタイプ間違いですか?それとも仕様ですか? 申し訳ありません。お恥ずかしい限りですが、タイプミスです。 すべて半角です。 >Q2)「入り数」フィールドは長整数型と考えてよいですか? > (「3」、「1」と全角になっているので念のため) はい。長整数型です。 >Q3)この2つのテーブルの主キーを教えてください。 それぞれのテーブルにID番号が1から振られていて、それを主キーにしています。 >Q4)このツールは、すみれさんが全て新しく作ろうとしているものですか? >それとも、既に動いているものに、その機能だけを追加するものですか? 私が新しく作りはじめています。 >たとえば、「○月伝票テーブル」ということは、月毎のテーブルが複数存在ので >しょうが、 > 年(数値) > 月(数値) >のようなフィールドを作って1つのテーブルにまとめたほうが、すっきりします。 「○月伝票テーブル」は複数存在しなくて、常に当月分1つだけです。 当月分に処理したものを「伝票明細」テーブルに追加する形にした後、データを削除し次の月から1から始めたいのです。 先月処理したデータ(既に「伝票明細テーブル」にのっているデータ、つまり伝票番号と商品名が同じもの)で変更があった場合、「○月伝票テーブル」でデータを処理し、「伝票明細テーブル」に上書きしたいのです。 「伝票明細テーブル」には常に最新のデータを入れておきたいので、前にはいってるデータを削除し最新のデータのみを残すようにしたいのです。 説明がわかりづらくて本当にごめんなさい。 よろしくお願いします。 |
すみれさん なかなか書き込みができずに申し訳ありません。 >しのしのさん ありがとうございます。 >初心者なので説明がゴチャゴチャで失礼しました。 いえいえ、私も初心者からちょっと毛が生えている程度です。 自分も、わけわからずに作っていたので、他人事とは思えません。 とくにDBを作るというの、なかなか大変です。 Q1、Q2、Q3、Q4につき、了解いたしました。 >「○月伝票テーブル」は複数存在しなくて、常に当月分1つだけです。 >当月分に処理したものを「伝票明細」テーブルに追加する形にした後、データを削除し次の月から1から始めたいのです。 了解しました。 ただ、テーブル名に○のような文字をテーブル名につけないほうがよい、と思います。 個人的な思い込みかもしれませんが、SQL文を作成するような時に困ることがあるかもしれません。一般的なDBでは使用できなかったはずです。(勘違いかも?) まぁ、ACCESS.MDBはなんでもありですから、問題ないかな? この辺りは、博識の方の投稿をお待ちしております。 >先月処理したデータ(既に「伝票明細テーブル」にのっているデータ、つまり伝票番号と商品名が同じもの)で変更があった場合、「○月伝票テーブル」でデータを処理し、「伝票明細テーブル」に上書きしたいのです。 Q5)逆に○月伝票明細は、(履歴を残すなどの目的で) 同じ伝票番号かつ同じ商品名のレコードが複数存在する可能性がある ということですか? Q6)先月処理したデータでないものは、何も処理しないのですか? Q5,6)質問がわかりつらいですかね?下のフロー例のように、 ご希望の処理例を書いていただければ、有り難いです。 伝票番号'A002'、商品名'かきく'の処理が発生 ↓ 処理1.○月伝票テーブルに 伝票番号'A002' 商品名'かきく'のレコードがあるか チェック ↓ 処理1.1-1 レコード有り 入り数4に更新 処理1.1-2 レコードなし 伝票番号'A002' 商品名'かきく'入り数4のレコード追加 ↓ 処理2.伝票明細テーブルに伝票番号'A002' 商品名'かきく'のレコードがあるか チェックする。 ↓ 処理2.1-1 レコード有り 入り数を4に更新 処理2.1-2 レコードなし 伝票番号'A002' 商品名'かきく'入り数4のレコード追加 すみれさんのご希望は、上記例でいうところの、処理2および処理2.1.1になります。 早く、すみれさんのご希望の処理まで到達したいのですが、 仕様がわからないと、どうしようもないのです。すいませんね。 PS 正規化って御存じですか? 例えば、商品マスタテーブルというのを作ります。 商品ID 取り扱い会社ID 商品名 価格 在庫数 で、伝票を新規作成する画面でリンクしておけば、ほぼ自動ではいります。 そして伝票明細テーブルなどには、 商品ID 価格 というフィールドを用意し、レコード追加時に入力しておきます。 (価格は、変動する可能性がありますから、) で、伝票明細情報としては、商品マスタテーブルと伝票明細情報の外部結合 クエリーをテーブルかわりに使用します。 それにより、商品マスタテーブルの更新だけでいつでも最新の在庫数がみえるし、 同じ商品名をもつ、他の商品と間違うこともなくなるわけです。 すみれさんのテーブルも同じようにもう少し整理したいなぁと思うのですが、 そこまでやったらでしゃばりすぎか?と、少々、悩んでいます。 |
しのしのさん お返事ありがとうございます。 大変感謝しております。 >ただ、テーブル名に○のような文字をテーブル名につけないほうがよい、と思います。 はい。「○月伝票テーブル」と書いてしまいましたが、「当月伝票テーブル」という名前で使用しています。すみません。テーブル名を何にしていいか迷っていたので○月と書いてしまいました。 >Q5)逆に○月伝票明細は、(履歴を残すなどの目的で) > 同じ伝票番号かつ同じ商品名のレコードが複数存在する可能性がある > ということですか? 同じ伝票番号で同じ商品名のものは、必ず1つのレコードしかありません。 >Q6)先月処理したデータでないものは、何も処理しないのですか? 先月にかかわらず、遡って1度処理したレコードが訂正(更新)になることがあることはあります。 頭がゴチャゴチャになってしまったので、もう1度よく考えてフローをまとめてみました。 1.伝票番号’A002’、商品名’かきく’の処理が発生 ↓ 2.「当月伝票テーブル」を基にしたフォームがあるので入力。「当月伝票テーブル」にレコード作成。 ↓ 処理2.2-1.「伝票明細テーブル」に同じ伝票番号’A002’、商品名’かきく’があるかどうかチェック 処理2.2.-2レコードあり。入り数4に更新 処理2.2-3レコードなし。伝票番号'A002' 商品名'かきく'入り数4のレコード追加 この処理2.2-1と2.2.-2をしたいのです。 >早く、すみれさんのご希望の処理まで到達したいのですが、 >仕様がわからないと、どうしようもないのです。すいませんね。 本当にありがとうございます。初心者のため、説明が的を得なくて申し訳ないです。 >正規化って御存じですか? >すみれさんのテーブルも同じようにもう少し整理したいなぁと思うのですが、 >そこまでやったらでしゃばりすぎか?と、少々、悩んでいます。 とんでもないです。 ご親切に感謝します。 正規化は、前に1度してみたことがあるのですが、うまくできなかったので もう1度ヘルプをみて勉強してみたいと思います。 只、今回のDBにも「商品マスタテーブル」はあるのですが、管理しているのは「商品ID」と「商品名」だけです。私の会社は変わっていて、価格の管理を部内でしていません。部内で必要なのは最新の「入り数」情報なので、一覧できるようなものを作りたく思っています。 「商品マスタテーブル」の商品IDは「伝票明細テーブル」、「当月伝票テーブル」の商品IDと結び付けています。 また説明がわかりづらくなって申し訳ないです。 よろしくお願いします。 |
>頭がゴチャゴチャになってしまったので、もう1度よく考えてフローをまとめてみました。 > >1.伝票番号’A002’、商品名’かきく’の処理が発生 > ↓ >2.「当月伝票テーブル」を基にしたフォームがあるので入力。「当月伝票テーブル」にレコード作成。 > ↓ >処理2.2-1.「伝票明細テーブル」に同じ伝票番号’A002’、商品名’かきく’があるかどうかチェック >処理2.2.-2レコードあり。入り数4に更新 >処理2.2-3レコードなし。伝票番号'A002' 商品名'かきく'入り数4のレコード追加 > >この処理2.2-1と2.2.-2をしたいのです。 えーっと、とりあえず作ってみました。 「当月伝票テーブル」を基にしたフォームで、 直接フォーム上のレコードにユーザから変更が加えられた場合、処理が走ります。 コントロール名は、そのコントロールソースと同じ名前にしていますので、 変換してお使いください。(「Me.ddd.value」 の「ddd」のことです) また、伝票番号、商品ID、入り数にNULL値はないものとしています。 下のモジュールをフォームのコードに貼り付けて、 念のため、フォームプロパティ-イベントで 更新前処理 更新後処理 読み込み時処理 をイベントプロシージャにしてください。 ------------------------------------------------------ Option Compare Database Option Explicit Private mblnFlg As Boolean 'ユーザ変更処理フラグ Private Sub Form_AfterUpdate() If mblnFlg = True Then Call ExcuteMEISAI End If mblnFlg = False End Sub Private Sub Form_BeforeUpdate(Cancel As Integer) 'ユーザがデータ更新したり、新しいレコードを設定したとき If Me.Dirty = True Or Me.NewRecord = True Then '当月伝票データの重複レコードチェックをしてくださいね 'ユーザデータ更新完了フラグを立てて処理を終了する mblnFlg = True Exit Sub End If mblnFlg = False End Sub Private Sub Form_Load() mblnFlg = False End Sub Private Sub ExcuteMEISAI() Dim lngAffected As Long '更新レコード数 Dim strSQL As String 'SQLステートメント 'すみれさんフロー処理2.2.-2 の処理をしています。 strSQL _ = "UPDATE 伝票明細テーブル SET 入り数 = " & Me.入り数.Value & vbNewLine _ & "WHERE 伝票番号= '" & Me.伝票番号.Value & "' AND 商品ID=" & Me.商品ID.Value & ";" _ & vbNewLine CurrentProject.Connection.Execute strSQL, lngAffected '処理2.2.-2の処理をチェックしています Select Case lngAffected Case 0 '伝票明細テーブルには条件にあうレコードがなかった。 'すみれさんフロー処理2.2-3の処理をしています(レコードを追加する) strSQL _ = "INSERT INTO 伝票明細テーブル ( 伝票番号, 商品ID, 入り数 )" _ & vbNewLine _ & "SELECT '" & Me.伝票番号.Value & "'," & Me.商品ID.Value & "," _ & Me.入り数.Value & ";" & vbNewLine CurrentProject.Connection.Execute strSQL Case Is > 1 '伝票明細テーブルに条件にあうレコードが複数あった(想定外 ) 'エラー処置は必要ならつけてください。 MsgBox ("伝票明細テーブルのレコードが重複しています") End Select End Sub ------------------------------------------------------------------- こういうものは、フォームやコントロールのプロパティでかなり違いますので、 (私の思い違いもありますしね) 一度で動作するとは思えません。 試してみて、エラーになったところを教えてください。 よろしくお願いします。 ----- 上の処理では、「当月伝票テーブル」を基にしたフォームからユーザがデータを 更新した場合の処理のみに対象になります。 ですから、すみれさんが、別途、VBAなどでデータを更新することになれば、 その処理を必ず追加しなくてはなりません。 ですから、「入り数」というのを2つのテーブルに持ち、それを最新に更新する という処理を考えるより、データをどちらか1つに持たせているほうが、 あとあとラクです。 また、すみれさんの処理はレコード追加時の重複チェック がないようです。 (多分、目視で充分とお考えなのですね) 例えば、当月伝票の主キーをID番号でなく、 伝票番号と商品ID とに設定しておけば、各チェックはDBがやってくれます。 |
しのしのさん すばやいレスポンスありがとうございます!! さっそく試してみようと思うのですが、初心者の私にとって、とても複雑なコードにおののいています。明日、会社で試してみようと思います。 >例えば、当月伝票の主キーをID番号でなく、 >伝票番号と商品ID とに設定しておけば、各チェックはDBがやってくれます。 1枚の伝票のデータ件数が少ないので、 レコード追加時の重複チェックは、いれてませんでした。 これも考えてみたいと思います。ありがとうございます。 >ですから、「入り数」というのを2つのテーブルに持ち、それを最新に更新する >という処理を考えるより、データをどちらか1つに持たせているほうが、 >あとあとラクです。 例えば「伝票明細テーブル」に直接データを追加していく形にしたら、 伝票番号 商品ID 入り数 A001 000101 5 A001 000101 3 となると同じ伝票番号、商品IDで2つのレコードができてしまい どっちが最新かわかりません。 日付をいれて日付の新しい日だけをクエリとかで選び出すということができますか? 日付 伝票番号 商品ID 入り数 12/1 A001 000101 5 12/2 A001 000101 3 同じ伝票番号、商品IDで1つしかレコードがない場合はそのレコードを 複数あるときは(今のところ複数=2つなのですが) 最新の日付を選ぶとういことができるなら、 今まで悩んでいたことはなんだろうという気もするのですが…。 でも、これはこれで又難しそうな気がする、自分の頭の悪さに卒倒しそうです。 |
▼すみれ さん: >しのしのさん すばやいレスポンスありがとうございます!! >さっそく試してみようと思うのですが、初心者の私にとって、とても複雑なコードにおののいています。明日、会社で試してみようと思います。 いろいろ実装を考えてみたのですが、 将来カスタマイズすることを考えて、 ちょっと、分かりづらいものになってしまったかもしれません。 いま、お使いの参考書とかけはなれているようでしたら、作り直しますよ。 (といっても、Runコマンドはあまり使ったことがないので、??です。) ADODBとかDAOとかRecordSetなど、でてきます? ------------------------- ここより下の記述は、モジュールとは全く関係なく、 まぁ、言い換えると、私のあくの強さがでているような記述なので、 無視していただいても、結構なのに、ご丁寧にお返事くださって ありがとうございます。 >>例えば、当月伝票の主キーをID番号でなく、 >>伝票番号と商品ID とに設定しておけば、各チェックはDBがやってくれます。 >1枚の伝票のデータ件数が少ないので、 >レコード追加時の重複チェックは、いれてませんでした。 >これも考えてみたいと思います。ありがとうございます。 > >>ですから、「入り数」というのを2つのテーブルに持ち、それを最新に更新する >>という処理を考えるより、データをどちらか1つに持たせているほうが、 >>あとあとラクです。 > >例えば「伝票明細テーブル」に直接データを追加していく形にしたら、 > >伝票番号 商品ID 入り数 >A001 000101 5 >A001 000101 3 > >となると同じ伝票番号、商品IDで2つのレコードができてしまい >どっちが最新かわかりません。 >日付をいれて日付の新しい日だけをクエリとかで選び出すということができますか? 履歴を残す必要がある場合もありますが、 同じ内容のレコードが2つもできるのは、問題があると思います。 すみれさんの場合なら必要ありませんよね。 >日付 伝票番号 商品ID 入り数 >12/1 A001 000101 5 >12/2 A001 000101 3 > >同じ伝票番号、商品IDで1つしかレコードがない場合はそのレコードを >複数あるときは(今のところ複数=2つなのですが) >最新の日付を選ぶとういことができるなら、 >今まで悩んでいたことはなんだろうという気もするのですが…。 >でも、これはこれで又難しそうな気がする、自分の頭の悪さに卒倒しそうです。 これは私が通常行なうやり方なのですが、 ユーザに見せるフォームのレコードソースには、 複数のテーブルを結合させたり、レコード数を絞り込んだりしたものを使います。 いわゆる選択クエリを使う、と考えてください。 「正規化」してテーブルを分割して、データの重複を避けるのです。 ですから、ユーザの「データ追加」の操作には複数のテーブルにレコードを追加する ことが必要になります。 そのために、「データ追加」には、入力専用のフォームなり、非連結コントロールなりに 入力していただいて、ボタンクリック操作を経て、 該当のテーブルにレコードを追加させる、という場合が多いです。 すでに登録されているデータを更新する場合も、 ユニークな値で検索し、非連結コントロールや、別のフォームに書き出してから、 ユーザが更新し、ボタンクリック操作を経て、レコードを更新することが多いです。 この方法では、いくつかの利点がありますが、説明しきれないので省略します。 例えば、すみれさんの作成フォームの問題点は レコード追加と更新が同時にできてしまうことから、 本来変更できない(変更したらシステム上大問題)伝票番号と商品IDの 値を自由に変更できる状態にありますよね。 また、今回は全く考慮に入れていませんが、複数ユーザが同時に利用した場合など 問題がでてきます。 しかし、これらは運用でカバーできる範囲ですので、問題を認識していただく程度で構わないと思います。 (じゃあ、書くなって???ごめんなさい) あまり、回答になっていませんね。 |