レコードを移動させても 更新処理が動作しないようにするには?

解決


銀河系軍団  2005-08-18 02:03:47  No: 124179

・検索ボタン押下時の処理
Private Sub cmdKensaku_Click()

    'レコードセットオブジェクト認識
    Set prRsSyain = New ADODB.Recordset
    
    'カーソル定義
    prRsSyain.CursorLocation = adUseClient
            
    'SQLのクリア
    prStrSql = ""
    
    'SQLの指定
    prStrSql = "SELECT * FROM SYAIN WHERE N_KAISYA_CD = " & prStrKaisyaCd(cboCompanyNm.ListIndex) & " ORDER BY N_SYAIN_NO"

    'レコードセットオブジェクトへ接続する
    prRsSyain.Open prStrSql, prCn, adOpenStatic, adLockOptimistic

    '会社番号テキストにデータソースを指定
    Set txtNo.DataSource = prRsSyain
    
    '氏名テキストにデータソースを指定
    Set txtNm.DataSource = prRsSyain
    
    '年齢テキストにデータソースを指定
    Set txtAge.DataSource = prRsSyain
    
    '社員番号テキストへ表示
    txtNo.DataField = "N_SYAIN_NO"
    
    '氏名テキストへ表示
    txtNm.DataField = "V_SYAIN_NM"
    
    '年齢テキストへ表示
    txtAge.DataField = "N_SYAIN_AGE"
    
    '移動ボタン制御呼び出し
    Call chkbtm
    
End Sub

・レコード移動ボタン押下時の処理
Private Sub cmdMove_Click(Index As Integer)

    With prRsSyain
    
        Select Case Index
        
        '先頭レコード移動ボタン押下時
        Case 0
                        
            '先頭レコードへ移動
            .MoveFirst
            
            '移動ボタン制御呼び出し
            Call chkbtm
        
        '前レコード移動ボタン押下時
        Case 1
        
            '前レコードへ移動
            .MovePrevious
        
            '移動ボタン制御呼び出し
            Call chkbtm
    
        '後ろレコード移動ボタン押下時
        Case 2
            
            '後ろレコードへ移動
            .MoveNext
                    
            '移動ボタン制御呼び出し
            Call chkbtm
        
        '最終レコード移動ボタン押下時
        Case 3
            
            '最終レコードへ移動
            .MoveLast
            
            '移動ボタン制御呼び出し
            Call chkbtm
            
        End Select

    End With

End Sub

・更新ボタン押下時の処理
    '氏名テキストに表示された「'」を「''」に置き換える
    txtNm.Text = Replace(txtNm.Text, "'", "''")
                
    'SQLのクリア
    prStrSql = ""
    
    'SQLの指定
    prStrSql = "UPDATE SYAIN SET V_SYAIN_NM = '" & txtNm.Text & "', N_SYAIN_AGE = '" & txtAge.Text & "' WHERE N_SYAIN_NO = " & txtNo.Text & ""
        
    '画面の内容で社員情報テーブルを更新
    prCn.Execute prStrSql
        
    'レコードセットオブジェクト認識
    Set prRsSyain = New ADODB.Recordset
    
    'カーソル定義
    prRsSyain.CursorLocation = adUseClient
        
    'SQLのクリア
    prStrSql = ""
    
    'SQLの指定
    prStrSql = "SELECT * FROM SYAIN WHERE N_KAISYA_CD = " & prStrKaisyaCd(cboCompanyNm.ListIndex) & " ORDER BY N_SYAIN_NO"

    'レコードセットオブジェクトへ接続する
    prRsSyain.Open prStrSql, prCn, adOpenStatic, adLockOptimistic

    '会社番号テキストにデータソースを指定
    Set txtNo.DataSource = prRsSyain
    
    '氏名テキストにデータソースを指定
    Set txtNm.DataSource = prRsSyain
    
    '年齢テキストにデータソースを指定
    Set txtAge.DataSource = prRsSyain
    
    '移動ボタン制御呼び出し
    Call chkbtm

End Sub


銀河系軍団  2005-08-18 02:09:16  No: 124180

検索ボタンを押下して  テキストにレコードを表示させ
レコード移動ボタンで  動かすときに
なぜか  更新の処理まで動いてしまいます。
デバッグモードで見ていても  なぜ更新処理まで動いてしまうのか
さっぱりわかりません・・・。


銀河系軍団  2005-08-18 02:12:03  No: 124181

すいません。
イベントプロシージャが  ひとつ抜けてしまいました。

・移動ボタン制御
Private Function chkbtm()
    
    With prRsSyain
    
        'レコードが1件の場合
        If .RecordCount = 1 Then
            
            '先頭レコード移動ボタン使用不可
            cmdMove(0).Enabled = False
            
            '前レコード移動ボタン使用不可
            cmdMove(1).Enabled = False
        
            '後ろレコード移動ボタン使用可
            cmdMove(2).Enabled = False
            
            '最終レコード移動ボタン使用可
            cmdMove(3).Enabled = False
        
        '先頭レコードの場合
        ElseIf .AbsolutePosition = 1 Then
            
            '先頭レコード移動ボタン使用不可
            cmdMove(0).Enabled = False
            
            '前レコード移動ボタン使用不可
            cmdMove(1).Enabled = False
        
            '後ろレコード移動ボタン使用可
            cmdMove(2).Enabled = True
            
            '最終レコード移動ボタン使用可
            cmdMove(3).Enabled = True
        
        '最終レコードの場合
        ElseIf .AbsolutePosition = .RecordCount Then
        
            '先頭レコード移動ボタン使用可
            cmdMove(0).Enabled = True
            
            '前レコード移動ボタン使用可
            cmdMove(1).Enabled = True
        
            '後ろレコード移動ボタン使用不可
            cmdMove(2).Enabled = False
            
            '最終レコード移動ボタン使用不可
            cmdMove(3).Enabled = False
        
        'その他のレコードの場合
        Else
            
            '先頭レコード移動ボタン使用可
            cmdMove(0).Enabled = True
            
            '前レコード移動ボタン使用可
            cmdMove(1).Enabled = True
            
            '後ろレコード移動ボタン使用可
            cmdMove(2).Enabled = True
            
            '最終レコード移動ボタン使用可
            cmdMove(3).Enabled = True
        
        End If
        
    End With
        
End Function


で?  2005-08-18 02:35:17  No: 124182

ソースを公開するのでデバッグをお願いしますってことですか?w
突っ込みどころ満載ですが・・・
とりあえず自分の環境くらいは書きましょう。


もげ  2005-08-18 17:55:30  No: 124183

デバッグモードというのが何なのかわかりませんが、
各イベントプロシージャにブレークポイントを仕掛けて
1行づつステップ実行してみることをお勧めします。
プログラムは貴殿が思ったとおりではなく、貴殿が書いたとおりに動きます。


銀河系軍団  2005-08-18 19:31:14  No: 124184

>ソースを公開するのでデバッグをお願いしますってことですか?w
>突っ込みどころ満載ですが・・・
>とりあえず自分の環境くらいは書きましょう。

ソースはおまけとして書いたのですが・・・。
言葉だけでも  十分だったかもしれません。
要するに  データベース特有の  データを変更すると勝手に更新されてしまうのを
防ぐにはどうすればいいのか?ということだったんです。
環境はVB6.0です。


通りすがり  2005-08-18 20:08:03  No: 124185

>要するに  データベース特有の  データを変更すると勝手に更新されてしまうのを
>防ぐにはどうすればいいのか?ということだったんです。

DB特有なんじゃなくてあなたのコーディング特有のでしょ?w
そんな仕様のDBが存在するなら是非聞きたいw

で、DB何?


魔界の仮面弁士  2005-08-18 20:09:13  No: 124186

> レコード移動ボタンで  動かすときに
> なぜか  更新の処理まで動いてしまいます。
何故といわれても……まぁ、そういう仕様なので。

どうしても更新させたくないなら、
  案1) 画面表示用データソースと、DB反映用データソースを分離する。
  案2) 最初から、画面側を更新不可に設定しておく。
  案3) 更新が行われた後で、自分で値を元に戻す。
  案4) WillMoveイベントやWillChangeFieldイベントで、ステータスを
      adStatusCancel に変更する。
  案5) そもそもデータバインドなど使わず、テキストボックスの
      Textプロパティ等を、Recordsetから個別に割り当てるようにする。
などの手法が考えられます。

> 要するに  データベース特有の  データを変更すると勝手に更新されてしまうのを
> 防ぐにはどうすればいいのか?ということだったんです。

ならば単純に、Recordsetをデータベースから切り離しておけば良いのでは。
そうすれば、Recordsetの内容が変更されても、その編集結果が
データベース側に反映されることはありませんし。
http://www.microsoft.com/japan/msdn/library/ja/jpado260/htm/mdcondisconnectedrs.asp


銀河系軍団  2005-08-18 21:13:13  No: 124187

'レコードセットオブジェクトへ接続する
    prRsSyain.Open prStrSql, prCn, adOpenStatic, adLockOptimistic

    'データソースからレコードセットオブジェクトを切断
    prRsSyain.ActiveConnection = Nothing

これでうまくいきました。
魔界の仮面弁士さん  ありがとうございました。


銀河系軍団  2005-08-18 21:47:03  No: 124188

解決チェックマーク忘れてました^^;


銀河系軍団  2005-08-19 19:51:03  No: 124189

半分しか解決していませんでした・・・。

    'レコードセットオブジェクトへ接続する
    prRsSyain.Open prStrSql, prCn, adOpenStatic, adLockOptimistic

    'データソースからレコードセットオブジェクトを切断
    prRsSyain.ActiveConnection = Nothing

これでデータソースの方は更新されなくなったんですが
画面側の方も更新されなくしたいです。

>  案2) 最初から、画面側を更新不可に設定しておく。
これは  どうやればいいんでしょうか?


銀河系軍団  2005-08-19 21:36:06  No: 124190

With prRsSyain
    
        Select Case Index
        
        '先頭レコード移動ボタン押下時
        Case 0
                        
            '先頭レコードへ移動
            .MoveFirst

            WillMove adRsnMoveFirst, adStatusCancel, prRsSyain ・・・※
            
            '移動ボタン制御呼び出し
            Call chkbtm

こうしても  ※で「sub または Function が定義されていません」って出るし・・・。


いな  2005-08-19 22:09:27  No: 124191

エラーメッセージの内容のままですが、
Sub、Functionの定義はしていますか?


特攻隊長まるるう  2005-08-19 22:09:51  No: 124192

WillMove はイベントだと説明されていると思いますが?
[VB6.0]
Private WithEvents prRsSyain As ADODB.Recordset

Private Sub prRsSyain_WillMove(ByVal adReason As ADODB.EventReasonEnum, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)

End Sub


銀河系軍団  2005-08-19 23:10:51  No: 124193

Private Sub cmdMove_Click(Index As Integer)
            
    Call prRsSyain_WillMove
            
End Sub

Private Sub prRsSyain_WillMove(ByVal adReason As ADODB.EventReasonEnum, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)

    Dim Index As Integer

    With prRsSyain
    
        Select Case Index
        
        '先頭レコード移動ボタン押下時
        Case 0
                        
            '先頭レコードへ移動
            .MoveFirst
    
            prRsSyain_WillMove adRsnMoveFirst, adStatusCancel, prRsSyain
    
            '移動ボタン制御呼び出し
            Call chkbtm
        
        '前レコード移動ボタン押下時
        Case 1
        
            '前レコードへ移動
            .MovePrevious
            
            prRsSyain_WillMove adRsnMovePrevious, adStatusCancel, prRsSyain
    
            '移動ボタン制御呼び出し
            Call chkbtm
    
        '後ろレコード移動ボタン押下時
        Case 2
            
            '後ろレコードへ移動
            .MoveNext
            
            prRsSyain_WillMove adRsnMoveNext, adStatusCancel, prRsSyain
    
            '移動ボタン制御呼び出し
            Call chkbtm
        
        '最終レコード移動ボタン押下時
        Case 3
            
            '最終レコードへ移動
            .MoveLast
            
            prRsSyain_WillMove adRsnMoveLast, adStatusCancel, prRsSyain
            
            '移動ボタン制御呼び出し
            Call chkbtm
            
        End Select

    End With

End Sub

「スタック領域が不足しています」とエラーメッセージが出ますが
コードの記述は  とりあえずこれであっているんでしょうか?


特攻隊長まるるう  2005-08-20 00:03:34  No: 124194

全く違います。

[WillMove、MoveComplete (ConnectionEvent) メソッド (ADO)]
のヘルプを読んで下さい。パラメータの説明の中に
>保留中の操作のキャンセルを要求するには〜
という記述があると思います。adStatus を設定するだけです。

余談ですが、イベントについて全くご理解されていないようです。
ヘルプでイベントがどういうものか調べておくことをお勧めします。
残念ながらコードで
>            prRsSyain_WillMove adRsnMoveFirst, adStatusCancel, prRsSyain
と書いてもコードで書いた prRsSyain_WillMove 関数が呼ばれるだけで、
WillMove イベントとは何の関係もありません。イベントは実体を持って
いるオブジェクトが発生させるもので、
   WillMove イベントが発生 → prRsSyain_WillMove 関数が呼ばれる
の一方通行で、prRsSyain_WillMove 関数を呼んでもイベントが発生する
わけではありません。


特攻隊長まるるう  2005-08-20 00:46:59  No: 124195

…あれ?(汗)というかヘルプの構成がおかしいなぁ…メソッドの
説明じゃ誤解を生むなぁ…。…しかし分類はADOイベント…(謎)。
オイラの説明もおかしいですm(__)m失礼。

こちらではヘルプで確認しただけなので、実際に動かしての確認はお願いします。
以下のコードでテストしてみて下さい。
[VB6.0]
Private Sub prRsSyain_WillMove(ByVal adReason As ADODB.EventReasonEnum, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)
    adStatus = ADODB.EventStatusEnum.adStatusCancel
End Sub


銀河系軍団  2005-08-20 01:19:01  No: 124196

Private prRsSyain   As ADODB.Recordset

Private WithEvents prRsSyain As ADODB.Recordset
にして

Private Sub prRsSyain_WillMove(ByVal adReason As ADODB.EventReasonEnum, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)
    adStatus = ADODB.EventStatusEnum.adStatusCancel
End Sub
を加えると

    '社員番号テキストへ表示
    txtNo.DataField = "N_SYAIN_NO"
でエラーが出ます。

WillMoveメソッドは  必要なんでしょうか?  必要ではないんでしょうか?
WillMove adRsnMoveFirst, adStatusCancel, prRsSyain


銀河系軍団  2005-08-20 01:41:16  No: 124197

魔界の仮面弁士さんの言われた
>  案2) 最初から、画面側を更新不可に設定しておく。
これが一番簡単そうですが  やり方が分からない・・・。


特攻隊長まるるう  2005-08-20 02:12:53  No: 124198

>    '社員番号テキストへ表示
>    txtNo.DataField = "N_SYAIN_NO"
>でエラーが出ます。
あくまで必要最小限のテスト用のサンプルコードを示している
だけですので、自分の要求を満たすような形に変更してご使用
下さい。
WillMove イベントはユーザによる操作だけでなく、コードに
よる変更でも起こります。adReason を利用してどんな時の
操作なのか場合分けしたり、コードからの変更を許可する場合は
フラグを用意して操作を許可するなどの工夫をして下さい。


銀河系軍団  2005-08-20 02:38:48  No: 124199

一旦解決にして  勉強しなおします。
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加