単純なキーブレイク処理処理のはずなのですが、ロジックが構築できません。
対称はテーブルで、Noはレコードの識別子です。
Noが連続しない場合(固有のレコード)、は削除したいです。
ループ処理の中で、1,2,3、1、1、1,2とカウントを数えて、
カウントが1だったら削除というようなロジックになるだろうと考えているのですが、
キーが切れた時に、
直前まで持っていたカウントが1なら
rs.MovePrevious、
rs.delete、
rs.MoveNext
カウント初期化にようなロジックではどうもうまくいきません。
N0 Cnt
107 1
107 2
107 3
110 1・・・削除
111 1・・・削除
123 1
123 2
アドバイスよろしくお願いいたします。
コードはこちらです。
Funcion keyBreak()
Dim rs As DAO.Recordset
Dim PreNo As Long
Dim strSQL As String
strSQL = "select * from Mtbl_社員 ORDER BY No"
Set rs = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset, dbFailOnError)
cnt = 0
Do Until rs.EOF
If PreNo = rs!No Then
cnt = cnt + 1
Else
If cnt = 1 Then
rs.MovePrevious
rs.Delete
rs.MoveNext
End If
PreNo = rs!No
cnt = 1
End If
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
End Function
No
は Access SQL における予約語の 1 つであり、Yes/No 型( VBA における Boolean 型)の False 値、
数値型の 0 と同義です。
(最初からそんな名前はつけない方がよいですが)
フィールド名として識別させたいのであれば、[]で囲ってください。
テーブル[Mtbl_社員]の主キーはフィールド[No]である、
という意味だとして、
これはどのテーブルのレコードのことをおっしゃっているのでしょうか。
[No]が主キーであれば、[No]の値が他のレコードと重複するレコードを
テーブル[Mtbl_社員]に格納することは出来ないはずですが。
実際のコードとは違いまして、簡略化したコードを載せています。
ご指摘の通り、Noは使っていません。
Noは社員コードの意でして、主キーではありません。
Mtbl_社員(現所属)の社員コードとご理解ください。
簡易チェックのためのテンポラリーの抽出で、所属が専任ではなく、兼任の人を抽出したいという意図があります。
一応、このコードでも削除自体はできていまして、
ただ、あまりいいやり方ではないのかなという懸念と、
最終レコードの社員が1レコードのみの場合の削除ができていないという詰めが甘いです。
ループを回す前に、Movelastをして、最終レコードの社員が1レコードの場合は削除、
MoveFirstとするようなお粗末なやり方を考えました。
では、以下[社員コード]と読み替えます。
単純に「[Mtbl_社員]に格納されているレコードのうち、
[社員コード]の値が同一であるレコード同士を 1 つのグループとみなし、かつ
『レコード件数が 2 件以上であるグループ』に含まれるレコードを抽出したい」
ということでしょうか。
例えば、以上のような選択クエリを作成なされば同様の結果が得られるはずです。
抽出されたレコードに対し、更に何らかの編集操作を行いたい場合は、
上記の選択クエリの結果を同一構造の一時テーブルに出力するように
なさればよいでしょう。
はいその通りでして、当初SQLでやろうとして断念し、作業テーブルに書き出したものを、
VBAで削除するしかできませんでした。
すごいですね。これでできてしまうのですか!
こちらを採用させていただきます。
下記のSQLでもskさんのクエリと同じ結果を得られます。
メリットとしては、このクエリの場合は編集操作が可能です。
デメリットとしては、データ数が多いとskさんのより重くなる可能性があります。
ありがとうございます。
最初、Dcountが直感的にはやりやすいので思い浮かびましたが、
これまでの経験上、D系を使うとかなりストレスフルなのを感じていましたので、
レコードが2万件くらいあるので、やりずらかったです(なので試してもいなかったです)。
HAVINGのほうは、それほどストレスなく使えました。
抽出したデータの閲覧だけならskさんのサブクエリを使う方法でいいと思います。
更新する必要があり、かつ、ストレスなく使いたいという場合は、私なら下記の方法をとります。
下記のような[社員コード]のみの一時テーブルを作成しておきます。
テーブル名: Tmp_兼任社員コード
フィールド: 社員コード (主キー)
下記のクエリを順次実行します。
削除クエリ: 一時テーブルのデータを削除
追加クエリ: 一時テーブルに兼任社員コードを追加
兼任社員抽出クエリ
やっていることはskさんのSQLのサブクエリ部分を一時テーブルにしただけです。
これでストレスフリーで編集作業も可能になります。
確かにです、一時テーブルに社員コードだけを格納してINNER JOINですね。
パフォーマンスを落とさず、クエリが読み取り専用になってしまう場合などは、有効ですね。