公式アカウントからの投稿が始まります

ACCESSで重複チェックをしたいと思います。

現在は電話番号テーブルだけしかありません。
電話番号のテーブルを主キーを使って重複している場合エラーメッセージを出すというものです。保存ボタンもありません。

Private Sub text電話番号_BeforeUpdate(Cancel As Integer)

If IsNumeric(text電話番号) = False Then '数字チェック。

MsgBox "電話番号は数字で入力して下さい。", vbCritical
Cancel = True ' 処理を取り消します。
Me.Undo

End If

Dim strmsg As String

strmsg = "重複しています"

If Not IsNull(DLookup("[電話番号]", "ダブリチェックテーブル", "[電話番号] = [text電話番号]")) Then

MsgBox strmsg, 16, "ダブリチェック"
Cancel = True '処理を取り消します。
Me.Undo '元に戻します。

Else

Cancel = False '処理を続行します。

End If

End Sub

これに、企業名と出発日という項目を増やしたいと思います。
ですが、何万とある電話番号を一気に入力して調べているので、一回一回企業名と出発日を入れていると生産性が落ちます。
ですので、企業名と出発日は最初の入力だけで次のレコードに移動してを継続させたいのです。そして電話番号以外にカーソルを行かないようにしたいです。

何か良い方法があればご教授お願いします。
ちなみにいろいろ自分なりに試したのですが、重複してエラーを出した場合に企業名にカーソルが飛んだししてうまくいきませんでした。

A 回答 (4件)

BeforeUpdateイベントで処理せずに、電話番号のExitイベントで処理した方がよいでしょう。

たとえば企業名入力に移行しようとした瞬間。重複があれば電話番号にフォーカスを戻す。
それから重複があった場合、既に登録済み番号の企業名を表示する必要などないのでしょうか?タイプミスによる重複かどうか確認できた方がよいと思うのですが。
    • good
    • 0

No.2です。


まず、前回の修正から(汗)

新規レコードの入力のみの前提なら、前回のままでも問題ないのですが、
現実的には入力完了後の訂正もあるはずですので、DCountの3番目の引数に
「現在編集中のレコード以外」の条件も追加しておく必要があります。
(同じ値での上書時に、編集対象レコード自身によってDCountの結果が
 「1」になってしまい、Escキーで編集を取り消すしかなくなる)

具体的な方法としては、現在のレコードを特定できるフィールド(オート
ナンバーなどの非重複のもの)、たとえば「ID」フィールドがあれば、
「"[電話番号]=[text電話番号]"」を
「"[電話番号]=[text電話番号] And [ID]<>[textID]"」
といった条件に変えます。


> ウインドウが出て、OKをクリックしたら次の新しいレコードに移動する

レコード移動して構わないのでしたら、更新後イベントで対応するのが
よいかと思います。
(更新前イベントと違って、全く別の値の代入も可能な分、自由度が高いので:
 たとえば値を削除する代わりに「重複により取消」等の文字列を入れることも
 可能(text電話番号の連結フィールドがテキスト型だった場合))

Private Sub text電話番号_AfterUpdate()
On Error Goto エラー処理

  Dim StrMsg As String, StrSQL As String

  If IsNumeric(text電話番号) = False Then
    StrMsg = "電話番号は数字のみを入力します。"
  ElseIf DCount("*","ダブリチェックテーブル", _
      "[電話番号]=[text電話番号] And [ID]<>[textID]") Then
    StrMsg = "電話番号が重複しています。"
  Else
    Goto 終了処理
  End If

  StrMsg = StrMsg & String(2, vbCrLf) & "入力は取り消されます。"
  MsgBox StrMsg, vbCritical, "確認"

  '「電話番号エラー」テーブルに、入力しようとした値をSQLで記録
  '(上記テーブルは予め用意してある前提:フィールド=ID,電話番号)
  '※電話番号は市外局番対応を考慮してテキスト型を想定(→「'」括り)※
  StrSQL = "Insert Into 電話番号エラー (ID, 電話番号)" & vbCrLf _
      & "Select " & textID & ", '" & text電話番号 & "';"
  DoCmd.SetWarnings False
  DoCmd.RunSQL StrSQL  '追加クエリを作成しておいてそれを呼んでも可

  '編集前の値に戻します。
  text電話番号 = text電話番号.OldValue

終了処理:
  'エラー時にSetWarnings(警告表示)がFalseのままになるのを
  '避けるため、常にこの処理を通してから終了させる
  DoCmd.SetWarnings True
  Exit Sub
エラー処理:
  MsgBox Err & ":" & Error$, , Me.Name & " text電話番号"
  Resume 終了処理
End Sub


・・・以上です。
なお、Shiftキー+Tabキーで前レコードへの移動になる場合も想定して、
レコード移動のコードは入れていません。
    • good
    • 0

> 電話番号以外にカーソルを行かないようにしたい



フォームをデザインビューで開き、カーソルを移動させたくない
コントロールのプロパティシートを開いて、『データ』タブの
『使用可能』を「いいえ」にするか、『その他』タブの『タブストップ』
を「いいえ」にするのもひとつの方法です。


また、入力規則に反する文字を入力した時でも、部分的なタイプミスなら
その部分だけを修正したい、という場合もあるかと思いますので、
「Me.Undo」をしてしまうよりは、ユーザーが取り消し/修正を選択可能に
した方がよいのではないでしょうか(取り消しはキーボードのEscキーで対応)。

Private Sub text電話番号_BeforeUpdate(Cancel As Integer)

  Dim StrMsg As String

  '入力規則の合否判断
  If IsNumeric(text電話番号) = False Then
    StrMsg = "電話番号は数字のみを入力します。"
  ElseIf DCount("*","ダブリチェックテーブル","[電話番号]=[text電話番号]") Then
    '上記条件式は、「0」以外(=重複あり)は「True」とみなされます。
    StrMsg = "電話番号が重複しています。"
  Else
    Exit Sub  '取り消す必要がないので処理をそのまま通します。
  End If

  'メッセージを表示して処理を取り消し
  StrMsg = StrMsg & String(2, vbCrLf) _
        & "入力を取り消す場合は、Escキーを押して下さい。"
  MsgBox StrMsg, vbCritical, "確認"
  Cancel = True

End Sub


> 企業名と出発日は最初の入力だけで次のレコードに移動してを継続させたい

こちらは、フォームの更新後イベントで、各コントロールの既定値を
切り替えてやるのがよいかと思います。

Private Sub Form_AfterUpdate()

  Dim StrDef As String

  '企業名の既定値を設定
  text企業名.DefaultValue = Chr(34) & text企業名 & Chr(34)

  '出発日の既定値を設定
  '(日付型を想定して「#」括り。Nullの場合はエラーとなるため切り分け)
  If IsNull(text出発日) Then StrDef = "" Else StrDef = Chr(35) & text出発日 & Chr(35)
  text出発日.DefaultValue = StrDef

End Sub


・・・以上、参考まで。
    • good
    • 0
この回答へのお礼

思っていたことができました!
ありがとうございます!

一つだけ質問させてください。

重複した場合にエラーメッセージを出し、「確認」したらESCを押さなくてもそのまま処理を続行できるようにするにはどう書いたらいいでしょうか?ウインドウが出て、OKをクリックしたら次の新しいレコードに移動する感じです。そして、重複した電話番号は貼り付けエラーを自動形成してそこに入る感じです。

宜しくお願いします。

お礼日時:2009/03/17 11:08

質問に対する直接的な回答ではないですが、何かのきっかけになればと思い書いてみます。

どのようなものを作っているのかよくわかりませんが、私が作るなら、

電話番号を入力しながら(6-7桁目くらいで対象件数がある程度絞られた段階で

対象企業名をリスト1に表示させ

登録していなければ別フォームをモーダルで開き、企業情報を登録させる。(登録時には企業名での2重登録のチェックも行う) 
登録してあれば、リスト1の該当レコードをクリックする際に、その電話番号によって登録されている、「レコード(出発日を含む)」をリスト2に表示させる。 
その画面から、新規「レコード」を追加させる方法を作り、登録の際に2重登録のチェックを行う。

のような具合に作るかも。 
テーブルとしては、「企業リスト」と
出発日を含む「何らかのリスト」は別に作ると思います。
電話番号は、企業リストのインデックスとして利用する。

レコードの検索については、dlookupを使わず、ADOでSeekを使うか、クエリ(select文)で該当レコードを探すかしてパフォーマンスを稼ぐと思います。

何万というレコードを扱う場合は同時ユーザーの数によってはアクセス以外のdbを使うこともあると思います。 (フロントエンドはアクセスでもかまいません)

まあ、今作っているものを簡単に変えるなら、テキストボックスのプロパティの「使用可能」を一時的に変更することによって解決できそうな気もします。
    • good
    • 0

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