none
DAO Recordcountが再コンパイルで利用できなくなった RRS feed

  • 質問

  • 2013年3月ごろぐらいからVB6で作成したプログラムのロジックのみの修正が必要になった為、ロジック修正後再コンパイルすると「DAO.Recordset」の「Recordcount」プロパティで値が取得できなくなってしまった。

    今まで動作していたのでWindowsアップデートによる影響だと思いますが、どの他か技術情報ご存じないでしょうか?

    開発環境は以下の通り

    WindowsXP(SP3)、Windows7(SP1)

    2013年6月17日 9:51

回答

  • 「DAO.Recordset」の「Recordcount」プロパティで値が取得できなくなってしまった。

    DAO のバージョンは何でしょうか?

    また、「値が取得できなくなった」との事ですが、具体的にはどういう状況なのでしょうか? (エラーになる、常に -1 になる、常に 0 になる、常に 1 になる、毎回異なる不定値になるなど)

    プログラムのロジックのみの修正が必要になった為、ロジック修正後再コンパイルすると

    ロジックを修正したとのことですが、OpenRecordset メソッドの引数指定を変更された覚えはありませんか?

    DAO の RecordCount プロパティは、アクセスしたレコードの絶対数を返すことになっています。このプロパティが、単純なレコード数を表しているわけではないことに注意してください。

    • テーブルタイプ(dbOpenTable)やスナップショット(dbOpenSnapshot)の場合、このプロパティはレコード数と一致します。
    • ダイナセットタイプ(dbOpenDynaset)の場合は、一度でもアクセスしたレコード数を返します。開いた直後なら1です。MoveLast すると全レコード数が返されます。マルチユーザー環境で他者が削除したレコードがカレントレコードになった場合、RecordCount は 1 減少します。なお、ORDER BY 指定されたクエリーや集計クエリーの場合には、取得直後であっても全レコード数が得られます。
    • 前方スクロールタイプ(dbOpenForwardOnly)の場合も、一度でもアクセスしたレコード数を返します。開いた直後なら1です。ただし、EOF に達すると -1 を返します。また、MoveLast は使用できずエラーとなります。
    2013年6月17日 13:10

すべての返信

  • 「DAO.Recordset」の「Recordcount」プロパティで値が取得できなくなってしまった。

    DAO のバージョンは何でしょうか?

    また、「値が取得できなくなった」との事ですが、具体的にはどういう状況なのでしょうか? (エラーになる、常に -1 になる、常に 0 になる、常に 1 になる、毎回異なる不定値になるなど)

    プログラムのロジックのみの修正が必要になった為、ロジック修正後再コンパイルすると

    ロジックを修正したとのことですが、OpenRecordset メソッドの引数指定を変更された覚えはありませんか?

    DAO の RecordCount プロパティは、アクセスしたレコードの絶対数を返すことになっています。このプロパティが、単純なレコード数を表しているわけではないことに注意してください。

    • テーブルタイプ(dbOpenTable)やスナップショット(dbOpenSnapshot)の場合、このプロパティはレコード数と一致します。
    • ダイナセットタイプ(dbOpenDynaset)の場合は、一度でもアクセスしたレコード数を返します。開いた直後なら1です。MoveLast すると全レコード数が返されます。マルチユーザー環境で他者が削除したレコードがカレントレコードになった場合、RecordCount は 1 減少します。なお、ORDER BY 指定されたクエリーや集計クエリーの場合には、取得直後であっても全レコード数が得られます。
    • 前方スクロールタイプ(dbOpenForwardOnly)の場合も、一度でもアクセスしたレコード数を返します。開いた直後なら1です。ただし、EOF に達すると -1 を返します。また、MoveLast は使用できずエラーとなります。
    2013年6月17日 13:10
  • 魔界の仮面弁士さん、コメントありがとうございます。

    >DAO のバージョンは何でしょうか?

    3.6を参照設定で利用しております。

    >ロジックを修正したとのことですが、OpenRecordset メソッドの引数指定を変更された覚えはありませんか?

    引数指定は変更しておりませんが、取得する列が増えたためSQLは変更しております。

    引数としては「dbOpenDynaset」を指定しています。

    また、変更箇所以外でも同じようにRecordcountが取得できなくなってしまっていたので、

    何か内部的なアップデートでもあったのか?と懸念がでてきたため投稿させていただきました。

    とりあえずの処理としては、取得件数が少ないので変数を作成してすべてのレコードを読み込んで件数を取得してからMoveFirstで戻して他のロジックに影響が出ないように対処しました。

    2013年6月17日 23:51
  •  「値が取得できなくなった」との事ですが、具体的にはどういう状況なのでしょうか? (再確認)

    > 3.6を参照設定で利用しております。

    12.0 系では無いのですね。

    > 引数としては「dbOpenDynaset」を指定しています。

    ダイナセットの場合、先述したように SQL文の内容によって、RecordCount の結果が変化する可能性がありますが、今回は該当していなかったのでしょうか?

    > 何か内部的なアップデートでもあったのか?と懸念がでてきたため投稿させていただきました。

    直近のアップデートというと、毎月第2火曜日の翌日にある月例更新のことでしょうか?

    JET 4.0 世代は Service Pack 8 を最後に、ここ10年ほど、大きな更新は無かったと記憶しています。もっとも、セキュリティ更新は何度かありましたが、恐らくは 2009年あたりの物が最新版かと思います。まして XP 向けともなると、2008年5月の KB950627 が最後かと。(私が見落としているだけかも知れませんが)

    一応、アップデートの可能性を確認するために、変更前のソースで動作検証してみてはいただけないでしょうか。その結果、旧ソースの動作まで変化していれば、システム側の更新の可能性が浮上してきますし、旧ソースで再現しないのであれば、プログラム側の問題ということになるでしょう。

    その際には、念のため DLLのバージョンも確認しておいてください。エンジン本体は msjet40.dll、ライブラリ側は dao360.dll です。現象を再現可能な最低限のソースとテーブル構成などを頂ければ、こちらでも追試してみたいと思います。

    > すべてのレコードを読み込んで読み込んで件数を取得してからMoveFirstで戻して

    パフォーマンス上の問題が出ない場合は、それが最も簡単な対処法かと思います。

    カーソル移動の実行コストが高い場合(異種DB間クエリ等)には、「MoveLast してから、BOF まで MovePrevious」という逆移動や、「SELECT COUNT(*) で代用」といった手法が使われることもあります。

    • 回答の候補に設定 星 睦美 2013年6月18日 4:05
    2013年6月18日 1:39
  • >一応、アップデートの可能性を確認するために、変更前のソースで動作検証してみてはいただけないでしょうか。

    検証した結果、問題ありませんでした。

    >直近のアップデートというと、毎月第2火曜日の翌日にある月例更新のことでしょうか?

    以前、月例更新でMSGRIDなどActiveXが急に動かなくなった事があったのでもしかしたらと考えましたが、上記結果から当方の予想と異なると考えられます。月例更新は関係なさそうです。

    >また、変更箇所以外でも同じようにRecordcountが取得できなくなってしまっていた・・・

    デバッグした際の当方の見間違いの可能性があります。

    申し訳ありません。

    パフォーマンス上特に影響がないので、簡単な対処方法で対処します。

    丁寧にお付き合いいただきありがとうございました。

    2013年6月18日 2:57
  • フォーラム オペレーターの星 睦美です。
    武装戦線 さん、こんにちは。

    魔界の仮面弁士 さんの返信が問題の切り分けに役立ったのではないかと思います。
    ほかの方のトラブルシューティングにも役立つと思いますので、私からスレッドに[回答としてマーク] させていただきました。

    これからもMSDN フォーラムをよろしくお願いします。


    日本マイクロソフト株式会社 フォーラム オペレーター 星 睦美

    2013年6月19日 4:40