• 締切済み

VBAでデータベースの構築をしています。

VBAでデータベースの構築をしています。 全く同じフィールドを持つ2つのテーブルがあり、その2つのテーブルを 比較し、重複するレコードのみを3つ目のテーブルに抽出したいのですが、 可能でしょうか? 『重複するレコードを削除する』というのはウェブで検索すると出てくる のですが・・・ よろしくお願いいたします。

  • man_u
  • お礼率70% (56/80)

みんなの回答

  • DexMachina
  • ベストアンサー率73% (1287/1744)
回答No.10

No.3です。 まず、不適切な言葉がありましたこと、お詫びします。 大変失礼致しました。 >No.4 > 下記のような方法でとりあえずは快適に動作しましたが、 > エラく回り道をしている感は否めません。 失礼、「重複」の意味を取り違えていました。 (「テーブルA、テーブルBで一致するレコードがあるもの」と  考えていました) ご質問のパターンでも、クエリやSQL文で対応可能です。 1)テーブルAとテーブルBを結合させたクエリをデザインビュー  で開く(→レコードが単純に重複表示される選択クエリ) 2)ツールバーなどから『Σ(集計)』ボタンをクリック 3)クエリに『集計:』行が追加されるので、1レコードに集約  するフィールドについては「グループ化」を指定  →No.8で提示の例では「field2」が該当 4)重複しているかどうかを判定するフィールドについて、  『集計:』行に「カウント」を指定  →同じく提示例では「field1」が該当 5)「カウント」を指定したフィールドの『抽出条件:』行に、  「>1」を指定  (→仮に「5件より多い場合」なら「>5」を指定することに  なります)  ※重複数のデータの表示が不要な場合は『表示:』の   チェックをオフにしておきます。 6)上記クエリをテーブル作成クエリ、又は追加クエリとして  保存 ・・・以上です。 なお、添付画像は、フィールド構成が異なりますが、 こちらで作成したサンプルになります。 この画像のSQL文は、以下の通りです: (SQLビューに切り替えて表示されたものをそのまま貼付) SELECT テーブルA.店舗ID, テーブルA.店舗名, テーブルB.顧客ID INTO 来店一覧 FROM テーブルA INNER JOIN テーブルB ON テーブルA.店舗ID = テーブルB.店舗ID GROUP BY テーブルA.店舗ID, テーブルA.店舗名, テーブルB.顧客ID HAVING (((Count(テーブルB.来店ID))>1)); プログラミングにしても話し言葉にしても、「言語」の習得の 基本は「他人のものをなぞる」ところから始まると思います。 提示したサンプルが基礎を固める手助けとなれば幸いです。

  • layy
  • ベストアンサー率23% (292/1222)
回答No.9

>おそらくご説明いただいた動作と似てます? いろいろロジックを考えた結果であれば問題ないです。 VBAでやりますというからには、 VBAで(クエリでもできるINSERT、DELETEらそのままの)SQL実行するよりは、 クエリでできないこと、 VBAでないとできないこと、 を実装するのが今後のためになると思います。 応用すれば、テーブルはいくつか出力できるので、 テーブルAとテーブルBをそれぞれ読み込み、 テーブルAだけのレコードのテーブルC出力、 テーブルBだけのレコードのテーブルD出力、 テーブルA、Bの重複レコードのテーブルE出力、 と1回の処理でできるようになります。 ほか実現策もいろいろあります。 エクセルで重複となるデータを求めておいて アクセスで条件に付与してもできます。 比較キーだけテキストファイルに保存してコンペアしても良いです。 重複するレコードを削除できれば、その裏返しの発想で、 残ったレコード=今回削除したいもの、になります。 時間かけてもうちょっと考えてみる=ヒントがみつかる、という事も必要です。 答えを提示したら、その時点で解決、で終わり。その先の応用を考えなくなるケース多いです。 がんばってください。

  • layy
  • ベストアンサー率23% (292/1222)
回答No.8

テーブルA 「1」「2」「3」「4」の4レコード テーブルB 「1」「1」「3」「5」「6」の5レコード とあった場合 テーブル作成クエリと追加クエリで テーブルC 「1」「A」 「2」「A」 「3」「A」 「4」「A」 「1」「B」 「1」「B」 「3」「B」 「5」「B」 「6」「B」 クロス集計クエリ ヘッダ「 」「A」「B」 --------- 明 細「1」「A」「B」重複 明 細「2」「A」「 」 明 細「3」「A」「B」重複 明 細「4」「A」「 」 明 細「5」「 」「B」 明 細「6」「 」「B」 これはできますか。 ※VBA上でSQL文発行でしょうか??

man_u
質問者

お礼

2度もありがとうございます。 解決しました。 下記のような方法でとりあえずは快適に動作しましたが、 エラく回り道をしている感は否めません。 (1)テーブルAとテーブルBを結合し昇降順にソート (2)最初のレコードと次のレコードを比較  一致すれば次へ、不一致であれば最初のレコードを削除  というのをEOFまで繰り返す (3)一致したレコードが2つレコードとして残る    field1 field2     1 aaaa    2 aaaa     3 bbbb     4 bbbb     5 cccc     6 cccc というようなテーブルが出来きました。 (4)上記例でいうfield1の偶数を削除する。 といった具合です。 おそらくご説明いただいた動作と似てます? SQL文発光であったり、DAOであったりけっこうグチャグチャしてます。

  • layy
  • ベストアンサー率23% (292/1222)
回答No.7

例えば、 テーブルA 「1」「2」「3」「4」の4レコード テーブルB 「1」「1」「3」「5」「6」の5レコード とあった場合、 Aの1-Bの1(1つめ)重複 Aの1-Bの1(2つめ)重複 Aの1-Bの3 Aの2-Bの3 Aの3-Bの3重複 Aの3-Bの5 Aの4-Bの5 Aの4-Bの6 終了 となる基本構造のロジックをまず作れば良いです。 あとは判断条件、出力条件、終了条件を確認すればできます。 50行いかないくらいです。 DO~LOOP文とIF文、レコード移動くらいなんですが、 機能要件が固まっていながら書けないならしょうがないです。 クエリにしてもVBAにしても テーブルAとテーブルBの一致するレコードは 1レコード(上記例の3)なのか複数レコード(上記例の1)なのか、 どっちを想定した回答か、両方を満たしている回答かは 確認しておいた方がいいですね。

  • layy
  • ベストアンサー率23% (292/1222)
回答No.6

COBOLというかマッチングのアルゴリズムがわかれば、本件何ら問題ないので、余裕があればお願いします。

  • layy
  • ベストアンサー率23% (292/1222)
回答No.5

参考) COBOLでよく使うマッチング(1:1や1:N)のプログラムロジックを VBAで実現したらできます。 COBOLプログラミングでは基本です。 簡単にいうと、 AファイルとBファイルを順番に1レコードずつ読み込んで 比較するキーが、 A=Bのとき、両方にある A<Bのとき、Aにしかない、 A>Bのとき、Bにしかない、 と判断するロジックです。 比較判定のあと、次に読み込むのはAなのかBなのか、 終了タイミングはいつなのか、がポイントです。 AとB両方にあるとき、 Aだけ出力しておく、Bだけ出力しておく、AとB両方出力しておく、制御可能です。 お勧めしたいですが、 ロジックが理解できてないと失敗します。

man_u
質問者

お礼

ありがとうございます。 COBOLですか。名前を聞いたことあるだけで全くわからないです。 こういう制御ができれば、というのは少しは思い浮かぶのですが、 いざコードにしようとするとなかなか思うようにいかないですね。

  • air300p
  • ベストアンサー率15% (9/60)
回答No.4

ん? これってAccessだったの? ところで Excelでもテーブル、レコード、フィールドの概念はありますけど・・。

man_u
質問者

お礼

ありがとうございます。 Accessだったんです。

  • DexMachina
  • ベストアンサー率73% (1287/1744)
回答No.3

「VBA」「データベース」「フィールド」「テーブル」のキーワードから、 Accessについてのご質問と推測しての回答になります。 (勘違いされている方がいるようなので、念のため) > 2つのテーブルを比較し、重複するレコードのみを3つ目のテーブルに > 抽出したい 「テーブル作成クエリ」または「追加クエリ」で、ご希望の動作を行えます。 a)「テーブル作成」クエリは、抽出実行時にテーブル自体を作成します。  (同名テーブル存在時は、上書き(=既存のテーブルが削除)されます) b)「追加クエリ」は、既存のテーブルにレコードを追加します。  (指定したテーブルが不在の場合は、エラーになります) なお、前者では、作成したテーブルに主キーやリレーションシップ等を 設定しても、上書きによって消されてしまいます。 ですので、フォームでの表示程度にしか使わない(=インデックスなどを 使わない)なら前者、抽出結果を元に検索や抽出を更に行うなら後者が、 それぞれお勧めです。 1)新規クエリをデザインビューで開き、比較対象となる2つのテーブルを  追加 2)比較に使用するフィールド全てについて、一方から他方のテーブルに  フィールドをドラッグ&ドロップするなどして、結合線を作成 3)メニューやツールバーなどから、クエリの種類を「テーブル作成クエリ」  や「追加クエリ」に設定 4)作成又はレコードを追加するテーブル名を要求するダイアログが表示  されるので、テーブル名を指定後、『OK』ボタンをクリックしてを閉じる 5)適当な名前をつけて保存 ・・・基本は以上ですが、このときによく問題になるのは、「フィールドの値 がNullの場合は、一致(重複)とみなされない」(=結果、意図した抽出状態 にならない)ということです。 これを回避するには、  a)【初心者にわかりやすいと思われる方法】   それぞれのテーブルを直接使用する代わりに、各テーブルごとに   「Nullのフィールドを適当な値に変換するクエリ(各フィールドにNz関数   を適用して、テキスト型なら「""」(空文字)、数値型なら「0」や「-1」など   に変換、と)を作成して、これをレコード比較に使用する  b)【SQL文の編集が苦にならない場合】   クエリをデザインビューからSQLビューに切り替えて、On句に指定して   いるフィールドを、Nz関数で変換する形に編集   <編集前> ・・・ On TblA.ID = TblB.ID And TblA.氏名 = ・・・   <編集後> ・・・ On Nz(TblA.ID, -1) = Nz(TblB.ID, -1) And Nz(TblA.氏名, "") = ・・・ といった方法を採ることになります。 (添付画像では「テーブルA」等としていますが、ここでは1行に収めるため「TblA」  などとしています)

man_u
質問者

お礼

ありがとうございます。 推測通りaccessでございます。 細かい説明に画像まで入れていただき ありがとうございます。 試してみます。

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.2

>『重複するレコードを削除する』というのはウェブで検索すると出てくる のですが・・・ そっくり丸写しするコードを探しても無理だろう。処理ロジックがどうなるのか、考える力が無ければ、VBA使いではない。エクセルで「データベースの構築」(大がさ)など出来ない。 余談だが、VBAでなくても、VLOOKUP関数などでも近いことが出来ると思う。 ーーー 本題は、2つのファイルの突合せ問題で (1)両者をキーで各々ソートして、両者をマッチングのアルゴリズムで比較 http://soudan1.biglobe.ne.jp/qa5512095.htmlの私の回答(ただしCSVファイルの質問例) (2)「1方のデータの1行のキーデータ」を軸にして、他シート?のデータを、初めから終わりまで総なめして探す。平均で数*1/2の比較を行う泥臭い方法だがわかりやすい。 全行繰り返す。 (3)「1方のデータの1行のキーデータ」を軸にして、他シート?のキー列データをFindメソッドで探し、見つかれば重複あり。全行繰り返す。 (4)後者のデータをソートしておき、2分法で探索。比較階数は少なくて済む。 (5)あと後者を前者の下行範囲ににコピペ。キーでソートして、重複出現するキーがあるかチェック (6)その他 誰か良いアイデアがあるかも こう言う思考訓練を得て、コードを書いてみて、行き詰ったら質問というのが、力をつけるもと。

man_u
質問者

お礼

ありがとうございます。 投稿したすぐ後に気付きました。 『access 2000』て入れんの忘れてるわ!と・・・ すみません。 2つのテーブルを結合し、ソートし、上から順に直下の行(レコード)との文字列を比較を し、というようなことは思いついたんですが、(1)のようなやり方があれば 一番快適ですね。

  • air300p
  • ベストアンサー率15% (9/60)
回答No.1

いろいろやり方があるんだろうけど 一番簡単だと思うのは そのレコードのフィールドをすべて & で連結して1つの文字列にしてしまい それを比較して同じかどうかで判断すればいいのでは? ワタシがよくやる手法です レコードの検索は For EACH なんかでやればいいかと・・

man_u
質問者

お礼

ありがとうございます。 フィールドを全て連結!? なんだか難しそうですね。 レコードの検索とかはできるのですが・・・

関連するQ&A

  • Access2000で重複データに・・・

    Access2000の重複データの処理について質問です。 あるフィールドの重複レコードを検索し、該当するレコードの別フィールドに「●」をつけようとしています。ただ、重複する最初のレコードには「●」をつけたくないのです。 例えば  aaa ・・・ (1)  bbb  aaa ・・・ (2)  ccc  aaa ・・・ (3)  eee というフィールドだった場合、(1)には「●」をつけずに(2)以降にのみつけたいのです。 重複クエリで重複レコードを抽出して重複テーブル作成→重複テーブルと元テーブルを組み合わせて更新クエリ作成という方法でやったのですが、そうすると(1)にも「●」がついてきます。(当然ですが・・・) 何か名案があれば教えてください。 やはり、VBAを使わないと無理でしょうか・・・?

  • 「主キー以外重複データ(フィールド多数)」の抽出

    タイトルのような抽出方法が必要になり、その出し方で困っています フィールドが100以上ある大きなテーブルが複数(フィールド構造は全く同じ)あり、 そのレコードを一つにまとめる為重複データを抽出し削除したいのです 条件は「主キー以外の全てのフィールドのデータが一致してる重複データ」であり、 それをどうやればAccessの機能で出せるのか悩んでいます。 最初はクエリでグループ化して出そうと思ったのですがこのフィールド数では全て グループ化はできず、 VBAで一行ずつループで処理しようにもキー以外の全フィールド一致とする検索条件のSQLのWHERE式が複雑すぎると出て処理できませんでした フィールド数が多大なテーブルで主キー以外完全一致の重複レコードをうまく抽出するにはどうすればいいのでしょうか?

  • データベースのワイルドカードは%ではないの?

    アクセスのテーブルに あ い う があり、 SQL文で *********************************************** SELECT テーブル1.フィールド FROM テーブル1 WHERE (((テーブル1.フィールド) Like "%あ%")); *********************************************** としてもエラーにならないけど、「あ」が抽出されません。 *********************************************** SELECT テーブル1.フィールド FROM テーブル1 WHERE (((テーブル1.フィールド) Like "*あ*")); *********************************************** にすると、「あ」が抽出されます。 アクセスなどのデータベースのワイルドカードは%だと思っていたのですが違うのですか?

  • excel vbaでデータベース構築

    現在、excel vbaで共有サーバ上にあるデータベース(excelファイル)を複数人で利用していますが、データ数に限りがあるし、データ数が増えて動きが鈍くなっています。 そこで、共有サーバ上のデータベースをmdbファイルに変更してみようかと考えてWeb検索してみたら、危険な行為みたいな記述が多く、困惑しています。 そこで、ご存知の方にお尋ねします。なお、私はvba以外は知らない超初心者です。 1.excel vba で mdbファイル を利用することの是非。 2.もし、mdbファイルを利用する場合、ここさえ注意すればOK!というアドバイス よろしくお願いします。

  • データベースの設計について少し疑問が出たので投稿しました。

    データベースの設計について少し疑問が出たので投稿しました。 数千万レコードを取り扱う場合、以下のどの構成が一番クエリを早く実行できるのでしょうか? 1.1つのデータベースに1つのテーブルを構築して全てのレコードを格納。 2.1つのデータベース内に複数のテーブルを構築して、レコードを分散して格納。 3.複数のデータベースにそれぞれ1つのテーブルを構築して、レコードを分散して格納。 データベースはMySQLです。 参考までに、ご意見をお聞かせいただければと思います。 宜しくお願いします。

    • ベストアンサー
    • MySQL
  • access・複数のテーブル・重複除外したデータ

    accessで複数のテーブルで重複しないレコードだけを抽出するSQL文を知りたいです。 フィールドは多数あり、「フィールドの内容が全て一致するレコード」以外のレコードを 重複しないレコードとして抽出したいと思っています。 テーブルは3つ以上ありますが、2つのテーブルで実行するSQL文でかまいません。

  • SQL文の構築について教えてください。

    SQL文の構築について教えてください。 こんばんは。Oracle9iのデータベース検索で、どうしてもSQLが思い浮かばないため、質問させていただきます。 ■Table ID    NUM   SIGN 100   1    A 100   2    A 101   1    A 102   1    B 103   1    B 104   1    C 首キーはID、NUMです。 上記のようなテーブルで、 IDが同一かつNUMが最大のもので、 SIGNが同一のレコードで、2件以外のレコードを抽出したいです。 (例表でいうと、ID104のレコードのみが抽出されるようにしたい) すこし急ぎなんですが、SQLが得意でお時間がある方、力を貸していただけないでしょうか。 よろしくお願い致します。

  • ExcelのVBAでAccess操作です

    タイトルの操作で、エクセルシートのセルのコード番号をアクセスの データベースのIDのフィールドから検索し、アクセスのその行を削除または、修正をしようとしています。 アクセスのIDのフィールドには重複するものは存在しません。 現在For~Nextで一行づつ見る方法まできましたが、レコード数が増えた場合かなりの時間がかかります。 エクセルのVBAの記述で TROW=検索範囲.Find(検索文字列,Lookat:=xlWhole).Row に換わる記述はどういうものがあるのでしょうか? エクセルのVBAで処理をしたいのですがよろしくお願いします。 また、For~Nextの記述の場合、変更しようとするとLockedがYesになっているため変更できない旨のメッセージが出ます。 アクセスのテーブルにロックがかかっている意味だと思うのですが、 Unprotectのような記述もあれば教えていただきたいと思います。 アクセスは全く初めてで壁にぶち当たっています。 どうぞ宜しくお願いします。

  • vba

    ACCESSのVBAからテーブルを作成する方法を教えてください。 フィールド内に書かれるレコードは、VBAからインポート(?) するような形になります。

  • 2つのテーブルで重複する値のレコードを削除したい

    削除クエリ?重複クエリ?について教えてください。 テーブル1 フィールド"番号"には 1 2 3 テーブル2 フィールド"番号"には 3 4 5 があるとします。 「テーブル2と重複しているテーブル1のレコードを削除する」 (この場合「3」が重複しているのでテーブル1の3が入力されているレコードを削除) としたいのですがどいゆうSQL文を書けばいいのかわかりません。 ご教授よろしくお願いします。

専門家に質問してみよう