マスタファイル2万件、トランザクションファイル約50件程度のデータベースがあります。
50件のデータを1件1件マスタから検索し(キーは2つ)、あればマスタを修正し、なければマスタに追加するプログラムを作成する場合、どういった方法が良いのでしょうか?

1.Do until トランザクション.eof
   クエリの実行(約50回)
 loop

2.Do until トランザクション.eof
findで検索(約50回)
loop

3.2つともレコードセットを開いて上から順番に検索していく。

分かりづらかったらすみません。方法はこれ位しか思い浮かびませんでした。
ほかにあれば教えて下さい。
1の方法がプログラム的には一番楽なのですが、実行スピードは3なのでしょうか?

すみませんがご教授お願いします。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

まず参考になる質問を一つ(続き物なので2つ上げています)を見てみてください。


http://www.okweb.ne.jp/kotaeru.php3?q=155505
http://www.okweb.ne.jp/kotaeru.php3?q=161189

で前置きはこの程度として

まずトランザクションデータが格納されているファイルをワークテーブルに挿入して

1.マスタテーブルとワークテーブルでキー項目で結合して更新が必要な部分更新する。
2.ワークテーブルにあってマスタテーブルに無いキー項目をもつレコードを抽出(不一致クエリーの応用)
3.2の結果を追加クエリーでマスタテーブルに追加

という方法もありますね。
    • good
    • 0
この回答へのお礼

早速の回答ありがとうございます。
またよろしくお願いします。

お礼日時:2002/01/09 18:48

アクセスのコーディングそのものになっていませんのでお気に


召さないかもしれませんが、寝る時間になったので・・・。
レコード数が多いマスターに対し、数が少ないトランザクションのマスター更新では、色々の処理ロジック考えられる(注)が、一般には
(1)マスターレコードをキー項目でソート(2)トランザクションレコードを同じキー項目でソート(3)(情報処理試験の解説書に良く出てくる)マッチングのロジックで更新するのが一番早いと思います。
マッチングの処理はご存知でしょうが、
p4:マスターを1レコード読む(キーをK1とする)
   もしEOFならk1にハイバリューをセット(ハイバリュー例16進F  FFF...   )
  第1レコード以外はp6へ 
p5:トランザクションを1レコード読む(キーをK2とする)
   もしEOFならk2にハイバリューをセット(ハイバリュー例16進F  FFF...   )
p6:if k1=k2 then goto p1
   if k1>k2 then goto p2
   if k1<k2 then goto p3
   p1:    k1がハイバリュ―なら終わり(p7へ)
          でなければトランザクションでマスターを更新
   p2:    トランザクションでマスターを作る。

次ぎのトランザクションレコードを読みにいく(p5へ)
   p3:    次ぎのマスターレコードを読みにいく(p4へ)
p7:ファイルをクローズ
end   
昔大型コンピュターのオフラインバッチ処理のマスター更新の定番
でした。メモリーが少ないコンピュター時代でそれなりの採用理由があったと思います。ソートプログラム(のロジックがメーカー製で優秀で)早かった事も寄与したでしょう。
(注)1例としてマスターを1レコード読むごとに、全トランザクションを舐めて等しいキーのものが見つかると更新するとか。トランザクションが同一キーが2以上あるかでロジックが変わる。ないと仮定して良いなら見つかって後は打ち切って、次ぎのマスターレコードへ行ける。
       
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

おっしゃらる通りです。
私が3番目に考えていた方法がそんな感じです。
省略したコーディングを2番目に回答して頂いた方のお礼に書いています。
こんな感じでしょうか?

こういったやり方とクエリーを複数回実行するのとではどちらが負荷を掛けずに処理が行えるのか、またどちらが一般的なのかが分かりませんでした。

ご丁寧な回答ありがとうございました。

お礼日時:2002/01/10 11:50

3の「2つともレコードセットを開いて上から順番に検索していく。

」というのはトランザクションを読んでFindかSeekでマスタを検索するっていうやり方でしょうか?
でしたら一番遅いと思います。マスタの方が2万件ということでしたらOpen時だけでも時間かかると思いますよ。
どうしても、3の方法でやる場合でしたらキーはPrimaryKeyだけでなくそれぞれインデックスをつけて、

Do Until TRN.EOF
Set MST=CurrentDB().OpenRecordset("抽出するSQL文",dbOpenDynaset)
If MST.EOF=True Then
MST.AddNew
Else
MST.Edit
End If
  ・
  ・
  ・
MST.Update
MST.Close
TRN.MoveNext
Loop
TRN.Close

っていう感じでやります。

上で書いたようにキーの2つのフィールドにインデックスが設定されている場合、1が一番速いように思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
3の方法ですが、
findもseekも使わず、1件1件上から調べて行く方法を考えてました。
findやseekの場合、トランザクションファイルの件数分だけ行わないといけないですが、1件1件マッチングさせていくと2万件を1回見てやるだけで済むと思ったんです。(説明が分かりづらくてすみません。)

凄い省略して書くと
MST = OpenRecordset(マスタ)
TRN = OpenRecordset(トランザクション)

Do Until TRN.EOF
 If MST.[キー] = TRN.[キー] then
  マスタ修正
  MST.MoveNext
  TRN.MoveNext
 ElseIf MST.[キー] > TRN.[キー] then
  マスタ新規追加
  TRN.MoveNext
 Else
  MST.MoveNext
 End If
Loop
MST.Close
TRN.Close

(キーを昇順とした場合です。)
(マスタが先にEOFになった場合の処理とかは省略しています。)

合ってるかどうかよく分からないですが、非常に簡単に書くと3はこんな感じのつもりでした。

まず、一番最初の方に答えて頂いたクエリーの方法で試してみます。
ただ条件によってマスタの変更するフィールドが変ってくるので(10箇所位)クエリが30個位になるので条件によってSQLを切り替えるようにしていきたいと思います。

似たようなクエリーが増えるのって嫌じゃないですか?
みなさんどうなされているのでしょうか。

どうもありがとうございました。
またよろしくお願いします。

お礼日時:2002/01/10 11:40

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Qword2000での差込印刷、約1000件のデータを100枚程度の紙で印刷したいのですが・・・

word2000でラベルで差込印刷ヘルパーを使って宛名ラベルを作成しようとしています。
データの件数は約1000件で、A4の用紙に10件づつ印刷できるようにして、
用紙が100枚程度ですむようにしたいのですが、うまくいきません。
今起こっている状態は、1ページ目には1番目のレコードから10番目のレコードのデータが入力されていて、
2ページ目には2番目のレコードから11番目のレコードのデータが入力されています。
つまり、この状態で印刷すると、すべての件数のデータを印刷するには約1000枚の用紙が必要になります。
どうすれば1ページ目には1番目のレコードから10番目のレコードのデータが入力されて、
2ページ目には11番目のレコードから20番目のレコードのデータが入力されて出力されるようにできるのでしょうか?

Aベストアンサー

>今起こっている状態は、1ページ目には1番目のレコードから10番目のレコードのデータが入力されていて、
>2ページ目には2番目のレコードから11番目のレコードのデータが入力されています。

それはどうして確認しましたか?
もしかして、差込ツールバーの「ABC](差し込んだデータの表示)ボタンをクリックしながら確認しているのでは?

1頁に複数あるラベルなどをそのボタンで確認すると、質問のような表示になります。

で、ちゃんと差し込まれているかを確認するには、
差込ツールバーの右の方にある「新規文書への差込」ボタンをクリックして、新規文書へ全て差込みます。
差込みが終わったらその新規文書を見て確認します。

そして上手くいったのを確認して、その新規文書を印刷。

勘違いでしたら、ご容赦!
以上。

Qクエリ実行結果0件の場合のフォーム展開中止とメッセージ表示

Access初心者です。
テーブルのデータをクエリで抽出し、フォームで表示しようと考えています。
たとえば、
「テーブル1」に、「ID」「氏名」「部署」「趣味」のフィールドが、
「結果表示フォーム」にも対応するレコードソースを持つボックスがあり、
「条件指定フォーム」に「部署」という名のボックスと、「マクロ1」を割り当てた「ボタン1」がある場合に、
「テーブル1」を基にした「クエリ1」で、「部署」の抽出条件に「[条件指定フォーム]![部署]」と設定し、
「マクロ1」では、「クエリ1」をフィルタにして、「フォームを開く」コマンドで「結果表示フォーム」を開きたいと考えています。
この場合、
「条件指定フォーム」の「部署」ボックスにたとえば「総務部」と入力して「ボタン1」をクリックすると、「テーブル1」中に総務部の社員がいれば「結果表示フォーム」は問題なく展開しますが、「総務部」の社員がデータ中にないときには、すべてのテキストボックスが空欄のまま「結果表示フォーム」が展開してしまいます。
そこで、
「クエリ1」実行の際、結果のレコード数が0件の場合には、「結果表示フォーム」の展開を中止してメッセージボックスを表示するような修正を「マクロ1」に追加したいと思います。
どのような条件付けをすればよいでしょうか。
どなたかよいアドバイスをお願いいたします。

Access初心者です。
テーブルのデータをクエリで抽出し、フォームで表示しようと考えています。
たとえば、
「テーブル1」に、「ID」「氏名」「部署」「趣味」のフィールドが、
「結果表示フォーム」にも対応するレコードソースを持つボックスがあり、
「条件指定フォーム」に「部署」という名のボックスと、「マクロ1」を割り当てた「ボタン1」がある場合に、
「テーブル1」を基にした「クエリ1」で、「部署」の抽出条件に「[条件指定フォーム]![部署]」と設定し、
「マクロ1」では、「クエリ1」をフィ...続きを読む

Aベストアンサー

マクロの条件で
Dcount("*","クエリ1")<>0 →フォームを開く
ではどうでしょう?

又は、
Dcount("*","クエリ1")=0 →メッセージボックス
...            →マクロの中止
             →フォームを開く

Qloopを抜け出すには Exit Forですが

loopを抜け出すには Exit Forですが
loopの次のサイクルに行くには?
For i=1 to 10
.
Exit For
.
.
Next i
今、i=5を実行中とします
以下の処理をスキップして
i=6に行くには、なにかありませんか
普通はIf文で処理するとおもいますが

Aベストアンサー

条件に合う場合のみ実行するのであれば、
DO
LOOP
が便利です。
どのような条件の場合i=6になるのか不明ですが・・・

参考URL:http://www.accessclub.jp/bbs3/0138/superbeg47812.html

Qトランザクション処理

accessをローカルで一人で使う場合は、
トランザクション処理については考慮しなくても問題ないのでしょうか?

Aベストアンサー

トランザクション処理が必要ない場合とは、更新テーブルが1つだけの場合のみで
ローカルや人数に関係なく必要です。

更新項目によって、複数テーブルの項目が更新される場合は整合性を保つために
トランザクション処理が必要になってきます。

http://www.serpress.co.jp/access/vba028.html

まぁ、個人利用で整合性を重視しないなら必要ないとも言えるのですが
デットロックの発生で、テーブル構成の不都合を見つけやすいので
なるべくなら入れた方がいいです。

QAccessでの かな氏名検索・電話番号検索を教えて下さい。

Access初心者です。
今Accessで顧客管理を作製しています。
フォームでかな氏名検索をしたいのですが、
検索先が入力順になっている為とても検索し辛いです。
これをかなの昇順に変える方法があったら教えて下さい。
また電話番号検索でも下4桁での検索とかが可能でしたら、教えて頂けるとうれしいです。
どうぞ宜しくお願いします。

Aベストアンサー

たぶん、コンボボックス、もしくはリストボックスで一覧を出して、そのClickイベントあたりで目的のお客のレコードへ飛びたい、というのもだと思います。

VBAで微調整はいりますが、#2さんのロジックを元に、コンボボックス、もしくはリストボックスの値集合ソースを設定してやればOKだと思います。

もちろん、イベント発生後に、目的のレコードへ飛ぶコードを各必要がありますが、これはコンボボックス作成時のウィーザードで「レコードの移動」を選択すれば、サンプルを作っていくれますので、それを元にモデファイすればいいと思います。


人気Q&Aランキング

おすすめ情報