アクセスのMoveLastの使い方について
- アクセスでリストを登録するツールを作成しています。
- フォームを開く際に、IDのフォームに自動的にID番号を採番したいです。
- しかし、4番目のデータを登録する際にIDが表示されません。原因を教えてください。
- ベストアンサー
アクセスのMoveLastの使い方について
初めてアクセスでツールを作っています。 リストを登録するツールを作っており、フォームに入れた情報を 「テーブル」に登録する仕様となっております。 フォームを開く際、自動的にIDのフォームにID番号を採番したいです。 ID番号はリストを登録する「テーブル」を参照し、既存のレコードの最後の行を検索し 最後の行に+1をした番号を振るようにしました。 下記のようにプログラムを組み、最初のID:1、2、3まではフォームを開いた際に自動的に採番できました。 ところが次の4番目のデータを登録する際にフォームを開くと 何故かIDは3のまま表示されてしまいます。 デバックしたところ、Debug.Print rs!ID の箇所は何故か数字が2が入っております。 MoveLast でレコード末尾を参照しようとしているのですが、 何故か末尾であるはずの3にはなりません。 アクセスでこのようなツールを作るのは初めてになるため、原因がわかる方お願い致します。 Private Sub Form_Load() 'フォーム読み込み時にID番号を付与 Dim rs As New ADODB.Recordset Me.ID.Value = Null rs.Open "テーブル", CurrentProject.Connection If rs.EOF = True Then Me.ID.Value = 1 Else rs.MoveLast Debug.Print rs!ID Me.ID.Value = rs!ID.Value + 1 End If rs.Close End Sub
- Visual Basic
- 回答数1
- ありがとう数1
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
1、一般的な採番手法。 私は、テーブル「主キー管理表」や「id管理表」等を用意して管理するんだろうと認識しています。 Public Function NewID(ByVal strIDName As String) As Long On Error GoTo Err_NewID Dim N As Long Dim strSQL As String Dim cnn As ADODB.Connection Dim rst As ADODB.Recordset Set cnn = CurrentProject.Connection Set rst = New ADODB.Recordset strSQL = "SELECT final_value FROM id管理表 WHERE id_name='" & strIDName & "'" cnn.Errors.Clear cnn.BeginTrans With rst .Open strSQL, _ cnn, _ adOpenDynamic, _ adLockOptimistic If Not .BOF Then N = .Fields(0) + 1 .Fields(0) = N .Update End If End With cnn.CommitTrans Exit_NewID: On Error Resume Next rst.Close cnn.Close Set rst = Nothing Set cnn = Nothing NewID = N Exit Function Err_NewID: N = -1 If cnn.Errors.Count > 0 Then ErrMessage cnn.Errors(0), strSQL cnn.RollbackTrans Else MsgBox "プログラムエラーが発生しました。システム管理者に報告して下さい。(NewID)", _ vbExclamation, " 関数エラーメッセージ" End If Resume Exit_NewID End Function 2、安直な採番手法。 それは、テーブルの最後のレコードの列[id]の値ではなく最大値を求める手法。もちろん、列[id]で逆順に ORDER BY して先頭のレコードを参照する手もあります。しかし、安直な普通のやり方は最大値を求める手法です。 Public Function DBLookup(ByVal strQuerySQL As String, _ Optional ByVal ReturnValue = Null) As Variant On Error GoTo Err_DBLookup Dim DataValue Dim rst As ADODB.Recordset Set rst = New ADODB.Recordset With rst .Open strQuerySQL, _ CurrentProject.Connection, _ adOpenStatic, _ adLockReadOnly If Not .BOF Then .MoveFirst DataValue = .Fields(0) End If End With Exit_DBLookup: On Error Resume Next rst.Close Set rst = Nothing DBLookup = IIf(Len(DataValue & ""), DataValue, ReturnValue) Exit Function Err_DBLookup: MsgBox "SELECT 文の実行時にエラーが発生しました。(DBLookup)" & Chr$(13) & Chr$(13) & _ "・Err.Description=" & Err.Description & Chr$(13) & _ "・SQL Text=" & strQuerySQL, _ vbExclamation, " 関数エラーメッセージ" Resume Exit_DBLookup End Function (注意)テーブルの並びは、必ずしも登録順、あるいは主キー昇順ではない。その状況は、変化する。 *********************** PS、主キーの追加、参照とCnnExecute() *********************** ? CnnExecute("INSERT INTO id管理表 VALUES ('Test2', 2);") True ? DBLookup("final_value", "id管理表", "id_name='Test2'") 2 ? CnnExecute("INSERT INTO id管理表 (id_name, final_value) VALUES ('Test3', 3);") True ? DBLookup("final_value", "id管理表", "id_name='Test3'") 3 ? CnnExecute("DELETE FROM id管理表 WHERE id_name='Test2';") True ? DBLookup("final_value", "id管理表", "id_name='Test2'") NULL ? CnnExecute("DELETE FROM id管理表 WHERE final_value=3;") True ? DBLookup("final_value", "id管理表", "id_name='Test3'") NULL このように私はSQL文を実行する関数(CnnExecute、)でもって主キーの参照、追加を行っていました。 Public Function CnnExecute(ByVal strSQL As String) As Boolean On Error Goto Err_CnnExecute Dim isOK As Boolean Dim cnn As ADODB.Connection isOK = True Set cnn = CurrentProject.Connection With cnn .Errors.Clear .BeginTrans .Execute strSQL .CommitTrans End With Exit_CnnExecute: On Error Resume Next cnn.close Set cnn = Nothing CnnExecute = isOK Exit Function Err_CnnExecute: isOK = False If cnn.Errors.Count > 0 Then ErrMessage cnn.Errors(0), strSQL cnn.Rollbacktrans Else MsgBox "プログラムエラーが発生しました。" & _ "システム管理者に報告して下さい。(CnnExecute)", _ vbExclamation, " 関数エラーメッセージ" End If Resume Exit_CnnExecute End Function
関連するQ&A
- 自前採番処理について
Access2013で、自前で採番処理をスル場合 以下のどちらが正しいでしょうか? 1) フォームの保存ボタンで、採番管理テーブルを参照して、現在の主キーのID番号を取得して、それに+1したものを採番管理テーブルに保存し、エラーがなければ、画面にセットして保存。 2) フォームのレコードソースのID番号の最大値を取得して、それに+1加算したものを採番管理テーブルに保存し、エラーがなければ、画面にセットし保存。 1) 2)どちらも、採番管理テーブルに+1した番号を保存する時にエラーが起きたら、画面は Me.Undoする。 よろしくお願いします。
- ベストアンサー
- その他(データベース)
- Accessでメイン、サブフォームへの入力について
accessほぼ初心者です。 取引先の会社情報を管理するために、access2007で顧客管理を作成しています。現在、取引先本社情報とその支店情報を登録するフォーム「会社登録フォーム」を作成していますが、次のようなことで困っています。 <問題としていること>: 「サブフォーム」をクリックした瞬間に、テーブルにレコードが追加されてしまう。 <改善したいこと>: 本社テーブルの会社名が未入力ならば、上記の操作でレコードを追加しない。(会社名に主キーは設定していません。) <会社登録フォームの環境>: 会社の本社情報をメインフォーム、その会社の支店情報をサブフォームに、単票形式のタブコントロールで複数画面にして支社ごとに分けて入力できる登録フォームを作成しました。本社テーブルの会社IDを主キーに、支店テーブルの支店IDを主キーにしてリレーションシップを設定しています。 <会社情報の入力に関して行っていること>: ・メインフォームに「新規」「更新」「削除」ボタンを設置。 ・新規ボタンでメインフォームの「会社ID」に自動採番。 ・会社(本社)名がないと困るので、未入力の状態で「新規」「更新」及び「サブフォーム」をクリックされた際に「会社名が未入力です。」のメッセージを表示され「OK」で元の状態にもどります。 ・会社(本社)名が入力済みならば、「更新」ボタンで、メッセージ「OK」「キャンセル」が表示され、「OK」ならば本社テーブルにレコードが追加され「キャンセル」ならばそのままの状態になります。 上記の<問題としていること>の補足ですが、新規ボタンで新規登録フォームに会社IDが自動採番(末番)されるのですが、「会社名」を入力せず、先にサブフォームの支店情報から(タブ名「支店(1)」)入力しようとした場合、「会社名が未入力です。」のメッセージを表示されますが、この時点で本社テーブルに、この採番でレコードが追加されてしまいます。入力者がそのまま会社名(本社)から入力するも、途中でキャンセルした場合、再度新規登録をする際、登録フォームの自動採番がキャンセルされた採番の次の番号になります。 キャンセルされた会社情報空白のレコードができるということになります。これを回避したいのです。 出来るだけ詳細をとおもい説明が長くなりましたが、よろしくお願いいたします。
- ベストアンサー
- その他(データベース)
- Accessでの質問
ID ----- 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A このようなテーブルがあり、フォームにいくつかのテキストボックスと登録というコマンドがあります。登録ボタンをクリックしたときtxtidというテキストボックスに何も入力されていないとき上のテーブルを参照してIDを採番し、登録できるようにするにはどうすればいいですか?ちなみIDコードの登録は16進数で登録できるようになっています。上の場合だと000Bを採番したいのです。仮に0007がないときは0007を採番したいんですが…初心者なので本当に困っています。お願いします。説明不足でわかりにくい時は質問していただければ大変助かります!
- 締切済み
- その他(データベース)
- ACCESS ADOのMovePreviousについて
毎度お世話になっております。 ACCESS2003を使用しています。 ACCESS ADOにて、レコードセットがeofになった後、 MovePreviousをし、MoveNextをし、 さらにもう一度MovePreviousをすると、 最終レコードの一つ前に戻ってしまいます。 テーブル1 フィールド1 フィールド2 1 あ 2 い 3 う 4 え 5 お コード Sub test() Dim cn As New ADODB.Connection Dim rs As New ADODB.Recordset Set cn = CurrentProject.Connection rs.Open "select * from テーブル1 order by フィールド1", cn, adOpenDynamic, adLockReadOnly Do Until rs.EOF rs.MoveNext Loop rs.MovePrevious Debug.Print rs.Fields("フィールド1").Value rs.MoveNext rs.MovePrevious Debug.Print rs.Fields("フィールド1").Value rs.Close: Set rs = Nothing cn.Close: Set cn = Nothing End Sub 一度目のdebug.printは5に、 二度目のdebug.printは4になります。 このような仕組みなのでしょうか。 ご教授お願いいたします。
- ベストアンサー
- その他(データベース)
- Access アクセス VBA レコード追加
Access フォームからのレコードの追加方法を教えてください。 テーブル1 ・ID(主キー) ・窓口 ・コストセンター ---------- テーブル2 ・コストセンター(主キー) ・目的 ---------- リレーションシップ テーブル1のコストセンターとテーブル2のコストセンターを一対多 ---------- メインのフォームに”ID”を入力したときにテーブル1に一致するレコードがない場合、新規登録用のフォームが表示されるようになっています。 新規登録用のフォームにレコードを入力してもテーブルに反映されません。 新規登録用のフォームは下記のように作成しています。 また、フォームに”コストセンター”を入力したときに入力したレコードがテーブル2にあっても自動で”目的”が表示されません。 メインフォームにはサブフォームで各テーブルが表示されています。 フォーム ・ID(初期値•••メインで入力したID) ・窓口 ・コストセンター ・目的 ・コストセンター(非表示) 上から順に ・テーブル1 ・テーブル1 ・テーブル2 ・テーブル2 ・テーブル1
- 締切済み
- Access(アクセス)
- Access EOFの判定がうまくいかない
お世話になります。 Access2010 テーブルのEOFの判定がうまくいきません。 If TMP.EOF = False Then MsgBox "EOFではありません" Else MsgBox "EOFです" End If TMPには1レコードありますが、なぜかTrueになってしまいます。 なお、TMP.MoveLastしてもエラーにならず、その後、イミディエイト ウィンドウで?TMP.EOFとしてみると、Falseが返ってきます。 本来であればEOFでMoveLastするとカレントレコードが無い旨のエラーに なるかと思うので、EOFではないと思うのですが。。 どのようなことが考えられますでしょうか。 <TMPについて> ・(訳あって)主キーは設けておりません。 ・0レコードか1レコードです。1レコード以上になることはありません。 ・TMPはあるフォームのレコードソースとしています。 ※フォーム上の登録ボタンが押されたら、フォームのレコードソースを ""としフォームを閉じます。このタイミングでTMPにレコードが生成 されます。 上記の判定処理は、フォームを閉じた直後に行っています。 ご教示の程、宜しくお願い致します。
- 締切済み
- その他MS Office製品
- 2回目に画面のレコードセットの値が読めない
メインフォームとサブフォームの画面゛て レコードソースは、ワークテーブルを参照し メインフォームの保存ボタンの処理で、 Private Sub 保存ボタン_Click() Set mySubFm = Me![テーブル子].Form Set myParFm = Forms(Me.name) '<== 親フォーム Set Rec1 = myParFm.RecordsetClone Set Rec2 = mySubFm.RecordsetClone Lng受注ID = Rec1.Fields("受注ID").Value Dim Rtn As Integer ・レコードセットのデータを、本テーブルに更新する処理 ・自動採番した番号を、レコードセットのIDのフィールドにセット Rec1.Edit Rec1.Fields("ID").value = newID Rec1.Update ・Me.Requery '<== メインフォームの画面を更新 ・mySubFm.Requery '<==サブフォームの画面を更新 Set Rec1 = Nothing Set Rec2 = nothing End Sub この処理を一度行い、更に、画面のサブレコードの値を変更して、保存ボタンを再度押すと、 Lng受注ID = Rec1.Fields("受注ID").Value の行で、 「オブジェクトが正しくないか、現在設定されていません」というエラーになります。 この原因はどうしたら解決出来ますでしょうか? よろしくお願いします。
- ベストアンサー
- その他(データベース)
- RecordCount(ADO)が変わる?ADP+SQLServer
ACCESS2000(ADP)+SQLServerにて作成したものですが、 あるクライアント(1台)だけRecordCountがおかしいのです。 <フォームAのボタンクリック時の処理> DoCmd.OpenForm "フォームB", , , , , , Me!コード <フォームBの読み込み時の処理> Dim rs AS ADODB.Recordset Set rs = Me.RecordsetClone rs.Find "コード=" & Me.OpenArgs, 0, adSearchForward If not rs.EOF then Me.Bookmark = rs.Bookmark End if 問題のないクライアント(他の2台)では、 フォームBにてOpenArgに指定したコードが検索され, 該当のレコードが表示されます。 問題のクライアントでは、 「一部」のレコードを指定した場合にレコードが検索されず、 最初のレコードが表示されました。 原因を調べているうちに分かったことは、 Set rs = Me.RecordsetClone で取得したレコードセットがあるタイミングでは、 一部かけた状態になっているということです。 その際に使用した方法は、 Set rs = Me.RecordsetClone rs.MoveLast MsgBox rs.RecordCount MsgBox rs.RecordCount としてレコードの件数を調べて判明しました。 MsgBox rs.RecordCountが2つあるのは記述ミスではありません。 該当のテーブル(レコード)は757件ありますが、 問題のないクライアントでは2回ともに757を返します。 問題のクライアントでは、 1回目のRecordCountは500 2回目のRecordCountは757を返してきます。 しかも、何回も実行していると 1回目が400、450、500とランダムで変化します。 (500が2回続いたりするときもあります) 以上のことから、考えられる原因は何かありますでしょうか。 よろしくお願いいたします。
- ベストアンサー
- Visual Basic
- Access フォームの表示順をなおしたい
いつもお世話になっています。 Access フォームを利用していたのですが、テーブルの既存データを更新してから、そのフォームでのデータ表示順が変わってしまいました。 レコードにはIDとして番号データがあるので、小さい順にフォームに表示させたいと思います。 ちなみに、元となるテーブルはID番号が小さい順に並んでいます。 よろしくお願いします。
- ベストアンサー
- オフィス系ソフト