Access2000VBA・Excel2000VBA独学~A表とB表の内容を(連番列以外の)「すべての列」で比較して、B表から、「重複しない行」を取り出す。(できたら、「抽出されたもの」について何かするために)
  
※まだ書きかけです。すみません。
※間違ってたらすみません。
※メモ書きなので、自分でも意味不明な箇所も多いです。ごめんなさい。

  
  

★ 目的

「A表:T99_社員マスタ」と「B表:t99_社員マスタ002」の内容を(連番列以外の)
「すべての列」で比較して、
「B表:t99_社員マスタ002」から、
「重複しない行」=「A表:T99_社員マスタと一致しない行」=「A表:T99_社員マスタと一致した行以外の行」、
を「B表:t99_社員マスタ002」から取り出す。

※連番列のみ、あるいは、全列を取り出す。

できたら、それを削除する。

汎用的な言い方だと・・・・

A表とB表の内容を(連番列以外の)
「すべての列」で比較して、
B表から、
「重複しない行」=「A表と一致しない行」=「A表と一致した行以外の行」、
を取り出す。

できたら、「抽出されたもの」について何かする。

・・・・という感じになります。
  
  

★ テーブル内容

例えば以下のような感じの内容の表を比較します。

この中では、「河村 加助」さん、「玉田 十夢」さんのレコード(行)が、
2つの表の中で(連番列以外の)全列の内容がまったく同じなので、
それ以外のデータを、「(B表)t99_社員マスタ002」から抽出する・・・、
というかたちになります。
  
  

★ ヒント(不一致の行だけを取り出す定型作業)

A表とB表の内容を(連番列以外の)
「すべての列」で比較して、
B表から、
「重複しない行」=「A表と一致しない行」=「A表と一致した行以外の行」、
を取り出す。

  
  

【不一致な B表のすべての列を表示させる例】

これは、「連番」という列がA表にもB表にもあることが大前提です。この列だけは内容が異なってもいい、という前提です。
(なので、あとから作り足してもOKです。)

なので、もし無ければ、先に、A表とB表の両方に「連番」という列を作ってから
以降のようなSQL文を書いて作業します。
作業は、Microsoft Queryか、VBAで行います。

なお、2つの表を「本記事のような条件で」比べる場合、「毎回・常にこのSQL文でOK」です。

また、今回の例については、
重複チェックをする列が、「列01~列04の4つ」で、
その「すべての列を同時に」、重複しているかどうかを調べます。(連番列以外の列です。)

以下のSQL文ですと、「ON ~ AND ~ AND ~ ・・・」という部分(4行分)が、
重複チェックしている部分です。(「AND」は「かつ」という意味です。)

なお、重複を比較する列の名前は、A表とB表のあいだでは、「全く同じでなくてもOK」です。
列名が異なっていても、列同士の「データ型」と、格納されている値そのものが正常なら大丈夫です。
その場合は、お互い「列01」のところで、異なる列名を書き合います。それでOKです。

逆に、誰かがデータを変にいじってしまい、『 内容がメチャクチャになってしまっている 』ような状況ですと、もし列名が同じであっても・・・、
「エラーになって止まってしまう」か、
「とりあえず動くけど、でも絶対に重複はヒットしない」、
・・・という状況になってしまいます。
(Excelは初期状態では、「入力データのデータ型をそろえたりチェックしたりする機能がまったくといっていいほど働いていない」ので、結果、何でもできてしまい、「データや数式をメチャメチャにし放題」なので、注意が必要です。そこが「Excelはあまりデータ蓄積には向かない」と言われる一番の理由だと思います。ただ、そこさえちゃんと気を付けて、「他の人の自由にさせない」仕組みを追加すれば、Excelでもなんとかシステムめいたものが作れると思います。もちろん、SQLも使えます。)

以上は、定型的な作業なので、
最初のうちは「SELECT」や「FROM」「WHERE」などの意味がわからなくてもOKですが、
でも必ず、少しずつでも意味を学び、SQL文について少しずつでもいいので、
理解を深めていってほしいと思います。

そうするとExcelのフィルタ機能よりもさらに細かい動きをさせることができますし、
何といっても、
「VBAプログラムよりも短い文で」書けますし、
「ワークシート関数よりも分かりやすく複数の条件が書けます」から、
結果的に
「無駄で、本来書かなくていいVBAやワークシート関数を書いたり」、
「意味のわかりにくい修正しにくいVBAやワークシート関数を書く」、
というムダが減ります。
システム業者もVBAよりもSQLを使うので、メンテはもちろん、その他いろんな方面、例えば「高機能化のための外注時」にもコストが抑えられます。

特に、VBAやワークシート関数は「セルの位置」でなんでもやるので、A表やB表の列が増えたり行が増えたりするとそのたびに「何がどうなっているかを考え直して」プログラムをムダに書き換えないといけません。しかもループも使うことも多いのでわかりづらい&間違えやすいです。特に初心者には。=メンテもしにくい、ということでもあります。
でも、SQLを使うと、列名でプログラムが書けますから目的の列のデータがどのセルにあろうが場所が変わろうが そんなことは関係が無く、考える必要がありません。行についても「増えることが前提なので考えなくていい」ですし、ループなんて使わないもんですから、なので(基礎さえわかれば)VBAよりは意味がわかりやすいです。
なので、内容を書き換えるにしても無駄なVBAや無駄なワークシート関数よりは「書き換えやすい」「書き換える箇所が少ない」というメリットがあります。
「一度作ったものを、VBAやワークシート関数よりも "使いまわし・再利用がしやすい" というメリットがある、」=「時間をムダにしないというメリットがある」ということになります。
はっきり言って、SQLを知らずに(使わずに)VBAのループ処理ばかり自慢する人(ループ処理しか書かない人)は「愚かで即戦力にはなりません」。SQLを知ってて、でも状況によってあえてSQLを使わない人は「即戦力になる」と思います。
僕はSQLは得意ではないですが、「何がどうできるか?くらいのおおよそのこと」は知っていますので、ExcelVBAができるだけの人と、SQLもVBA知ってて効率化してくれる人とだったら、後者の方を採用しますし、お給料にも差をつけます。(もちろん、SQLを使って効率化が本当にできれば、ですが。)
もちろん、SQLも万能ではないですからVBAでのループ処理ももちろん「大切なもの」ですが、でも「SQLをまったく知らない」と、すぐに、「無駄・かつ・メンテしにくいループが増える」=無駄な時間コストや金額コストが増える、ということになるので、罪であることは確かなのです。

特に「経営者目線」、「独立する人間目線」、では。

  
  
※補足01:
コードの2行目~9行目(最初の FROMの次から、「AS C表」 の前まで)のカッコの中が
「副問い合わせ(サブクエリとも言います)」と呼ばれる部分となります。
このカッコの中で「重複データの抽出」をしています。
カッコの外で、「その重複以外のデータの抽出」をしています。

※補足02:
最終的には、上記のようなSQL文を書きますが、
重複チェックしたい列が増えるごとに、
「AND (A表.列04 = B表.列04)」の行 以降を、
  AND (A表.列05 = B表.列05)
  AND (A表.列06 = B表.列06)
  AND (A表.列07 = B表.列07)・・・
という感じで増やしていきます。

逆に、「列03と列05だけの同時重複を調べるだけでいい・・・、という場合は、

  ON   (A表.列03 = B表.列03)
    AND (A表.列05 = B表.列05)

という形に減らします。

例えば「氏名の列と市区町村の列だけの同時重複を調べるだけでいい・・・」という場合は、

  ON   (A表.氏名 = B表.氏名)
    AND (A表.市区町村 = B表.市区町村)

という書き方になります。

なお、もし B表側で、本来「市区町村」となるはずの列が「市」という列名になってしまっていたら、

  ON   (A表.氏名 = B表.氏名)
    AND (A表.市区町村 = B表.市)

という書き方になります。

各行の先頭にスペースは必ず入れておきます。
(あとで自動的に適量にカットされますので。)

SELECT、FROM、LIGHT、REFT、その他、などを「句」と呼ぶんですが、その前後は「半角スペースならどれだけ入っていてもOKです。ただし、「全角スペース」が入るとエラーになりますから、絶対に全角スペースは使わないでください。
特に、Webからのサンプルのコピペの場合、なんらかの理由で全角スペースが混ざることがあるので本当に注意してください。命令文が完璧でもエラーが出続けてしまいます。

※補足03:
SQL文の作成に関しては、
テキストエディタやWordなどを利用して、A表、B表、の部分を置換し、
そのあと、列01~列04 も必要に応じて置換します。
そうすれば、作業がラクになるかと思います。
C表は置換しません。
(※VBAで使う場合でも、Microsoft Query、
  あるいはAccessその他で使う場合でも同じです。)

置換では駄目な場合は、
必要に応じて、表(シート側)のほうの列名を手修正で書き換えるか、
SQL文のほうの 列01~列04 の部分を、
現状に合致するように手修正で書き換えます。

なお、B表とA表を逆にして調べたかったら・・・・、
例えば「B表側ではなく、A表側の行をピックアップや削除」
ということをしたかったら、単純に、逆に置換すればいいだけです。
ただ、その場合、両方の表の間で列名が一部異なるような場合は、
それをその状況に合致するように(列名を)手修正する必要があります。
  
  

★ 2つのテーブルの間での重複チェック

4つのフィールドの例

  
  

★ 2つのテーブルの間での不一致データのチェック(副問い合わせの利用)

※元となるテーブルがT99_社員マスタ
 重複データを消したいテーブルがt99_社員マスタ002

カットしたい連番だけを選択して表示。

  
  
カットしたい連番も、氏名その他すべてをも選択して表示。

  
  
===========================================
  
  
★ 参考操作

※ すみません!ミスです!この「参考操作」の項のところだけ、「削除分」を「重複分」に読み替えてください。
(SQL内容も。)

(A)まず「t99_社員マスタ002削除分」クエリを作成

  
  
(B)その「t99_社員マスタ002削除分」クエリをもとに、不一致クエリを作成

  
  
(C)上記の2つのクエリをひとつにまとめる(副問い合わせの利用。)
方法は、まず、(B)のFROM句の「t99_社員マスタ002削除分」の部分を、
(A)の「t99_社員マスタ002削除分」クエリの内容に置き換え、「AS C表」(C表)とし、
RIGHT JOIN 句 や WHERE句 の「t99_社員マスタ002削除分」と記述されたところを
「C」(C表)に書き換えます。

  
  
(D) (C)で、リストアップされた内容が確認できたら、
 「SELECT t99_社員マスタ002.*」の「*」を「連番」に書き換える。

===========================================
  
  
  
  
★ ExcelのMicrosoft Query や、QueryTableオブジェクト+VBA(ODBC等)の場合

※読み込み先のファイルがExcelファイルの場合、テーブル名には「&」をつけて、[ ](あるいはバックスラッシュ)で囲む必要があります。
仮想表の「C表」にもそれをおこないます。

なお、読み込み先のファイルが、『 テキストファイルやAccessファイル、SQL Server など 』でしたら、Microsoft Query やQueryTableオブジェクトでの利用であっても、そのSQL 文のテーブル名には、その処置は要りません。

(この記事の最初にご紹介したようなSQL 文となります。)

参考:『「VBAプログラム」からも、「MicrosoftQueryの画面」からも操作が可能となる、そのための「VBAからのSQLの書き方」や「前提条件」など(概要説明のみ)
  
  
(01)Microsoft Queryの「SQL」ボタン押下の場合

  
  
(02)QueryTableオブジェクト+VBA(ODBC等)の場合(変数利用:Arrey)

比較したい列の数が増える場合、条件の「AND ([A表$].列××× = [B表$].列×××)"」の行が増える(増やす)ような格好となります。
その際は、
  s_SQL02 = s_SQL02 & " ・・・・・"
  s_SQL03 = s_SQL03 & " ・・・・・"
  s_SQL04 = s_SQL04 & " ・・・・・"
の、ところで、それぞれの変数に均等に割り振って(差し込んで)いきます。

" ・・・・・" の中に書く 「AND」の前は「半角の」スペースならいくつ入っていてもOKです。「全角」のスペースはエラーになるので絶対に書かないでください。

なお、逆に条件が少ない時は
  s_SQL02 = s_SQL02 & " ・・・・・"
  s_SQL03 = s_SQL03 & ""
  s_SQL04 = s_SQL04 & ""
といった感じで、どれかの変数は "" にしてしまってもOKです。

===========================================
===========================================
===========================================

例:他ファイルから吸い込み。

「'アクティブシートに結果を表示」のところで、直接、他のファイル(フルパスとパス)を指定しています。(「;DBQ=」のところでフルパスを、「;DefaultDir=」のところでパスを指定しています。)

※実行する前に、必ず前回の結果を列丸ごと、削除してください。
でないと実行する度に結果の表が増えていったり、出力する列数が少ないと、前回の結果と横に合体してしまって「何も変化してない」と勘違いしてしまうことがあるので。

===========================================
===========================================
===========================================

例02:自ファイルデータを利用して吸い込み、自ファイルに。
※実行する前に、必ず前回の結果を列丸ごと、削除してください。
でないと実行する度に結果の表が増えていったり、出力する列数が少ないと、前回の結果と横に合体してしまって「何も変化してない」と勘違いしてしまうことがあるので。

===========================================
===========================================
===========================================

例03:SQLで吸い込む動作を関数化して、自ファイルに。
後述の(イ)や(ロ)の部分だけのように書いていけばOKとなります。
データの抽出だけなら、それだけのコードで済みます。

※実行する前に、前回の結果は「削除なくてもOK」です。そのような対応を関数側でやってありますので。

  
  
(イ)自ファイルの内容を読み込んで自ファイルのシートに結果を表示。

  
  
(ロ)他ファイルの内容を読み込んで自ファイルのシートに結果を表示。