• 締切済み

ACCESS重複のチェック

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 これに、企業名と出発日という項目を増やしたいと思います。 ですが、何万とある電話番号を一気に入力して調べているので、一回一回企業名と出発日を入れていると生産性が落ちます。 ですので、企業名と出発日は最初の入力だけで次のレコードに移動してを継続させたいのです。そして電話番号以外にカーソルを行かないようにしたいです。 何か良い方法があればご教授お願いします。 ちなみにいろいろ自分なりに試したのですが、重複してエラーを出した場合に企業名にカーソルが飛んだししてうまくいきませんでした。

みんなの回答

noname#182251
noname#182251
回答No.4

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

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

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キーで前レコードへの移動になる場合も想定して、 レコード移動のコードは入れていません。

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

> 電話番号以外にカーソルを行かないようにしたい フォームをデザインビューで開き、カーソルを移動させたくない コントロールのプロパティシートを開いて、『データ』タブの 『使用可能』を「いいえ」にするか、『その他』タブの『タブストップ』 を「いいえ」にするのもひとつの方法です。 また、入力規則に反する文字を入力した時でも、部分的なタイプミスなら その部分だけを修正したい、という場合もあるかと思いますので、 「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 ・・・以上、参考まで。

Armadillo5
質問者

お礼

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

  • ShowMeHow
  • ベストアンサー率28% (1424/5027)
回答No.1

質問に対する直接的な回答ではないですが、何かのきっかけになればと思い書いてみます。どのようなものを作っているのかよくわかりませんが、私が作るなら、 電話番号を入力しながら(6-7桁目くらいで対象件数がある程度絞られた段階で ↓ 対象企業名をリスト1に表示させ ↓ 登録していなければ別フォームをモーダルで開き、企業情報を登録させる。(登録時には企業名での2重登録のチェックも行う)  登録してあれば、リスト1の該当レコードをクリックする際に、その電話番号によって登録されている、「レコード(出発日を含む)」をリスト2に表示させる。  その画面から、新規「レコード」を追加させる方法を作り、登録の際に2重登録のチェックを行う。 のような具合に作るかも。  テーブルとしては、「企業リスト」と 出発日を含む「何らかのリスト」は別に作ると思います。 電話番号は、企業リストのインデックスとして利用する。 レコードの検索については、dlookupを使わず、ADOでSeekを使うか、クエリ(select文)で該当レコードを探すかしてパフォーマンスを稼ぐと思います。 何万というレコードを扱う場合は同時ユーザーの数によってはアクセス以外のdbを使うこともあると思います。 (フロントエンドはアクセスでもかまいません) まあ、今作っているものを簡単に変えるなら、テキストボックスのプロパティの「使用可能」を一時的に変更することによって解決できそうな気もします。

関連するQ&A

  • ACCESSの重複チェックについて

    顧客データをACCESS2003にて作成しています。 フォームにてVBAを用いて重複チェックをしているのですが、件数が多いせいかチェックに時間が掛かっております。(入力済件数は10万は超えております。) テーブル(T_顧客管理)よりチェック出来るようにしており、チェックのフィールドは「住所」にしております。 Private Sub 住所_BeforeUpdate(Cancel As Integer) If DCount("住所", "T_顧客管理", _ "住所='" & Me!住所 & "'") > 0 Then Beep MsgBox "既存のデータと同じ住所が入力されました! " & _ "別の値を入力してください。", _ vbOKOnly + vbExclamation, "重複エラー" Cancel = True Me.Undo End If End Sub 上記の式を入れておりますが、別の方法(式)にて上記と同じ内容にてチェック出来る式があれば教えていただきたいと思いますので、宜しくお願い致します。

  • ACCESSで重複チェック後にフォーカスを移動したい

    Private Sub 会社名_AfterUpdate() ACCESS2003です。 フォーム上で入力後(更新後処理)に重複チェックをしています。 重複したときにエラーメッセージを出してフォーカスさせたいのです。 エラーメッセージまでは上手くいくのですが、フォーカスが移動してくれません。 どこが悪いのでしょうか? Private Sub 会社名_AfterUpdate() Dim i As Integer i = DCount("*", "tbl取引先", "会社名 ='" & Me.会社名 & "'") If i = 1 Then MsgBox [会社名] & " は登録済みです。" Me![会社名].SetFocus Cancel = True End If End Sub よろしくお願いします

  • VB6 重複チェックについて

    お世話になります。 次の処理をVisual Basic6.0で教えてください。 1.Text1にキー入力した値をコマンドボタンクリックすると、Text1の値を保存します。 2.次にText1に新たに入力してコマンドボタンクリックで前項で保存した値と重複して   いないかチェックして重複無しならText1の値を保存します。 3.Text1に新たに入力して・・・・重複チェックして・・・・ といった具合に保存する値と重複チェックする対象の値がどんどん増えていきます。 さすがに10,000件はいかないですが。 保存先は読み書き込みの時間も考慮してVB内のTextBOXが第1希望、外部のtxtファイルやcsvファイルは第2希望としたいです。 If Text1=保存値 Then  処理 else  処理 End If 保存値をText2として行いましたが、完全一致でないとダメでした。 入力値:保存値=1:n(入力値が複数の保存値と重複したかどうか)が知りたいです! お手数おかけしますが、何卒よろしくお願いします。

  • Access2000でレコードの重複チェックをするとエラーに

    ボタンをクリックすると、「品名」「色番」「ロット」「枝番」「巾」の重複が無いかチェックして、重複があればエラーテキストを表示させたいのです。 下記のコードで動かすと、 「エラー'91':オブジェクト変数またはWithブロック変数が設定されていません」と出ます。 どこが問題でしょうか? 教えて頂けると幸いです。 Private Sub 重複チェックボタン_Click() Dim Rs As ADODB.Recordset Dim strSQL As String strSQL = "" strSQL = strSQL & " Select * From 変更ロットテーブル " strSQL = strSQL & " Where 品名 = '" & Forms!変更ロット入力チェックフォーム!品名 & "'" strSQL = strSQL & " And 色番 = '" & Forms!変更ロット入力チェックフォーム!色番 & "'" strSQL = strSQL & " And ロット = '" & Forms!変更ロット入力チェックフォーム!ロット & "'" strSQL = strSQL & " And 枝番 = '" & Forms!変更ロット入力チェックフォーム!枝番 & "'" strSQL = strSQL & " And 巾 = '" & Forms!変更ロット入力チェックフォーム!巾 & "'" Rs.Open strSQL, CurrentProject.Connection If Rs.EOF = False Then If MsgBox("重複ロットが存在します!", vbOKCancel) = vbOK Then Cancel = True End If End If End Sub

  • ACCESSのフォーム

    ACCESSのフォームでデータを入力しています。 既に入力したデータを誤って上書きしないように、更新前処理で下記のコードを入れました。 Private Sub 単価_BeforeUpdate(Cancel As Integer) If MsgBox("変更を保存しますか?", vbYesNo) = vbNo Then Me.Undo End If End Sub 入力済のデータを上書きする時はこの方法で良いのですが、新規に入力する時にも同じように確認メッセージが出てしまいます。 新規入力の時には確認メッセージを出さない方法があったら教えて下さい。 よろしくお願いします。

  • MSアクセス2010と2003

    アクセスの帳票フォームで入力用チェックボックスが84個(ck1からck84)あります。表示データは10個程度ですが、このチェックマークの更新前処理で、同じ場所へのダブリが発生しないような処理をしています。フォームフッターにテキストボックスを84個配し(Text1~Text84)、Text1はCk1の合計を、Text2はCk2の合計を出すようにしておき、CK1の更新前処理に Select Case Me![Text1] Case "" If (Me![ck1]) = -1 Then MsgBox "Please wait" Cancel = True Me.Undo End If Case "-1" If (Me![ck1]) = -1 Then MsgBox "Already used." Cancel = True Me.Undo End If End Select またチェックマークを入れることにより、計算処理をして結果をチェックボックスの下に表示しているためme.Refreshを更新後処理に入れております。アクセス2003+Office2003SP3では問題なく動きますが、アクセス2003+Office2003SP1、アクセス2010+Office2010SP1では次のチェックボックスにチェックを入れるのに5~6秒程掛かります。(アクセス2003+OfficeSP3ではチェックマークをつけて次のチェックマークを付けるのに待ち時間はありません。)したがって使い物になりません。何か考えられることはありますでしょうか。

  • 重複チェック

    マクロ初心者です。(エクセル2003使用) A列の管理番号が重複していたら、C列に☆をつけるようなマクロを作りたいのですが、うまくできません。 すみませんが、どなたか教えてください。 (Sheet1) A          B      C アカ154-7 アカ226-9        ☆ アカ446-0 アカ675-4        ☆ アカ669-8 アカ226-9        ☆ アカ118-5 アカ675-4        ☆ アカ226-9        ☆ (マクロ) Sub 重複() Dim 管理番号 As Variant Dim motoSht As Worksheets Dim セル範囲 As Range With Sheets("Sheet1") 管理番号 = Sheet2.Range("A2").Value Set セル範囲 = Range("A2:B65536").CurrentRegion.Find(管理番号, , LookAt:=xlWhole) If 同じ管理番号があったら Then            Range("A").CurrentRegion.Offset(2) = ☆ ElseIf Not セル範囲 Is Nothing Then MsgBox "管理番号は、重複していません" End If End With End Sub ご回答よろしくお願いいたします。

  • 重複チェック

    あるシートに値を入れた時、そのシートのA1:Z80の範囲内で重複する値が既存するかどうか調べたいです。 下記のコードを試すと、どの値を入れても既存すると帰ってきます。 入力した値自身を見つけて重複だと言っている気がするのですが、どのように対処すればいいのか教えてほしいです。 Private Sub Worksheet_Change(ByVal Target As Range) Dim myCell As Range For Each myCell In Sheets("居場所").Cells If Target.Value = myCell.Value Then MsgBox "この名前は既に存在しています。", vbOKOnly + vbExclamation Exit Sub If myCell.Address = "$Z$80" Then Exit Sub End If Next End Sub

  • エクセルテーブルをアクセステーブル取込む

    エクセルで作成したテーブルデータを取り込むときに余分に空白のレコードが取り込まれてしまうんですが原因が分かりません。 下記コードで処理してます。 Dim strac As String Dim strxls As String Dim strrange As String Dim strMsg As String strac = "T_障害票マスタ" 'Accessテーブルを指定します。 strxls = テキスト0 'エクセルファイルを指定します。 strrange = "T_障害票!" 'データ入力のシート名とセル範囲を指定します。 strMsg = "エクセルファイル" & strxls & " を、Accessファイル " & strac & _ "として、データ入力を行います。" & _ "よろしければ、OKをクリックして下さい。" 'MsgBoxのメッセージ If strxls = "" Then MsgBox "ファイルを選択して下さい。" 'テキストボックスの確認 Exit Sub End If 'DoCmd.DeleteObject acTable, strac 'テーブルを削除します。 If MsgBox(strMsg, vbOKCancel, "import") = vbOK Then '最初のデータをフィールド名として使います。 DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel8, _ strac, strxls, True, strrange MsgBox "インポートは、正常に完了しました。" End If Exit Sub なお取り込むテーブルデータはフィールド行を抜かして常に1レコードだけです。 アクセスでは既存のテーブルに保存してます。 詳しい方お願いします。

  • Accessで、重複データのチェック

    Access2000で、テーブル更新用のフォームを作っています。既に登録済みのレコードを編集する、あるいは新規のレコードを登録する機能を持っています。 そのフォーム上のテキストで、既存レコードを編集、あるいは追加したい新規レコードを入力して、テキストからフォーカスを離すと、入力したレコードが既存のレコードと重複していないか、チェックを走らせています。重複している場合は、適切なレコードが入力されるまで、そのテキストからフォーカスを離さないようにしています。が、やはりそのようなチェックの仕方では、既存のレコードに一度手を加えてしまうと、手を加える前のレコードに戻すことは出来ません。 たとえば、"東京都"というレコードが登録済みである→"東京都"を"北海道"に変える→やっぱり"東京都"というレコードに戻す→重複チェックにひっかかり、フォーカスもそこから離せない状態である→元のレコードにはもう戻せない、とにかく"東京都"と異なる値で登録するしかない。。。という具合です。以下の関数を、更新前処理でよんでいます。どなたか、よいアドバイスをください。お願いいたします。 Function ChkInp(pCntrl As Control, _ pClmName As String, _ pCourt_Cd As String) As Boolean   Dim wSQL As String ChkInp = False wSQL = "" wSQL = "select AREA_CD from COURTED_XXT009" wSQL = wSQL + " where COURT_CD = '" & pCourt_Cd & "'" wSQL = wSQL + " and " & pClmName & " = '" & pCntrl & "'" Set rst = CurrentDb.OpenRecordset(wSQL, , acReadOnly) If rst.EOF() = False Then ChkInp = True End If End Function