Microsoft Access 掲示板

ADOでレコードが飛ばされてしまう。 / 4

16 コメント
views
4 フォロー
4

コードの一部を追加しました。
残業区分 = 2の時の処理を記述しました

「元から ElseIf ブロックのコードがモジュールに記述されていた(が、最初の投稿時に端折っただけ)」とおっしゃりたいのか、「実際にはモジュールに記述されていなかったのでコードを修正した」という意味でおっしゃっているのか、どちらなのでしょうか。

仮に前者であるとして、

残業管理ID 130までは残業区分が3に変わりますが、
次は95がとばされてしまい、85のレコードの処理になってしまいます。

rs.Sort = "日付 ASC, 担当者ID ASC, 残業区分 ASC"

現時点では以下のいずれの意味でおっしゃっているのかが不明瞭です。

  1. レコードの並べ替え順が Sort プロパティで指定した通りにならず、[残業管理ID]が 130 であるレコードの次のレコードが 85 のレコードとなり、更にその次のレコード以降に 95 のレコードが現れる。

  2. レコードの並べ替え順は Sort プロパティで指定した通りになっているが、ElseIf ブロック内で呼び出された DCount 関数の戻り値が 0 となる(ので[残業区分]の書き換えとレコードの更新が実行されない)。

  3. レコードの並べ替え順は Sort プロパティで指定した通りになっているが、[残業管理ID]が 95 であるレコードを参照した際、最後の rs.MoveNext メソッドが呼び出されるより前のいずれかのタイミングで次のレコード( 85 )に移動している。

  4. それどころか、レコードセットの中に[残業管理ID]の値が 95 であるレコードが含まれていない。

  5. 上記以外の意味。

例えば 1,2 のいずれかに該当するならテーブル[tbl残業管理]の各レコードの[日付]に格納されている実際の値(例えば日付だけでなく時刻が含まれていないか等)を確認すべきですし、3 に該当するなら「(途中略)」とされた部分全てのコードが疑惑の対象となります。

通報 ...
  • 5

    sk様
    追加のコードについては、投稿時に端折っただけです。

    ご提示の1~5の選択肢については3だと思われます。

    下記のコードに書き換えて実行してみました。
    それでも同じく残業管理ID 95の残業区分が4にならずに2のままでした。
    他の残業区分IDは残業区分が3になっています。

        Dim cn As New ADODB.Connection
        Dim rs As New ADODB.Recordset
    
        Set cn = CurrentProject.Connection
        
        rs.CursorLocation = adUseClient
        rs.Open "tbl残業管理", cn, adOpenKeyset, adLockOptimistic
    
    
        rs.Sort = "日付 ASC, 担当者ID ASC, 残業区分 ASC"
        rs.MoveFirst
        
        
        Do Until rs.EOF
        
            If rs!残業区分 = 1 Then
            
                If DCount("休日", "tbl休日", "休日 = #" & rs!日付 & "#") > 0 Then
                
                    rs!残業区分 = 3
                    rs.Update
                    
                End If
    
        
            ElseIf rs!残業区分 = 2 Then
            
                If DCount("休日", "tbl休日", "休日 = #" & rs!日付 & "#") > 0 Then
                
                    rs!残業区分 = 4
                    rs.Update
                
                End If
    
            End If
            
            rs.MoveNext
              
        Loop
    
    
        rs.Sort = ""
    
        rs.Close: Set rs = Nothing
        cn.Close: Set cn = Nothing
    
    7

    書き換えたコードは途中略なしです。

  • 10

    ならば考えられる原因は 1 つだけです。

    rs.Sort = "日付 ASC, 担当者ID ASC, 残業区分 ASC"

    rs!残業区分 = 3

    [残業管理ID]の値が 130 であるレコードの[残業区分]の値に 3 を代入( 1 から 3 に変更)した瞬間に、そのレコードが 2 番目から 3 番目のレコードに、[残業管理ID]の値が 95 である([残業区分]の値が 2 である)レコードが 3 番目から 2 番目のレコードになった(レコードセット内での絶対位置が入れ替わった)からです。

    【 3 を代入する直前の状態】
    画像1

    【 3 を代入した直後の状態】
    画像2

    順番が入れ替わってもその時点でのカレントレコードは[残業管理ID]の値が 130 であるレコードのままなので、その後 MoveNext メソッドを呼び出せばその次( 4 番目)のレコードは[残業管理ID]の値が 85 であるレコードとなります。

    回避手段としては、Sort プロパティを使用せず Open メソッドの呼び出し時に「 ORDER BY 句付きの SELECT 文」を渡すことが挙げられます。

    rs.Open "SELECT * FROM [tbl残業管理] ORDER BY [日付] ASC, [担当者ID] ASC, [残業区分] ASC", cn, adOpenKeyset, adLockOptimistic
    
    12

    もっとも、「[日付]の値が休日に該当する場合は[残業区分]の値を書き換える」という処理だけに着目するのであれば、そもそもレコードを並べ替えること自体が不要であるとも言えますが。