insertしたmdbファイルでの挿入イベント

タグの編集
投稿者 モナリ座  (社会人) 投稿日時 2011/3/22 15:49:00
vb2010を使ってaccessファイルにレコードをインサートしています。
ここまではうまく行っているのですが、accessで新たにインサートしたレコードのフォームに品名を追加したいのですが、インサートされた時にイベントが発生しません。accessの使いかたの質問かもしれませんが、何か手はあるものでしょうか?品名は都度変わります。その時の品の名前をインサートするタイミングで追記したいと思っています。
教えて下さい。
投稿者 さなだ丸  (社会人) 投稿日時 2011/3/22 16:49:07
インサートした方法にもよるかと思います。
SQLを使用してインサートされたんでしょうか?

それならば、SQLの段階でフィールドに値をセットするように書く必要があるかと思います。


インサート作業を行なっている部分のコードでもあれば、わかりやすいのですが。
投稿者 モナリ座  (社会人) 投稿日時 2011/3/22 17:20:09
インサートはSQLで行っています。
vb2010でaccdb(質問はmdbとしてしましましたが・・)にフィールド含め新たなレコードを入れています。
インサートしているのはどの生産ラインで何時に品物が流れたかを示すためのものです。
そのレコードがインサートされたとき、今、生産で流れている品名を新たなフィールドに追加したいと思っています。品目は日に何種類か変わります。
access2007に外部からインサートされた場合、フォームで挿入後のイベントが発生しないような気がします。
accessで何か設定等、あるのでしょうか?
投稿者 shu  (社会人) 投稿日時 2011/3/22 21:08:05
どういうテーブルがあって
どのテーブルにインサートして
品名はどこから持ってきて
品名を追加する新たなフィールドとはどこにある何の事?
投稿者 とくま  (社会人) 投稿日時 2011/3/23 09:29:27
具体的なコードの提示による説明を要求しても
いいと思うけど、結論はあまり変わらない気がします
のでレスします。

質問で明確になってない点ではっきりさせた方がいい
と思うのは、データ更新は VB2010 なんだけど、
表示更新は VB2010 のフォームなのか Access2007
のフォームなのかという事。
(これも、どちらでも答えは変わらない気もしますが。)

VB(VBA) と データベース(Access) じゃ、隣りの家
みたいなものだから、基本的に隣の家で食事の時間
なのか?お風呂の時間なのか?は、教えてもらわない
と分からないはずです。
そもそもフォームなど起動しているかどうかも分から
ないし、という事はイベントの通知をする人が居ない
のと同じだと思います。

データベースに変更があった場合に何かするには、
一般的には「トリガー」というものを作ります。
データベースの機能です。
キーワード検索すると Access でも情報が引っ掛かる
のであるのかもしれませんが、業務で Access を
データベースとする事はあまり無いので、実績は無し
です。
また、あくまでデータベース上での話で、おまけに
くっついている VBA のイベントが起こせるかも不明。
VB2010 であっても同様。隣の家ならまだ分かるけど、
実際に PC 上で動いているどのプロセスにイベントを
起こせばいいのかなんて判断できないはず。

一般の C/S システムでは、定期的にデータベース
検索して最新のマスタ情報を丸々表示更新します。
よっぽどデータ数が多い場合は差分を取ったりしますが、
データの変更をイベントで検知する事自体しません。

マスタで無く、実績データの更新自体で「排他処理」を
する場合は、データベースのテーブルにロックを掛け
たり、データ自体に更新情報を入れておき(更新者、
更新時間など)トランザクション処理の中で「データの
不整合が見つかった場合はロールバックする」という
作り方をします。

10年も前から変わらない定番の方法なので、最新の
新たな手法があるかどうかは知りません。
投稿者 モナリ座  (社会人) 投稿日時 2011/3/23 14:42:26
トリガについて調べましたが、accessではサポートしていないようです。
また、ご質問の回答ですが、フォームはaccess2007で作りフォームを起動しています。

センサ=>ハード(どのセンサから来たかコードを変えてpcに)=>VBでコードを解析しaccdbに挿入=>access2007でデータ解析や生産進捗確認。今回はaccess2007でレコードが挿入(製品がカウントされたら)新たに挿入されたレコードへ製品コード(フィールド変更)を行いたいと思っています。
vbを使わずaccessだけでできたかもしれませんが、自信が無くコード切り分けはvbを使いました。
更新クエリでフィールドにnullがあった場合、一括で書き込みする手もあるのですが、データベースのトランザクションを有利にするため、ある程度リアルタイムに行いたいと思っています。

単純にaccessのフォームのイベントをどう取るか?方法知らないだけかもしれません。
プロパティーのイベントでクリック時も何も動作しませんでした。
フォーム以外のテキスト等では、マクロも起動できましたが・・・・

accessは最近勉強しだしたばかりです。
教えて頂けると助かります。
宜しくお願い致します。
投稿者 とくま  (社会人) 投稿日時 2011/3/23 15:20:43
> 更新クエリでフィールドにnullがあった場合、一括で書き込みする手もあるのですが、
> データベースのトランザクションを有利にするため、ある程度リアルタイムに行いたい
> と思っています。
「トランザクションを有利」の意味が分からないです。
整合性を保つだけですので、処理の違いによる有利不利は
無いと思っています。

それはさておき、Access2007のフォームを起動していない
時(もしくはアプリケーションエラーで Access の処理が
正常に行なわれなかった時)はどうなりますか?
VB2010 の処理は accdb(mdb)ファイルが存在するだけで
実行できますよね?
システム(アプリケーション)が別である場合は、データの
遅延や不整合は考慮に入れておくべき点だと考えます。
当然、null のフィールドは複数できていると考えるべきでは。

こういった案件をイベントで処理しようとすること自体、
疑問に感じます。
「トランザクションが有利になる」に該当するような利点も
思い浮かびませんし、「ある程度リアルタイム」も実現でき
ますし、テーブルのデータを確認しながら処理した方が、
確実に思います。

が、私の個人的な意見ですのでしばらく様子見します。
投稿者 モナリ座  (社会人) 投稿日時 2011/3/23 16:46:20
とくま様
色々とありがとうございました。
自動でログを取っていきたい。そして製品の切り替え時はACCESSで指定した製品をマスターに追記していきたいと考えました。VBのインサートはACCESSが起動しなくても行われます。通常、何か不具合でACCESSが起動できていない時はご指摘の通り、NULLができてしまいますが、それはイレギュラーとして今は扱うよう考えています。(とりあえず)
本システムはセンサーの数がいっぱいありそれぞれの生産ラインでデータを取りますので、できる限りテーブルの操作は自動でと考えています。トランザクションが有利は、言い方がおかしかったですが、ACCESSフォームを見る人は複数でセンサー入力も都度入っているのに影響が無いようにと言う意味でした。
ご指摘の通り、イベントで行うのは疑問な点がありますが、VBはあくまでもaccdbにデータをインサートするだけに使って後のことはすべてaccessで行いたいと思いました。その時の方法が思いつきませんでした。フォームの挿入後イベントを使えば簡単だと思ったのですが・・。次の手考えてみます。
投稿者 shu  (社会人) 投稿日時 2011/3/23 21:06:40
製品情報がaccdb内にマスタとしてあるのなら、
accdb内のFormが開くときのイベントで製品情報のテーブルを参照し製品名を取得すればよいかと
思います。
投稿者 しるふぃん  (社会人) 投稿日時 2011/3/24 09:49:13
更新するタイミングは2箇所のみですよねぇ。
①VBからインサートする際に品名情報も一緒にセットする。
②shuさんが言っているように、accessを開くときのイベントでクエリ等を実行して更新する。

ただ、②だと開いたときのみの更新になるので、タイマーを仕込んでおき、何分置きとかで更新処理
のみ実行するよう、する必要があるかもです。

処理として効率いいのは、やはりVBからインサートする際に付加情報もつけてが一番いいと思われるので、現状の業務の流れ再度見直し更新タイミングを合わせるのがいいと思われます。
(業務にプログラムをあわせるのではなく、業務改善も必要なときがあるということ。)
投稿者 とくま  (社会人) 投稿日時 2011/3/24 11:26:31
> ②shuさんが言っているように、accessを開くときのイベントでクエリ等を実行して更新する。
そもそも shu さんはマスタテーブルの情報なら、更新処理自体が要らないのでは?
と言ってる気もします。

最初の質問では
> 新たにインサートしたレコードのフォームに品名を追加したいのですが
「品名」はマスタテーブルで1個持っていればいいデータです。「製品コード」
を実績テーブルに入れておいて、表示の Select 文でマスタテーブルと連結
するだけです。

ただし、途中から
> レコードが挿入(製品がカウントされたら)新たに挿入されたレコードへ製品コード(フィールド変更)を行いたいと思っています。
> インサートしているのはどの生産ラインで何時に品物が流れたかを示すためのものです。
となっているので、挿入された時点での履歴管理が必要なデータなのでしょう。
そういったタイミングで処理が必要になる可能性も確かにあります。

が、概要を見ていると、しるふぃんさん提案どおり VB2010 の挿入処理が
やるべき処理の気がします。「トリガー」の話を出しましたが、データを
更新しているのは VB2010 の処理なんだから、正に Trigger(引き金)です
よね。

> ACCESSフォームを見る人は複数でセンサー入力も都度入っているのに影響が無いようにと言う意味でした。
これこそ整合性を保つというのが本システムの肝であり、
> 通常、何か不具合でACCESSが起動できていない時はご指摘の通り、NULLができてしまいますが、
> それはイレギュラーとして今は扱うよう考えています。(とりあえず)
同一アプリケーション内であれば、自分でエラー検知できるので、この
考え方もありますが、別アプリケーション(プロセス)で動いている時点で、
整合性をいかに保つかの仕組みが最重要課題になります。通信などでは
当然、不具合(通信異常)を基準として設計しなければいけません。
イレギュラーな処理では無いからです。通信異常は日常的に起こる事です。
想定して然るべき仕様です。

つまり、VB2010 と Access2007 に処理を分けている時点で、質問者の
言葉を借りるなら「トランザクションは不利」です。

まぁ、それでは処理できないはずですので、実際は VB2010 の処理で、
Access2007 の処理につながる情報を何か入れているはずです。
そうなると、Access2007 の処理は必要ない可能性は非常に高いです。

ま、掲示板で指摘するような内容では無いですけどね。
投稿者 モナリ座  (社会人) 投稿日時 2011/3/24 14:53:12
皆様
色々とご指導ありがとうございます。
確かにトランザクションの件、vbだけで行うのが筋。という事はこの件でやってて思いました。
とくま様がおっしゃる通り、今回のシステムは履歴を取り、常時、フォーム上でリアルタイムに変化(生産カウント数、製品名)を表示しています。
*生産ラインでは常時大画面でフォームを映し、事務室は個々にフォームを開いてみます。
次の手としてvbを直すのは少し厄介。できないことはないと思いますが、今後、これらのデータから生産計画(ラインの品名毎の生産タイム等を計算し終了時間の割り出し、人員計画等)にも生かしたい。
そのため、accessを使いたいと思っています。
*その前にこの仕組みを考えた一番最初は、すべてaccessで行いたいと思ったのですが、accessはちょっとしかやったことが無く断念しました。(だったらすべてvbで、とも言われそうですが、今後の勉強のため。)
現在はshu様が書かれている②の方法で進めています。
更新クエリは、マスターのフォームですでに使っていますので、フォームを開く時と更新クエリの追加で行うつもりです。