同じような現象がなかったので、初心者ではありますが
質問させていただきます
http://okwave.jp/qa447885.html
こちらの質問にあった
ryuu001さん回答の
◎テーブル名 = テーブル1
◎連番のフィールド名 = ID とし
◎連番は後から入力した数値が
先に入力した数値より
小さくなることは無い。
(dmaxを使用しているので大丈夫かと思いますが)
Sub test()
Dim Db As Database
Dim Rs As DAO.Recordset
Dim Temp As String
Dim I As Integer
Set Db = CurrentDb()
Set Rs = Db.OpenRecordset("テーブル1")
Rs.MoveFirst
I = 1
Temp = ""
Do Until Rs.EOF = True
Do While I < Rs!ID
Temp = Temp & " " & I
I = I + 1 *1
Loop
Rs.MoveNext
I = I + 1
Loop
Rs.Close
Set Rs = Nothing
Db.Close
Set Db = Nothing
MsgBox "次の数字が抜けています。" & vblf & Temp
End Sub
VBAを利用させていただきました。
ですが「オーバーフローしました」とエラーが出てしまい
デバッグすると*1の場所で止まっているようでした
これはやはりLoopしているのが原因なんでしょうか
ずっと+1を繰り返している・・・?
No.9ベストアンサー
- 回答日時:
こんにちは
#8です。 的確なアドヴァイスが出来なくてごめんなさい。
>>MsgBox "比較処理中 I=" & Str$(I) & ", Rs!ID=" & Str$(Rs!ID)
>このメッセージボックス部分で「型が一致しません」と出てしまうようです。宣言など>が必要なんでしょうか?
>Str関数?がうまく機能してないのでしょうか・・・
質問者さんがにらんだ通り、当たりです(^^;
STR$()関数は、引数が数値でなくてはならないのですが、「Rs!ID」は
数値ではないため、エラーになりました。
>MsgBox "比較処理中 I=" & Str$(I) & ", Rs!ID=" & Str$(Rs!ID)
>MsgBox "Loop通過 I=" & Str$(I) & ", Rs!ID=" & Str$(Rs!ID)
従って、上記はどちらでも処理が通過するときエラーになります。
片方しかエラーが見つからないのは、たまたまデータが片方を通過
するパターンしかなかったということと理解しています。
ホントにすみませんでした m(__;m
さて、下記のようにしていただく案と..
MsgBox "比較処理中 I=" & Str$(I) & ", Rs!ID=" & Rs!ID
MsgBox "Loop通過 I=" & Str$(I) & ", Rs!ID=" & Rs!ID
Str$(Rs!ID) を Str$(J)にする案があります。
MsgBox "比較処理中 I=" & Str$(I) & ", J=" & Str$(J)
MsgBox "Loop通過 I=" & Str$(I) & ", J=" & Str$(J)
どちらでもいいです。プログラムが思ったように動いているかを変数
の値から把握するのが目的ですから。
飛び番がないときは、Loop通過 I=..しか表示されません。
飛び番があったら、比較処理中 I=.. が飛び番の数だけ表示されてか
ら Loop通過 I=.. に移るはずですね。
この回答への補足
夜遅くに回答ありがとうございます。
週末は見ることが出来ずに申し訳ありません・・・
おかげさまで検索開始することができ、状況も把握できるようになりました。
ですが、疑問が・・・
検索開始してOKをずっと押していると
比較処理中 I=6131, Rs!riyou_id=ZZZZ8939
等の結果がでるようになりました。
これは6131から8939までは空き番号と判断してしまっていいんでしょうか
理想としては最後にフォームが開き空き番号を参照できるようにしたいのですが、このVBAの最後は空き番号の最小値が出るだけだと思うのですが
実際空き番号の検索をしてみると総当りで見ているので検索が非常に長かったです。
毎回検索して空き番号を探しそこに登録!
という流れだと時間的に厳しいかなと思いました。
何かいい案はありますでしょうか?
コレばかりは仕方ないですかね・・・
No.8
- 回答日時:
こんにちは
#7です。横入りでごめんなさい。
積極的に変数の内容が意図したように変わっているか見てみましょう。VBAエディタを使いこなせるとステップ実行やウォッチ機能でできるのですが、コードに埋め込む手もあります。
Sub test()
'◆前提条件
'・レコードセットは、ID昇順で得られる。
'・同じ数値のIDはない。
'・IDの最小値は 1 である。
'・IDの最大値は Integerで扱える。
'・フィールド ID は、数値型
'
Dim Db As Database
Dim Rs As DAO.Recordset
Dim Temp As String '抜け番号レポート用文字列バッファ
Dim I As Integer 'レコード番号カウンタ(1~対象IDすべて)(32767以内)
Dim J As Integer 'ID番号(数字部分を整数に変換して格納される)
'●DBからIDのZZZZnnnn 抽出し、IDをキーに昇順ソート
Set Db = CurrentDb()
Set Rs = Db.OpenRecordset("SELECT ID FROM テーブル1 WHERE ID LIKE 'ZZZZ*' ORDER BY ID")
Rs.MoveFirst
Let I = 1 '1番目のIDからスタートするため、カウンタも1に初期化
Let Temp = "" 'レポート用バッファは空に初期化
'■レコードセットの終わりが来るまで Loop
Do Until Rs.EOF = True
'●IDの ZZZZnnnnの数字部分を切り取る
Let J = CInt(Right(Rs!ID, 4))
'■レコード番号カウンタがID番号よりも小さい(=抜けがある)間Loop
Do While I < J
Let Temp = Temp & " " & I '●抜けているレコード番号を記録
Let I = I + 1 '●次のID番号と比較する準備
MsgBox "比較処理中 I=" & Str$(I) & ", Rs!ID=" & Str$(Rs!ID)
'■
Loop
MsgBox "Loop通過 I=" & Str$(I) & ", Rs!ID=" & Str$(Rs!ID)
Rs.MoveNext
Let I = I + 1 '●次のID番号と比較する準備
'■
Loop
MsgBox "Loop終了(レコードセットの終端に達した)"
Rs.Close
Set Rs = Nothing
Db.Close
Set Db = Nothing
MsgBox "次の数字が抜けています。" & vbLf & Temp
End Sub
この回答への補足
A88No8さん、度々回答ありがとうございます。非常に参考になります。
補足が遅くなって申し訳ありません。
今回教えていただいた箇所を変更してみましたが、
>MsgBox "比較処理中 I=" & Str$(I) & ", Rs!ID=" & Str$(Rs!ID)
このメッセージボックス部分で「型が一致しません」と出てしまうようです。宣言などが必要なんでしょうか?
Str関数?がうまく機能してないのでしょうか・・・
ちなみにこのメッセージボックスの1行前にメッセージボックスを作ってみましたが表示がされました。
”や’の位置を変えてみたりしましたが、コンパイルエラーが帰ってきます・・・自分で解決できなくて申し訳ありません。
お暇な時にでも助言をお願いします。
あ、すみません。ちょっと記載ミスが・・・
>MsgBox "比較処理中 I=" & Str$(I) & ", Rs!ID=" & Str$(Rs!ID)
ではなくて
>MsgBox "Loop通過 I=" & Str$(I) & ", Rs!ID=" & Str$(Rs!ID)
こちらでした・・・。
お礼欄使ってしまって申し訳ないです
No.7
- 回答日時:
横入りでごめんなさい。
#6のアドヴァイスでトライされたのはよいのですが、古いDOコードが残ったままです(DOは、LOOPとセットで、DO~LOOP文です)。
とりあえず、下記の←印の行を削除して試してみましょう。
Do Until Rs.EOF = True
J = CInt(Right(Rs!ID,4))
Do While I < J
Do While I < Rs!ID ←前の2行で置換えるべきステートメントなので削除しないと
Temp = Temp & " " & I
I = I + 1
Loop
msgBox "Loop通過"
Rs.MoveNext
I = I + 1
Loop
この回答への補足
回答ありがとうございます!
あ・・・これは写しミスでしたごめんなさい・・・
この行じたいは'コメントアウトしてありますうっかりしてて申し訳ない・・・
ご指摘ありがとうございます!
No.6
- 回答日時:
#4 での前提条件に(基本的な条件として)1つ抜けがありました。
・フィールド ID は、数値型
> たとえば個人データならABCD0001。未特定データならZZZZ0001~9999のようになります。
数字部分を分離する必要があります。
未特定データでの修正案1)
IDの右4文字を数値として INUM 名で抽出しておく
・レコードセットを得るSQLを以下
SELECT CInt(Right([ID],4)) AS INUM FROM テーブル1 WHERE ID LIKE 'ZZZZ*' ORDER BY ID;
・Do While I < Rs!ID → Do While I < Rs!INUM
未特定データでの修正案2)
・レコードセットを得るSQLを以下
SELECT ID FROM テーブル1 WHERE ID LIKE 'ZZZZ*' ORDER BY ID;
・VBA 記述追加/変更
Dim J As Integer 宣言追加
Do Until Rs.EOF = True
Do While I < Rs!ID
↓
Do Until Rs.EOF = True
J = CInt(Right(Rs!ID,4))
Do While I < J
※ ID の右4文字を数値とする方法は上記のとおりで、5文字目以降という意味合いなら
CInt(Mid(○○,5))
※ 個人データであれば、'ZZZZ*' → 'ABCD*'
※ メモ
Dim I As Integer
I = 1
Do While I < AAA '----- (1)
I = I + 1
Loop
上記状態で、(1)の AAA をいろいろ変えた時の動き
・Do While I < 3
I が 3 になるまでループ
・Do While I < "3"
I が 3 になるまでループ
・Do While I < "A3"
型が一致しないエラー
・Do While I < Rs!ID IDはテキスト型で、中身 "A3"
I のオーバーフロー
この回答への補足
ご回答ありがとうございます。2つも案も出して頂きありがとうございます!メモとっても参考になります;;もしかするとZZZZの文字が邪魔してオーバーフローだったのかもしれないのですかね・・・
修正案をさっそくトライしてみました。
Sub test()
Dim Db As Database
Dim Rs As DAO.Recordset
Dim Temp As String
Dim I As Variant
Dim J As Integer
Set Db = CurrentDb()
Set Rs = Db.OpenRecordset("SELECT ID FROM テーブル1 WHERE ID LIKE 'ZZZZ*' ORDER BY ID")
Rs.MoveFirst
I = 1
Temp = ""
Do Until Rs.EOF = True
J = CInt(Right(Rs!ID,4))
Do While I < J
Do While I < Rs!ID
Temp = Temp & " " & I
I = I + 1
Loop
msgBox "Loop通過"
Rs.MoveNext
I = I + 1
Loop
msgBox "Loop終了"
Rs.Close
Set Rs = Nothing
Db.Close
Set Db = Nothing
MsgBox "次の数字が抜けています。" & vblf & Temp
End Sub
加えた場所は段差をつけて見ました
オーバーフローは解消 I を Variantにしたため解消できたようです
ですがやっぱりLoopの場所でずっと繰り返しているだけでした。エラーもでなかったので繰り返しているだけ?
気になってLoopの場所にメッセージボックスを置いてみたのですがやはり
Loop通過を繰り返すだけでした。
こればかりは結果でるまで待つしかないのでしょうか・・・それともLoopしてるだけで進んでいないのか・・・
申し訳ないのですが、助言いただけると幸いです。
No.5
- 回答日時:
こんにちは
#1、#3です。
#4さんの適切なご指摘で#1、3は外していることが明確になりましたので#1、#3は無視して下さい。
ごめんなさい。
ただ、「Rs!ID」の正体が気になり始めました。
この回答への補足
何度も回答ありがとうございます。助かります
>#4さんの適切なご指摘
本当に力不足で申し訳ないです。理解できるように勉強します。
Rs!IDは個人データ(IDが固有のもの)未特定データ(IDをとりあえず割り振ったもの)になるんですが、
たとえば個人データならABCD0001。未特定データならZZZZ0001~9999のようになります。
そういうことではなかったですか・・・?
No.4
- 回答日時:
なぜオーバーフローしたか分かりませんが、
このコードの前提条件は、以下と思われます。
・レコードセットは、ID昇順で得られる。
・同じ数値のIDはない。
・IDの最小値は =1 である。
・IDの最大値は Integer で扱える。
> データ数は数字上限でいうと9999です。
> 個人データと未特定データを合わせても2万弱になります。
一度確認されてみてはいかがでしょう。
※
Rs.MoveNext
I = I + 1 ← 次に得られるであろうID値を事前に設定している
この回答への補足
みなさん返答おくれまして申し訳ありません
もしかすると#3のA88No8さんの仰っていたIntegerの限界かもしれないです
フィールドが7つありレコードが2万弱・・・
前提条件に関しましてはまったくその通りです。
最後の行がとってもヒントにみえるのですがはっきりしません・・・
理解できるように勉強します。
No.3
- 回答日時:
こんにちは
#1です。勘違いされているようなので..
>Let I = I + 1 に両方とも変更してみたのですが
>同じくオーバーフローしてしまいました。データ数2万弱ですがこのVBAだと無理なんでしょうか・・・
いいたかったのは「Let I = I + 1」が変じゃない?ってことなんです。
外側のDOでレコード(行)をトレースし、内側のDOでフィールド(列)をトレースしているように見える。 Iの目的がデータすべての順序番号なら外側と内側の間にあるLet I=I+1は、不要。
Iの目的がフィールド順序番号を繰返す目的なら Let I=1 でフィールド(列)を一巡する内側のDOを抜けた時点で、Iを初期化すべきではないでしょうか?
あと、Iの目的がデータすべての順序番号なら、多分 integer だと16ビットのような気がするので 65536 の半分(3万ぐらい)までしかカウントできません。
フィールド×レコードの値が3万以内に入っていますか?
この回答への補足
回答ありがとうございます。とても参考になります!
>フィールド×レコードの値が3万以内に入っていますか?
これは・・・
テーブル1にはフィールドが7個ありました・・・それでいてレコードも2万弱ということは完全にあふれてしまっていますね・・・
integerでは扱いきれなかったのですね。納得です。
>フィールド(列)を一巡する内側のDOを抜けた時点で、Iを初期化すべきではないでしょうか?
申し訳ありません。Iを初期化する。とはどういうことでしょうか・・・無知で申し訳ないです。
Variant形式にして内側と外側の間にあるI = I + 1を削除してみたところ
オーバーフローはでなくなりましたがずっと検索を行っているようで終わりそうにありませんでした。重いのかもしれません・・・
No.2
- 回答日時:
回答ではないですが。
リンク先の回答のコードを使ってみたらオーバーフローしました。
と言ってもその質問者と同じ環境なのかどうかもわかりません。
あとIntegerの範囲を超えたデータ量と言うわけでもないですよね。
⇒Excelでたまに使ってしまい範囲を超えてオーバーフローさせる事もありましたもので。
この回答への補足
書き込みありがとうございます。
やはり分かりにくい現象なんでしょうか。。。
データ数は数字上限でいうと9999です。
個人が特定できているものを削除し、個人データに書き換えた時に空き番がでるのですが。。。
個人データと未特定データを合わせても2万弱になります。
No.1
- 回答日時:
こんにちは
Do Until Rs.EOF = True
Do While I < Rs!ID
Temp = Temp & " " & I
Let I = I + 1
Loop
Rs.MoveNext
Let I = I + 1 ←外側のループにあるこれが無意味のような(Let I=1 なら納得)。
Loop
この回答への補足
回答ありがとうございます。
I = I + 1
を
Let I = I + 1
に両方とも変更してみたのですが
同じくオーバーフローしてしまいました。
データ数2万弱ですがこのVBAだと無理なんでしょうか・・・
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Access(アクセス) 実行時エラー3131 FROM 句の構文エラーです について 7 2022/06/13 15:45
- Access(アクセス) DoCmd.SearchForRecord が動かない時の解決方法 3 2022/07/22 15:31
- Visual Basic(VBA) access count数を変数に格納 2 2022/03/30 19:21
- Visual Basic(VBA) ACCESS DAO で不要なテーブルのフィールド(列)の削除 4 2022/06/23 12:13
- Access(アクセス) docmd.gotorecordを起動するには 5 2022/06/17 15:20
- Visual Basic(VBA) データベースから絞り込んでデータを読み込み 1 2023/02/21 19:51
- Access(アクセス) チェックボックスにチェックが入った後の挙動 1 2022/08/21 12:39
- Access(アクセス) アクセス テーブルの空白を変数に置換するボタンが作りたい 4 2022/07/08 11:19
- Visual Basic(VBA) Excelで下記のようにマクロを作ったところ、一回目は実行できたのですが、二回目以降「実行時エラー1 1 2022/03/25 08:08
- Access(アクセス) アクセス レポートを開いたときにパラメーターの自動入力がしたい 4 2022/11/30 11:21
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルのデータをアクセスに...
-
EXCEL→ACCESSインポートでセル...
-
ACCESS フォームに入力できる文...
-
ACCESS 検索置換 にデ...
-
差込印刷での全角表示について...
-
日付型のフィールドに空白を入...
-
アクセスのエラー「クエリには...
-
SQL文で パラメータが少なすぎ...
-
アクセスで追加した項目に全て...
-
エクセルにおける「フィールド...
-
Word2010の差込印刷で金額にコ...
-
テキストボックスにクエリ結果...
-
ACCESSのクエリで抽出条件「ま...
-
アクセス・テーブルの改行につ...
-
Accessのテーブルのフィールド...
-
2つのテーブルに共通するレコ...
-
Accessのフォームのテキストボ...
-
ACCESSで行数指定(5万行目~8...
-
ACCESS クエリの抽出条件に他の...
-
Accessの桁区切りについ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ACCESSのテーブルのデータで、...
-
エクセルのデータをアクセスに...
-
EXCEL→ACCESSインポートでセル...
-
Accessチェックボックス 一度で...
-
ACCESS フォームに入力できる文...
-
アクセスのオートナンバーが飛...
-
ACCESSで改行コードを削除する方法
-
郵便番号の-(ハイフン)等をま...
-
ACCESSで行数を増やすには?
-
Access2003でフィールドのデー...
-
Access2000 テキストデータの...
-
アクセス2000で固定長フィール...
-
ACCESSのカスタマーバーコード...
-
ACCESS 検索置換 にデ...
-
【ACCESS】文字列を抜き出したい
-
【Win】ファイルメーカー⇔エ...
-
エクセルの重複データについて...
-
アクセス(データシートビュー)...
-
エクセルのデータをアクセスへ...
-
差込印刷での全角表示について...
おすすめ情報