● Access2000・mdbファイルが壊れる場面と回避方法・解決方法

ファイルサーバにデータ専用のmdb(バックエンド)を置き、クライアントパソコンにプログラム専用のmdb(フロントエンド)を置いたときに、複数のクライアントからサーバのmdbに同時アクセスすると、そのmdbが壊れやすいことがあります。
(mdbファイルをバックエンドとフロントエンドに分けない場合のほうがもっと壊れやすいかもしれません。その場合は分けてからこの記事を読んでください。でもOplockの設定変更はそれよりも前に一度、試してみてください。)

そのときの状況や解決のヒントなどをご紹介したいと思います。

★ 壊れる場面

mdbファイルをバックエンドとフロントエンドに分けずに作ったことがないのでよくわかりませんが、多分、そのように「分けずに作った場合」で、かつ、「多くの人が同時アクセス」をすると、基本、壊れやすいのではないかと思います。(ほんと、よくわかりませんのでスミマセンけど・・・。)

でも、mdbファイルをバックエンドとフロントエンドに分けて「クライアント・サーバもどき」(2層クライアントサーバ?)で利用をしているときも、「同時アクセス数やデータ量などに関係なく」「確実に壊れる」場合があります。

そのようなmdbファイルがよく壊れるのは、例えば次のような場合です。
(adpファイルは違います。)

(01)ファイルサーバ側で「 ”サーバとしての” Oplock」のレジストリ設定をしていない場合。

(02)連結フォームだらけの場合。
クライアントPCのフロントエンドのmdbの中に作ったフォームが、「ファイルサーバ側のmdbのテーブルとの ”連結フォームだらけ” 」で、かつ、それを多くのクライアントから同時に開き、なおかつ、閲覧のみならず更新・追加・大量ループ処理までガシガシ使ってしまっている場合

(03)日本語を含む名前を付けたフォームやレポートを、他のmdbからドラッグでコピーなどをした場合。(特にAccess2000のSR-1)
  
  
※逆に言うと、ここに注意して逆にして作れば、「まず壊れない」です。
当方でも、クライアント数30台弱、同時アクセス数:常時5~10で、Access2000のmdbで、システムができてから「19年」以上、1度も壊れてません。
ファイル容量は日報が250MB、売上が250MB、顧客マスタが60MB、くらいです。
どれも1回も壊れてません。
大きな機能別にサブシステム化している(あんど、外部mdb同士であっても参照整合性をとれるように自前の参照整合性のプログラムを作った)からかもしれませんけど・・・。
これから壊れるのかな?
気をつけよっと・・・。

  
  

★ 壊れる場面ごとの対処法

(01)ファイルサーバ側で「 ”サーバとしての” Oplock」のレジストリ設定をしていない場合。

※Windows98では発生しない問題かもしれません。Win2000以降では必ず対策します。
※また、Windows98では、リンクテーブルが遅くなる問題も起こりにくいです。

~以下、本文です。~

この場合、例えば以降の(a)~(c)のような時に、確実にmdbが壊れます。

(a)mdbに数台の同時アクセスがあるのにそのmdbをバックアップした時
(b)テーブルに対して多数の一括置換や全件ループ処理などをしたとき
 (数台かのクライアントが同時アクセスしているときに。)
(c)通常時に同時アクセスの数が増えたとき(本当の理由は不明)
などなど。

なので、この「サーバー側のOplock設定の変更」は、Accessで何かを作るとき、一番最初に知っておくべきこと、回避設定をしておくべきことです。

解決するには、ファイルサーバ側で「Oplock」のレジストリ設定を「サーバ用設定のほう」を変更します。
「Oplock」のレジストリ設定は「クライアント用設定のほう」もありますので、「サーバ用設定のほう」を間違えずに変更します。

また、サーバ側のOSがちゃんとしたサーバOSじゃなくて、クライアント用の2000やXP、Vista、7、などの場合でも、それは「サーバ」と見なせますので、そのクライアントOS上で、Oplockの「サーバ用の設定」のほうを、レジストリ上で変更します。

なお、設定は サーバ側だけでよく、クライアントパソコンのほうは 基本的には不要です。
いずれの場合も、使っているOSがサーバOSでもクライアントOSでもどちらであっても、「実質」の「サーバ側」と「実質」の「クライアント側」という形で見て、基本としては「実質のサーバ側」だけに設定します。
それだけで治らなかったら「実質のクライアント側」にも設定をしてみます。

設定方法については、詳しくは以下の記事を参考にしてください。

Access2000 100MbpsLANのファイルサーバに配置したmdbファイルへの同時アクセスにおいて、mdbファイル破損を激減させるサーバ側のレジストリ設定(Access2000昔からの既知の問題の解決)

この「Oplock」の設定をサーバ側でやっておかないと、ケースによっては、どんなに頑張ってmdbを作り変えても、mdbが壊れ続けます。

なお、mdbを置いている場所が「NAS(ネットワーク接続ハードディスク)」の場合、OSがLinuxである場合も多いと思います。その場合は、SAMBAでOplock をOFFにすると良いようです。
でも僕なら、NASはOplockの問題が無くてもNAS自体がアクセス数の増加によって壊れやすいイメージがあるのでめんどくさいので、3000円くらいのマシン買ってきてWin2000入れてセキュリティの設定だけしてレジストリでOplockはずしてしまいますけど・・・。
そもそもファイルサーバ上でも色々と自動処理したいので、OSがLinuxだと自動処理の仕方がわからないし・・・。
以下のWeb記事などもご参考にしてみてください。

はまった~~~(-_-;) NASで、oplockのせいで・・・
Windows7でsambaのファイルがうまく開けない件について(oplocks死すべし)
  
  
(02)「連結フォーム」だらけの場合。
クライアントPCのフロントエンドのmdbの中に作ったフォームが、「ファイルサーバ側のmdbのテーブルとの ”連結フォームだらけ” 」で、かつ、それを多くのクライアントから同時に開き、なおかつ、閲覧のみならず更新・追加・大量ループ処理までガシガシ使ってしまっている場合

このような場合も多分壊れやすいとは思います。
つまり、アクセスしている全員が、連結フォームを開いてしまって、何分も何十分も同じテーブルやレコードに常時アクセスしているような状態です。
(用が無くても、多くのユーザーは画面を閉じるのがめんどくさいのでフォームをひらっきっぱなしにする傾向があります。しかもいくつものフォームを。)

※ 補足 「連結フォーム」と「非連結フォーム」について
▼「連結フォーム」とは、Accessの専門用語のひとつです。「連結フォーム」では、テーブルの「列」とフォームの「テキストボックス」が、まるでトンネルででもつながっているかのようにリンクしていて、フォームに、レコードごとの各列の値を表示(=閲覧)する動作が「全自動」であり、そのほか、データの修正・削除・追加、にも、一切のプログラムが要らない「全自動フォーム」のことです。Excelで言うと2003までのメニューの「データ→フォーム」でのオートフォーム機能の超高機能版・・・、といった感じです。「全自動」なので入力・更新等の機能作成の工数がめちゃくちゃ少なく、クライアントサーバもどきで使用しない「パーソナル使用」の場合は本当に便利で、作ることに面倒がありません。ただし、クライアントサーバもどきでmdbを共有使用する場合は、フォームが開かれているあいだじゅう、常時、テーブルとフォームが「リンク状態」になります。つまり、複数のクライアントPCが「メインとしてよく使われる同じ連結フォーム」を同時に開けば、常にそのフォームと連結したレコードまたはテーブル(レコード管理機構とテーブル管理機構)が長時間、共有使用されていることになります。同じフォームが開いているあいだじゅうずーっと「すべてのレコード・あるいはテーブル(レコード管理機構とテーブル管理機構)を共有している・・・」というイメージなので壊れやすくなると言えばそうかもしれません。
また、mdbをプログラム専用とデータ専用に・・・、つまり、フロントエンドとバックエンドを分けずに使用している場合は、レコード(またはテーブル)のみならず、フォームまでもを「ずーっと常時」共有することになるので、「フォーム機構、テーブル機構、レコード機構、および実データ、すべての機能(動作)とデータを全員で共有してしまっている・・・」ということになりますので、さらに壊れやすくなる可能性が上がるかもしれません。
▼「非連結フォーム」もAccessの専門用語のひとつです。連結フォームとは逆で、テーブルの「列」とフォームの「テキストボックス」がリンクしておらず、フォームに各列の値を表示(=閲覧)・修正・削除・追加、をするには、逐一その手のプログラムが必要なフォームのことです(「その手のプログラム」=フォームの各テキストボックスに、目的のレコードの各列の値を転記して表示させるプログラムです。つまりフォームが作業テーブルのような役割りをします)。
「リンク状態」「共有状態」になるのは実質的にはテーブルだけで、また、それも、データの修正・追加・削除の、各一瞬一瞬ごと、となります。
連結フォームのようにフォームを開いているあいだじゅう、すべての機構や実データが共有使用されるわけではありません。
Accessなどが出るまでは、多分「非連結」のような形のフォームが一般的だったのだと思います。また、ブラウザをフォームがわりにして、「PHPやVBScript、Accessのデータアクセスページ、などでテーブルのデータを表示(=閲覧)・修正・削除・追加、をする場合」は、すべてこの非連結、のかたちとなります。また、最初からフロントエンドとバックエンドが分かれる形ともなっているため、なのでもともとどんなソフトであっても破損の可能性・確率も少ないし、常時サーバ側に接続してないので同時接続数がOSの限界を超えたかのように見えることもあります。

基本、連結フォームはデータの参照(閲覧)のみとし、更新、追加、ループ処理、などについてはワークテーブルを作成して使うほうがmdbファイルの破損が少ないです。(特に大量ループ処理に注意。)

クライアント側のワークテーブルにいったん加工対象のレコードをすべてダウンロードし、そして、例えばその修正結果は、更新クエリを使うとか、あるいは、DAO・ADO・DoCmd等々を用いたVBAプログラム上でSQLを使うとかをして、サーバ側のmdbにアップロードします。

つまりは、レコードの閲覧時以外は、テーブルやレコードにアクセスする時間を、「ほんの一瞬・0コンマ数秒の瞬間だけ」、にする、ということです。(フォーム側でも閲覧のみのモードの画面と、追加や編集のモード等々の画面を明確に分けることが必要です。「連結フォーム」のように閲覧モードで即更新もできてしまう・・・、つまり、「閲覧も修正も追加も削除も追加も全部、一つの連結フォーム直接いじりで」とはしないことです。作り変えや機能追加、メンテ等々を考えた場合、「閲覧のみを連結フォームにする」というだけでも、完全な非連結のフォームばかりでやることに比べれば、工数的に、かなり少なくてラクになります。)

ワークテーブルを使うことで「複数の人が、それぞれ常時同じレコードを見て1分以上アクセスしてる」「複数の人が、常時同じテーブルを開いて1分以上アクセスしてる」というような状況を極力減らせます。

基本的には、実データはすべてサーバに置いてリンクテーブルで、そして、一時テーブルはすべてローカルに置いてこれもリンクテーブルで、という形にします。

なお、ワークテーブルとしての一時テーブルは、クライアント側(ローカル)の別のmdbの中に置きます。
そして、それをリンクテーブルとします。サーバ側のmdbの中には、ワークテーブルを置かないようにします。
このように「一時テーブルもリンクテーブルとする」ことで、プログラム専用のmdbの破損をさらに低下させると同時に、プログラム専用mdbの容量肥大化も防げます。

もう少し言うと、「フロントエンドのプログラム専用のmdbの中には、基本的には実テーブルは一つも置かない」ようにします。もともとクライアント側の別mdbに一時テーブルを置いて、それのリンクテーブルを作成した場合、そのリンクテールの数はどれだけ多数作っても、どう更に別のmdbに入り組んでも、速度低下はほぼ起こりません。
また、前述のとおり フロントエンドのmdbも容量肥大が起こりませんし、プログラム専用のmdbのメンテナンス自体もとてもラクになります。(メンテナンスをするのに、システム全体を止めなくていい、一時テーブルの内容をバックアップしなくていい、などなど。)

なお、クライアントのインターフェイスをmdbで作らずに、例えば ブラウザを使う場合・・・、例えばHTMLでVbScriptやPHPなどを使ってサーバのmdbにアクセスすると、とたんにmdbが破損しなくなったり、サーバ側がクライアント用OSなのに同時アクセス可能数が急に10台超え、20台超え、50台越えが可能になったりする(ように見える)ことがあります。

それは『インターフェイスに ブラウザ+HTML+VbScriptやPHP等を使うことで、結果的に自動的に、”連結フォームを使用しなくなる” から』そういうことが可能となります。同じ理由で、バージョン2000の場合は「データアクセスページ」を多用することでもmdbの破損を回避できます。

  
  
(03)日本語を含む名前を付けたフォームやレポートを、他のmdbからドラッグでコピーなどをした場合

これも壊れることがあります。
「ネットワークがどうのこうの」という一見無関係な感じのエラーが出て、二度とのmdb自体が開けなくなります。
多分、絶対に直らないので、あきらめてファイルを捨てます。
バックアップが取ってない場合は、大変残念ですが、あきらめるほかなさそうです。(もしかしたら治す方法があるのかもしれませんが・・・。私の記憶では外部からの最適化すらできなかったような・・・。でも私だけかもしれないので、試す価値はあるとは思います。)

特にバージョン2000。
かつ、特に、VBAコードを含むフォームやレポート。
VBAが1行も書いてないフォームやレポートは多分大丈夫です。

次回から 回避するには、半角英数のフォーム名を付けます。
もしくは、他のmdbからコピペする直前だけ半角英数の名前に変更し、コピペ後に日本語名に変更します。
VBE本体ファイル(VBAj自体の実行ファイル)の「VBA6.DLL」を「Office2000:SP3」などの 新しいものに上書きすることで解決する場合もありますが、それで解決しない場合は多分ですけどこれしか回避方法が無いと思います。

※事前テストをご自身で必ずおこなってください。

  
  

※関連記事

Access2000・100MbpsLAN Pentium3 の「ネットワーク越しのリンクテーブル」の開く速度が遅いときの対処法(Access2000のときからあった既知の問題)

Access2000・mdbの動作速度をネットワーク越し利用でも速くする方法~結構重要~:★ ダミーテーブルの連結フォームを非表示で常時開いておく

100MbpsLAN Pentium3 でクエリが遅い場合の対処方法(データベース自体が遅い場合にもチェックしてみます。)

Access2000・mdbファイルが壊れる場面と回避方法・解決方法

Access2000・100MbpsLANのファイルサーバに配置したmdbファイルへの同時アクセスにおいて、mdbファイル破損を激減させるサーバ側のレジストリ設定(Access2000昔からの既知の問題の解決)

Excelが遅くなる場合の対処法~Accessや他のソフトからデータを貼付けした時

  
  

Excelが遅くなる場合の対処法~Accessや他のソフトからデータを貼付けした時

Access2000VBA・Excel2000VBA独学~VBAプログラミングとはどんなプログラミング方式なのか?(簡易版)

Access2000VBA・Excel2000VBA独学~用語:VBAプログラミングでの「オブジェクト」 について

ExcelでもAccessでも、顧客台帳(顧客マスタ)を作るときのヒント(できるだけ細かくしてしまう)