「馬吉」の改造が進んでくると、多くの箇所で無限ループに入ったり、砂時計が出たままの状態になったり、UnKnown エラーが出てプログラムが停止していまいます。
通常はタスクマネージャを呼び出して停止させるのですが、それすら出来なくなったりする場合もあります。
推定ですが、「馬吉」はメモリーを大量に消費するソフトのために、OSの動作さえも脅かすのではないかと考えております。
なぜ大量のメモリーを使用するのかと言うと、それはプログラムを高速に動作させるためです。
数十万件〜数百万件をのデータの中から、データを取り出すためには、出来るだけデータをメモリーに取り込んだ状態で動作させた方が動作上有利です。
「馬吉」に限らず、著名な競馬データの検索ソフトの多くは、メモリーを大量に消費しますのでメモリー管理がハード、ソフトとも適切に動作しないと不安定になります。
ここでは、私が改造中に嵌った点などを中心に記載します。
OpenTableDirect は標準モジュールの、basMain に記載されているコードです。
内容は以下の通りです。
' ' 機能: レコードセットを開く ' ' 備考: なし ' Public Function OpenTableDirect(rs As ADODB.Recordset, cn As ADODB.Connection, TableName As String) As Boolean On Error GoTo ErrorHandler rs.CursorLocation = adUseServer rs.Index = "PrimaryKey" rs.Open TableName, cn, adOpenKeyset, adLockReadOnly, adCmdTableDirect OpenTableDirect = True Exit Function ErrorHandler: gApp.ErrLog OpenTableDirect = False End Function
このサブルーチンは、多くの場所から呼び出されており、「馬吉」の中枢のプログラムの一つになっています。
データベースをオープンさせるだけのためのものです。
少なくとも私は最初はそう思っておりました。
データベースを SQLite にした場合に、 rs.Index = "PrimaryKey" の部分がプロバイダがサポートしていないとのエラーが出ましたのでコメントアウトしました。
その結果、このサブルーチンを抜け出すのに気が遠くなるような時間が掛かるようになります。
データの量によっては、OS が停止してしまいます。
今ならはっきり言えますが、「馬吉」公開版を改造して SQLite のデータベースで動作させるのは無理があります。
「馬吉」に記載されているデータベース関係のコードそのままでは使用出来ない場合が余りにも多過ぎます。
ここでは、rs.Index = "PrimaryKey" の Index で引っかかりましたが 「馬吉」で数多く使用している Seek も使えませんし、 MoveFirst は使えますが、MoveLast は使えません。
SQLite が機能が劣っていると言うよりは、アクセスには便利に使えるコードが多いからと考えた方が良いと思います。
ひょっとしたら、MySQL や、SQLServer は「馬吉」のコードをいじらなくてもそのままで動くかも知れません。
こちらも時間が取れたら確認したいと思います。
逆に言えば、SQLite で問題なく「馬吉」が動くようなコードに組み替えれば、全てのデータベースで動くようになるのではないかと考えています。
コードの書き換えは、処理内容を理解してから行なわなければなりませんので手間の掛かる作業ですが、やり方によっては処理速度の向上も図れると思います。
そこまで手間隙掛けて、「馬吉」を改造するのに意義があるのかは考えない事にしましょう。
話を戻しますが、SQLite で問題が起こるのはメモリー上に呼び出したデータベースのレコードセットの Index 情報を全て取り込むためではないかと思います。
SQLite の場合は、バッファをOSの持つメモリーの上限まで使用してしまうとの解説サイトもありましたが、詳しくは調べておりません。
このサブルーチンを呼び出す場合の呼び出し方は、多くの場合以下のようになっています。
Set mRS_UMA = New ADODB.Recordset If OpenTableDirect(mRS_UMA, mCN_UMA, "UMA") = False Then Set mRS_UMA = Nothing End If
テーブル UMA のデータベースをオープンさせるだけのためのようです。
このコードの場合はオープンした時にテーブルが無かったら(オープンエラー)レコードセットを閉じるようになっています。
SQLite で使用した場合は、どうやら問題がありそうでしたので以下のように呼び出し方を変更しました。
Set mRS_UMA = New ADODB.Recordset If OpenTableDirect(mRS_UMA, mCN_UMA, "UMA WHERE KettoNum = '" & ***** & "'") = False Then Set mRS_UMA = Nothing End If
呼び出す場合にWHERE句をつけてデータをフィルターにかけるように修正しました。
これで無限ループにでも入ったのではないかと思えるような現象はなくなりまいたが、単にデータベースのオープンに使っているだけのコードでしたので、「馬吉」のプログラムのコード配置をそのままでは使う事が出来なくなりました。
特にここにWHERE句を書いてしまったために、元々 WHERE句として使用していた標準モジュール basMain の SafeSeek と競合する事になり、このコードを削除して OpenTableDirect の記入位置を変更しなければならないなど、とんでもなく手間のかかる作業が必要になるようになってしまいました。
もう少し利口なやり方がないものかどうか、今でも考えております。
解決方法では無いのですが、現在は OpenTableDirect を使用しないで以下のような普通のコードにしています。
これは、clsDataRA のFetchに実際に記載しているものです。
'------------- ' RACE情報取得 '------------- Set rs = New ADODB.Recordset rs.Open "RACE WHERE [KeyCord] = '" & mKey.KeyCord & "'", mCN_RACE, adOpenKeyset, adLockReadOnly, adCmdTableDirect ' データが無かったらFalseを返して終了 If rs.EOF Or rs.BOF Then rs.Close Set rs = Nothing Fetch = False Exit Function End If ' RACEレコードをすべて構造体で保持する Call SetDataFromRS_RA(rs, mBuf_RA)
KeyCordは、私のデータベースには Year、MonthDay、JyoCD、Kaiji、Nichiji、RaceNum を連結して登録してあります。
【後記】
OpenTableDirect に記載の rs.Index = "PrimaryKey" の所で常にエラーになるため、SQLite がサポートしていないコードか、接続形式の違いでエラーになっているものだとばかり思っていました。
後で判ったのですが、ここに記載してる"PrimaryKey" は、一般的なプライマリーキーを指すのではなく、「馬吉」では固有名詞として使用していたのです。
つまり、「馬吉」では OpenTableDirect を全てのデータベースから共通に呼び出せるように、全てのデータベースのプライマリーキーの名称を PrimaryKey としていたのでした。
このようなサブルーチン方式が良いかどうかは別にして、「馬吉」を移植するだけなら私のような手間を掛ける必要は無かったかも知れません。
データベースが常にインデックスを使用するとは限らないらしいので、rs.Index = "PrimaryKey" のような記載がしてあるでしょうか。
これは、ひょっとしたらテクニックなのかも知れません。
「馬吉」ではデータベースの騎手の項目の書き方を KISYU ではなくて KISHU にしています。
念のために他のデータベース作成ソフトの項目の書き方も調べてみましたが、騎手は KISYU と書くのが一般的のようです。
「馬吉」を作成したプログラマーの勘違いだと思うのですが、騎手のデータは KISYU になっているものだと思っていると騎手関係のデータは一切表示されなくなります。
その他にもオッズ関係のデータベース項目にも「馬吉」独特の名前が使われている部分がありますから注意してください。
こちらはそのようなテーブルがありませんとエラーが出ますから、嵌ることは無いのですが。
オッズの「馬吉」独特の表示とは、PayWakurenKumiban1 のように ban が入っている事です。
それと、テーブルの RECORD にも独特の記載があって、それは TokuNum_SyubetuCD の部分で、通常は _SyubetuCD は記載しません。
おまけにこの部分は、6文字分を「馬吉」はテーブルに確保しておりますが、JRA-VAN からは4文字固定ですので余分に確保しているようです。
実害は多分ないでしょうが、これはミスだと思います。(この点は、実際はごちゃごちゃしていて故意なのかミスなのかは断定できません。)
【追記】
TokuNum_SyubetuCD の部分が故意なのかミスなのかについてですが、私は以下のように考えております。
他の項目では、JRA-VAN から提供されるデータを統合してデータベースに記載している部分はありませんので、テーブル作成漏れのミスではなかったかと考えております。
その後に作成漏れに気が付いた時点で、新たにテーブルを作成するのではなくて、TokuNum のテーブルに SyubetuCD を追加したのではないかと考えております。
この考えが正しいか間違っているるかですが、どちらにしてもプログラムが正常に動作すれば良い事ですから、「馬吉」にとってはどうでも良い内容でしょう。
クラスの検索モジュール(clsDataFind)に出てくる RegExp を知っているプログラマは少ないと思います。
当然の事ながら私のレベルでは始めて見る単語でしたので、サイト内を調べまくりました。
解説によれば、正規表現オブジェクトを生成します。と一言なのですが、これだけでは何の事か判りません。
正規表現とは何かを書くと、ちょっとした量の解説になってしまうようです。
私が下手な解説を書くよりは、今はインターネットで調べた方がず〜と詳しくその人のレベルに合った解説を得る事ができます。
テクニックにも書きましたが、「馬吉」はこれを利用して高度な検索を実現しておりました。
SQlite は、レコードセットの Movenext コマンドは受け付けてくれますが、MovePrevious コマンドを使用すると以下のエラーが発生します。
「実行エラー このコンテキストで操作は許可されていません。」
又、MoveFirst コマンドは受け付けてくれますが、MoveLast コマンドでは以下のエラーがでます。
「実行エラー 行セットは逆方向フェッチをサポートしていません。」
こんな基本的なコマンドも使えないのは変だとは思いましたが、サポートしていないなら仕様だろうと思っていました。
実はそうではありません。
SQLite は、レコードセットをオープンした場合にデフォルトの設定が、アクセスや MySQL と異なるのです。
例えば、RS.Open SQL, Cn と全くオプションをつけない場合はの SQLite の設定は以下のようになると思われます。
RS.Open SQL, Cn, adOpenForwardOnly, adLockReadOnly
この設定は、前方向のみのアクセスだけが可能で、処理はもっとも速くなるのですが、MovePrevious や MoveLast コマンドは使えなくなるようです。
これに対して Access や MySQL のデフォルトは、
RS.Open SQL, Cn, adOpenStatic, adLockPessimistic ではないかと思われます。
そのためオプション設定をしなくても MovePrevious や MoveLast が使えるのではないでしょうか。
実用性が第一の SQLite に対して、動作スピードよりは無用なトラブルを避ける事を重点にしている Access や MySQL と考えても良いのではないでしょうか。
どちらが標準規定に基づいているのかは不明ですが、大文字と小文字を区別しない点なども含めて、一般的なデータベースとは異なる点も多いようです。
兎に角、MovePrevious が使えないために、プログラムの変更に悩んでいたのが解消して万々歳となりました。
移植が進んでタイトルバンドにタイトルを表示しようとした時の事である。
タイトルバンドと言うのは、メニューバーから2番目に表示されるバーで表示の内容とレース場の選択やレースを選択するコンボボックスなどが表示されている。
通常は、Fetch の時に mstrTitle = "何とかかんとか" と設定をすれば、その内容が表示されるのだが、全く表示されなかったり表示内容が欠けて表示されたりする。
原因が判らず、これには相当悩んだが、どうやら()が関係しているらしい事が判って、ようやく原因が判った。
何と ctlTitleBand で、以下のような記述がしてあるのである。
' 場選択コンボボックスを表示するとき
' もともとタイトルバンドに表示していた回場日と重複する為
' 出馬表タイトル文字列の曜日の ")" 以降を削除する
' ※出馬表タイトル文字列はウインドウタイトル、履歴にも用いている為
' タイトルバンドでのみの例外処理として、ここで削除している。
Me.Caption = Left(Me.Caption, InStr(Me.Caption, ")"))
これでは、表示しない場合があるのも欠落する場合があるのも道理である。
もう少し、気の利いたやり方がなかったのだろうか。
ウインドウタイトルは兎も角としても、履歴にも用いているとはどういう意味なのだろうか。
進むや戻るが正常に動作しなくなると言う事なのだろうか。
不安を抱えながらも、この構文はコメントアウトした。
馬名検索でカンパニーと入力してみました。
画面の中心にプログレスバーが表示されて検索されております。
1回、2回・・・何度プログレスバーが巡回しても、カンパニーの情報は表示されません。
1分、2分・・・無限ループにでも嵌ったのだろうとプログラムを強制終了させようと思った頃にやっと表示されました。
騎手とか調教師の検索は直ぐに終了するので原因はほぼ判っています。
日本名(全角カナ)の馬名のインデックスは作成してあるのですが、英語名のインデックスは使わないので作成していなかったからです。
「馬吉」はご丁寧に馬名検索の場合に英語表記でも検索しています。
テキストボックスにカンパニーと入力した場合に、日本語の中に該当するのがあるかどうか調べると共に英語表記のなかにもカンパニーがないかどうかを調べているのです。
これでは検索が遅くなるのは当たり前です。
早速、英語表記のインデックスも作成しようと考えました。
しかし・・・。
これってマイクロ何とかさんのOSに良く出てくる余計なお世話機能ではないのかと思いました。
ディスクトップの使わないアイコンを整理しますかとか余計なお世話が多くて、余りにもたびたび出てきてむかついたので出ないようにする方法を必死で調べてやっとの事で対処しました。
この場合は、日本語と英語と両方で検索するのはとても気が利いているように見えて、実は何のメリットもないばかりか検索を遅くするためだけの余計な事に思えてきたのです。
日本人ならカンパニーと入力しますから、時々Company などと入力する人は余程の変人でもない限りいないはずです。
私の知能レベルではスペルを思い浮かべるのにも一苦労します。
もし日本人以外の人(英語)が使う事を考慮するのなら、言語設定を行えるようにしてメニュー部分から英語にすべきでしょう。
その方が遥かに気が利いていると思います。
言語設定まで行えるようにするかどうかはもう少し考えて見ますが、英語のインデックス作成は止めて日本語だけの検索にするように変更しました。
変更はクラスモジュールの clsDataFind のFetch の部分を変えるだけです。
'strSQL = strSQL & " OR [BameiEng] LIKE " & ByModeUMA(Key, Mode) とコメントアウトするだけでプログレスバーは一周もする事なくカンパニーのデータは表示されました。
メモリーキャシュの残っている状態のテストなので、本当に直っているのかどうかを確認するために後で再度調べてみる事にします。
実は騎手も調教師も同じように英語表記でも検索しているのですが、データ量が桁違いに少ないので検索は直ぐに終了するのです。
ちなみに「馬吉」の公開版でカンパニーを起動直後に検索してみたら私のパソコンでは1秒もかからないで表示されました。
データ数もほぼ同じで英語表記を含んでの検索ですから、さすがに良く最適化されていると思いました。
検索を選んだ時に、前もって競走馬のインデックスをメモリーに読み込んでいないとこうは速く動きません。
変更箇所のページにも記載したように、検索方法を変更した事によって騎手を検索する場合でも、’よこやま’とひらがなで入力しても横山典弘騎手をはじめ7名の騎手が瞬時に検索できるようになりました。
欧文で’nori' と記入すれば横山騎手の他に頭にNがつく騎手が地方、外国招待騎手も含めて13名が瞬時に検索できます。
馬名検索でも、ひらがな、カタカナ共に高速に検索できましたので、何の問題もないように思えましたが、馬名の欧文の検索に異常に時間が掛かる事に気が付きました。
最初はインデックスの作成を忘れていたのだろうと思っていたのですが、馬名欧文のインデックスを何度作成し直しても全く変化がありません。
どうやら、欧文のインデックスが作成できないか、作成状態がおかしいようです。
馬名の欧文のフィールドを調べてみると、これだけが80文字(80バイト)確保してあります。
カタカナの大文字と小文字が36文字なのと比較すると2倍以上の確保量です。
勿論、この確保量はJRA-VANの指定であり、私が勝手に決めたものではありません。
欧文の馬名だけが異常に多い確保量なので、実際に欧文の馬名の長さを調べてみました。
13万頭余の登録馬の中で欧文の馬名が80文字近い馬などは1頭もおりませんし、30文字でも十分過ぎるようです。
そこで、インターネットで競走馬名のルールを調べてみました。
そうすると「競馬と生産に関する国際協約」(パリ協約)と言うのがあって、日本もそれに沿っている事がわかりました。
それによりますと、馬名の長さはアルファベット18文字(空白を含む)までと決められているようです。
日本の場合は、1928年以降は馬名はカタカナに統一され、2文字以上9文字以内までとなっています。
使用できる文字も決められており、’・’の使用は出来なくなったりしています。
’ヴ’と’ヲ’の使用も用法に制限があり、「エアグルーヴ」や「エガオヲミセテ」「キヲウエタオトコ」など一部の変人的な馬主が使用するのみのようです。
これによれば、確保する文字のバイト数は18バイトで十分と思われます。
但し、輸入された種牡馬や繁殖牝馬、ジャパンカップなどの国際招待競走でカナ馬名にすると’テイクオーバーターゲット’のように12文字のような馬がいるために、若干の余裕が必要のようです。
それでも、30バイト(15文字分)もあれば十分でしょうし、JRA-VAMが馬名に36バイトも確保しているのは、決められたバイト数(18バイト)の2倍にしておこうと単純に決めたような気がします。
欧文名の80バイトの確保は私には不可解と言うしかなく、基本的には18バイトの馬名に若干の余裕を見るだけで十分と思われます。
それなら、30バイトでも十分過ぎると思いましたが、日本名の確保量に合わせて36バイトに減らす事にしました。
これだけ減らしても、今後も99.9%以上の確率で登録エリアが不足する事は無いだろうと考えております。
もし、フィールドの文字数の確保量の影響でインデックスが旨く作成されなかったのでしたら、これで解決できているはずです。
それまでは、80バイトの確保量は残したままで、検索用の数バイトのフィールドを作成して高速な検索を行わせようかと思ったのですが、36バイトなら支障なく検索できる事が確認されておりますので、これだけの変更に留めることにしました。
果たして、これで解決できたのでしょうか。
【後記】
テーブルの長さを JRA-VAN の指定のものから変更(短く)する事は検索には有効なようですが、異なるデータベースの変更などの処理の場合にトラブルが多くなります。
データの組み込む領域が狭くなるためで、変更プログラムはそこで停止してしまいました。
エラーが発生した場合に強制的に解除させるようにしておればプログラムが停止する事はなくなりますが、そのデータはデータベースに記録されません。
結局、テーブルの長さをいじるのは止める事にしました。
「馬吉」では各画面でタイマーの使用が目立ちます。
ゲームプログラムでは、タイマーを使用して画面を動かさなければゲームになりませんが、データベースの表示でこれだけ多くのタイマーを使用しているのは珍しいと思います。
一般的にタイマー動作は、裏で作業を行うために使用いたしますが、タイマーは勝手気ままに動作するために、タイミングによっては思いもかけない動作をします。
例えば3秒以内に処理が終了しなければ別な動作を行わせているような場合には、解析のために途中で動作を止めた場合には、再実行しても正常な動作を行いません。
「馬吉」では、このような処理が多いために、解析作業が難しくなっています。
タイマー動作は、最適化されて動作している場合は快適な処理を行いますが、そうでない場合には処理が遅くなる場合もあります。
タイマーの動作内容を調べて、必要性の薄い場合にはタイマーの使用は止めるべきでしょう。
大概の処理は、タイマーの力を借りなくても、OSの処理だけで動作するものです。
画面別のタイマーの動作内容を調べて見る事にしました。
タイマーの動作をオフにした時にどんな不具合が生じるのかを見てみるのが早そうです。
frmBrowser にはタイマーが1つあります。
ツールバー表示タイマーイベントとプログラム内にコメントが書いてある通り、タイマーを動作させないとツールバー内に画像が表示されません。
ツールバーを表示するとタイマー動作はオフになるようですから、ツールバーだけに使用されているようです。
タイマーで表示すると処理が速いのでしょうか。
それとも、処理が単純化できるのでしょうか。
現在も検討中です。
プログレスバーの表示にはタイマー動作が必須です。
これは、当たり前の話ですから、必要かどうかを調べるまでもありません。
「馬吉」はマウスのカーソル位置を調べるのにタイマーを使用しております。
これもどちらかと言うと、珍しいと思います。
フレキシブルグリッドの特定の位置のカーソルの検出は、フレキシブルグリッドにもありますから、そちらで行わせる事も出来る筈です。
個人的には画面がちらちらして好きではないのですが、アイディアの一つでしょう。
タイマーの動作を気にするようになったのは、データベースのアクセス時間がなかなか短くならなかったためです。
出来るだけメモリーに大量のデータを抱え込んで処理すれば速いのですが、最初の1回の読み込み時はどうしても時間がかかりますし、どうやら SQLite はOSのメモリーを大量に消費する気がしますので、メモリー展開で処理する方法は避けたいと思っています。
JRA-VAN からのデータの取得を、票数データ以外の全てのデータを取り込むようにしましたので、取得が終わる迄にかなりの時間を要します。
私のパソコンには、JRA-VAN の基本データは全て最新の状態になっていますので、新規にJRA-VANからデータのダウンロードを行う必要はありません。
それでも、西暦2000年からのデータのデータベースの構築が完了するまでには9時間程度掛かります。
「エクセル競馬予想 馬ちゃん」の時は、取得するデータを制限しておりましたので、3時間程度でデータベースの構築は終了しておりました。
ちなみに、私のパソコンのCPUは、AMD Athlon X2 3800+ で4,5年前なら高速の部類に入っていたのですが、今では平均以下のレベルでしょう。
それでも、私の古いパソコンのアスロンの2800+でデータベースを構築すると、20時間程掛かりましたから、標準的なノートパソコンや古いパソコンを使用している人は同程度の時間が必要かも知れません。
ゲームをやる人は、常に最高性能のパソコンを使用するのが当たり前ですが、競馬で儲けたいと思う人も常に最高性能のパソコンを持つべきだと思います。
なぜなら、仮に借金してパソコンを買った人は、それを返すために努力するでしょうから、それだけ力を入れて競馬予想を行います。
それが、どこからか拾ってきたようなパソコンを使っているような人は、どうせ当たらないだろうけどと競馬予想の意欲の点で最初から異なっています。
私にはケチな人間には競馬予想は無理(当たって欲しくない)と言う願望があるのかも知れません。
ケチの意味にも数種類あって、私は何事にもお金をできるだけ使いたくない人のことを言っているのですが、それよりもスケールの小さい人とと言った方が私の言うケチに近いと思います。
くだらない話はこのぐらいにして、本題のデータ変換に嵌る話をしたいと思います。
データのダウンロードに10時間近く掛かるのでは、さすがに限界に近いと思います。
今回は、2000年からのデータの取り込みでしたから、特に長い時間を必要としたのですが、2005年程度からでも、5,6時間は掛かるでしょうから何とかしたいと思いました。
たまたま、JRA-VAN からデータのダウンロード中に、JRA-VAN のサーバーのメンテナンスが始まって途中で途切れてしまいました。
それで忍耐の限度を越えた私は、「馬吉」のデータベースの内容から、直接 SQLite のデータベースに変換するデータベースコンバータープログラムの作成に着手したのです。
これが完成すると、今回はSQLite の変換でしたが、MySQL や FireBird や、その他もろもろのデータベースへの変換が楽に出来るようになるのです。
勿論、同じアクセス(Access)への高度な再構築にも使用出来ます。
このようなプログラムは、作成の難易度は低いのですが、作成に膨大な手間が掛かるので避けてきました。
JRA-VAN のサーバーのメンテナンスが終わる頃までには、とても完成するような代物ではありませんが、兎に角やる事にしました。
そこで嵌ったのが、馬毎レースデータ(UMA_RACE)の変換部分でした。
競走馬データ(UMA)の13万件のデータ変換やレースデータ(RACE)6万3000件などのデータ変換はすんなりと出来たのですが、馬毎レースデータがうまく変換できません。
このデータ量は巨大で76万件近くもあるのですが、何度作成しても63000件程度しか作成できないのです。
最初に考えたのは、データ量が多いのでコミットトランス(CommitTrans)を変換途中で1回も行っていないので、1000件データを取得する度にコミットさせても見ましたが変化はありません。
常識的に考えても、コミット出来るデータ量に制限があるはずはありません。
取り込みを行うフィルターは。以下の通りです。
strRaceKaisai = (rs1("Year") & rs1("MonthDay") & rs1("JyoCD") & rs1("Kaiji") & rs1("Nichiji") & rs1("RaceNum"))
strRaceKaisai にレースの開催の年月日や競馬場別、レース番号を設定しています。
このフィルターは特定のレース内容を取得するために、頻繁に使用しているものです。
もし、ここまで読まれて、私のミスの内容が自然に見つけられた人は、相当にプログラムに精通した方です。
私は、自分が日常的に使用しているプログラムコードだったので、直ぐには発見できませんでした。
問題点は、フィルターにあります。
strRaceKaisai = (rs1("Year") & rs1("MonthDay") & rs1("JyoCD") & rs1("Kaiji") & rs1("Nichiji") & rs1("RaceNum"))
このコードで、特定のレースの内容は問題なく表示されます。
(実際には、rs1("Kaiji") & rs1("Nichiji") の記載は無くても特定のレースを抽出できます。)
しかし、そこに盲点がありました。
確かに、競馬予想プログラムでは、特定のレース内容を表示させるのは、これで良いのですが今回はデータの変換プログラムですから、これでは駄目なのです。
これだけでは、複数のデータが該当するために、76万件のデータが63000件になってしまったのでした。
見つかってしまえば単純な事です。
同じレースに出走している馬が数多く存在していただけだったのです。
これでは、確かに全データから平均出走頭数で割っただけのデータしか変換できません。
年と共に私の知能レベルはどんどん低下しているようです。
【後記】
変更後のデータの記録時間ですが、76万件近くの馬毎レースデータ(UMA_RACE)の変換時間は、6時間掛かりました。
これは、単純に変換しているんでは無くて、データ内容を変えている事と、このデータから競走馬や騎手や調教師、馬主、生産者の過去走のデータも同時に作成しているためです。
これは、JRA-VAN からのデータの取得時にも行っておりますので、違いがある訳ではありません。
やはり、このデータ量は突出しております。
それから、コミットする間までに umachan.db-journal と言うデータベース名の後に -journal が付加されたファイルが自動的に作成されて、容量が150MBにもなりますので、10000件のデータを取得する度にコミットトランス(CommitTrans)を行う事にしました。
SQLite はデータ入力時にコネクションで BeginTrans を宣言しないとデータ1個を入力する度にBeginTrans とCommitTrans を繰り返して膨大な時間を必要とします。
その差は10倍程度はありますので、宣言しないと10時間で終わる作業が100時間も必要となります。
マイクロソフトアクセス(Access)の話なのですが、トランザクションを掛けた場合と掛けない場合の処理速度の差を調べていた時のことです。
処理中に、「ファイルの共有ロック数が制限を超えています」のエラーが発生しました。
サイトで調べて見ると、一万件を超えるようなテーブルをトランザクションかけてレコードセットで処理する場合に、アクセスでは発生する事があるらしい。
これの回避方法は、最大ロック数のMSX数(MAX初期値 9500)を増やしてやれば良いのだが、レジストリで設定を行っているようです。
仮に、自分のパソコンのレジストリの内容を変えて動作させたとしても、それを公開した場合は、使用する人のパソコンでは同様のエラーが発生する事になるでしょう。
トラブル対策としてエラーが発生した場合はレジストリのどこそこを変えてくださいと記載したとしても、エラー対策は見ない人が多いだろうし、使い物にならないソフトと評価を受けてしまうと思います。
アクセスで大量のデータにトランザクションを掛けるのは止めた方が良さそうです。
どうしても必要な場合は、ある程度の量でコミットさせるかとかしなければいけないと思います。
この対策を解説したサイトに以下のような方法もある事が記載されていたので抜粋しました。
私は実際にはこれを試してはいないので、動作の確認は取っておりません。
このサイトはマイクロソフトのサポート記事(http://support.microsoft.com/kb/815281/JA)からの抜粋との事です。
DBEngine.SetOption dbMaxLocksPerFile, 30000
Sub LargeUpdate() On Error GoTo LargeUpdate_Error Dim db As DAO.Database, ws As DAO.Workspace ' Set MaxLocksPerFile. DBEngine.SetOption dbMaxLocksPerFile, 200000 Set db = CurrentDb Set ws = Workspaces(0) ' Perform the update. ws.BeginTrans db.Execute "UPDATE BigTable SET Field1 = 'Updated Field'", _ dbFailOnError ws.CommitTrans db.Close MsgBox "Done!" Exit Sub LargeUpdate_Error: MsgBox Err & " " & Error ws.Rollback MsgBox "Operation Failed - Update Canceled" End Sub
上記がマイクロソフトで解説しているの回避方法のサンプルコードの全容です。
これを機会にアクセスのエラーコード一覧を作成してみました。
解説サイトのコピペですから、私は何の苦労もしておりません。
エラーの内容はエラー発生時に表示されますので通常は必要ありませんが、プログラムでエラー番号から分岐してエラー処理を行う場合は便利でしょう。
膨大な量がありますが、備忘録として記載する事にしました。
エラー 説明 2420 数値の構文エラーです。 2421 日付の構文エラーです。 2422 文字列の構文エラーです。 2423 '.'、'!'、または '()' の使い方が正しくありません。 2424 未定義の名前です。 2425 未定義の関数名です。 2426 この関数は式では使用できません。 2427 オブジェクトに値がありません。 2428 定義域関数の引数が正しくありません。 2429 In 演算子に '()' がありません。 2430 Between 演算子に対応する And がありません。 2431 構文エラー : 演算子がありません。 2432 構文エラー : カンマがありません。 2433 構文エラー 2434 構文エラー : 演算子がありません。 2435 不要な ')' があります。 2436 ')'、']'、または Item がありません。 2437 垂直バーの使い方が正しくありません。 2438 構文エラー 2439 関数で使用されている引数の数が正しくありません。 2440 IIF 関数に対応する '()' がありません。 2442 かっこの使い方が正しくありません。 2443 Is 演算子の使い方が正しくありません。 2445 式が複雑すぎます。 2446 メモリ不足のため、演算を実行できません。 2447 '.'、'!'、または '()' の使い方が正しくありません。 2448 値を設定できません。 3000 システムで予約されているエラー <アイテム> です。このエラーに対するメッセージはありません。 3001 引数が無効です。 3002 セッションを開始できませんでした。 3003 ネストされているトランザクションが多すぎるので、トランザクションを開始できませんでした。 3005 データベース名 <データベース名> は正しくありません。 3006 データベース <データベース名> は排他ロックされています。 3007 ライブラリ データベース <データベース名> を開くことができません。 3008 テーブル <テーブル名> はほかのユーザーが排他的に開いているか、既にユーザー インターフェイスを介して開いているので、プログラムによって操作することはできません。 3009 テーブル <テーブル名> は現在使用されているので、開くときにロックを試みてもロックできません。後で、再度実行してください。 3010 テーブル <テーブル名> は既に存在しています。 3011 オブジェクト <オブジェクト名> が見つかりませんでした。オブジェクトが存在していること、名前やパス名が正しいことを確認してください。 3012 オブジェクト <オブジェクト名> は既に存在しています。 3013 インストール可能な ISAM ドライバのファイル名を変更できませんでした。 3014 これ以上テーブルを開くことはできません。 3015 インデックスが見つかりませんでした。 3016 フィールドがレコードに適合しません。 3017 フィールド サイズが長すぎます。 3018 フィールドが見つかりませんでした。 3019 カレント インデックスを指定してください。 3020 Update または CancelUpdate メソッドには、対応する AddNew または Edit メソッドが必要です。 3021 カレント レコードがありません。 3022 インデックス、主キー、またはリレーションシップで値が重複しているので、テーブルを変更できませんでした。 3023 AddNew メソッドまたは Edit メソッドは、既に適用されています。 3024 ファイル <ファイル名> が見つかりませんでした。 3025 これ以上ファイルを開くことはできません。 3026 ディスクの空き容量が不足しています。 3027 データベースまたはオブジェクトは読み取り専用なので、更新できません。 3028 アプリケーションを起動できません。システム データベースが存在しないか、またはほかのユーザーが排他的にシステム データベースを開いています。 3029 アカウント名またはパスワードが正しくありません。 3030 アカウント名 <アカウント名> は正しくありません。 3031 パスワードが正しくありません。 3032 この操作は実行できません。 3033 オブジェクト <オブジェクト名> を使用する権限がありません。システム管理者またはこのオブジェクトの作成者から権限を取得してください。 3034 コミットまたはロールバックを実行するには、BeginTrans メソッドを使用してください。 3036 データベース サイズが上限に達しました。 3037 これ以上テーブルまたはクエリを開くことはできません。 3039 定義されているインデックスが多すぎるので、インデックスを作成できませんでした。 3040 読み取り中にディスク I/O エラーが発生しました。 3041 前のバージョンのアプリケーションで作成されたデータベースを開くことはできません。 3042 MS-DOS のファイル ハンドルが不足しています。 3043 ディスクまたはネットワークのエラーです。 3044 パス '<パス名>' は正しくありません。パス名に間違いがないことと、ファイルが置かれたサーバーに接続していることを確認してください。 3045 <ファイル名> は既に使用されているので、使用できませんでした。 3046 ほかのユーザーによってロックされているため、保存できませんでした。 3047 レコードが大きすぎます。 3048 これ以上データベースを開くことはできません。 3049 データベース <データベース名> を開くことができません。アプリケーションで認識できないデータベースであるか、またはファイルが破損しています。 3050 ファイルをロックできませんでした。 3051 ファイル <ファイル名> を開くことができませんでした。ほかのユーザーが排他的に開いているか、データを読み取る権限がありません。 3052 ファイルの共有ロック数が制限を超えています。 3053 クライアント タスクが多すぎます。 3054 メモ型、OLE オブジェクト型、またはハイパーリンク オブジェクト型のフィールドが多すぎます。 3055 ファイル名が正しくありません。 3056 このデータベースを修復できませんでした。 3057 この操作は、リンク テーブルには実行できません。 3058 インデックスまたは主キーには、Null 値を使用できません。 3059 ユーザーによって処理が中止されました。 3060 パラメータ <パラメータ名> のデータ型が正しくありません。 3061 パラメータが少なすぎます。<数> を指定してください。 3062 出力の別名 '<別名>' が重複しています。 3063 出力先 <デスティネーション名> が重複しています。 3064 アクション クエリ '<クエリ名>' を開くことができません。 3065 選択クエリを実行できません。 3066 クエリには、出力フィールドが 1 つ以上必要です。 3067 クエリの入力には、1 つ以上のテーブルまたはクエリが必要です。 3068 別名が正しくありません。 3069 アクション クエリ '<クエリ名>' をデータ ソースとして使用することはできません。 3070 <名前> を有効なフィールド名、または式として認識できません。 3071 式が正しく入力されていないか、複雑すぎるために評価できません。たとえば、数式に複雑な要素が多すぎます。変数に式の一部を割り当て、式を簡単にしてください。 3072 テーブルの入力規則や列に対する CHECK 制約を作成するときに、データ型が一致しませんでした。 3073 更新可能なクエリであることが必要です。 3074 FROM 句でテーブル名 <テーブル名> を繰り返すことはできません。 3075 クエリ式 '<式>' の <メッセージ> 3076 抽出条件式の <名前>。 3077 式の <メッセージ>。 3078 入力テーブルまたはクエリ '<クエリ名>' が見つかりませんでした。そのテーブルやクエリが存在していること、または名前が正しいことを確認してください。 3079 指定されたフィールド <フィールド名> が SQL ステートメントの FROM 句にある複数のテーブルを参照しました。 3080 結合テーブル <テーブル名> が FROM 句に指定されていません。 3081 同じ名前 (<テーブル名>) で複数のテーブルを結合することはできません。 3082 JOIN 操作 '<操作>' は結合テーブルにないフィールドを参照しています。 3083 内部レポート クエリは使用できません。 3084 アクション クエリを使用してデータを挿入することはできません。 3085 式に未定義関数 <関数名> があります。 3086 指定されたテーブルから削除できませんでした。 3087 GROUP BY 句の式が多すぎます。 3088 ORDER BY 句の式が多すぎます。 3089 DISTINCT 出力の式が多すぎます。 3090 作成されるテーブルは、複数のオートナンバー フィールドを含むことはできません。 3091 グループまたは集合のない HAVING 句 (<名前>) です。 3092 TRANSFORM ステートメントで HAVING 句は使用できません。 3093 ORDER BY 句 (<句>) が DISTINCT 句と矛盾しています。 3094 ORDER BY 句 (<句>) が GROUP BY 句と矛盾しています。 3095 式 (<式>) で集計関数を使用することはできません。 3096 WHERE 句 (<句>) で集計関数を使用することはできません。 3097 ORDER BY 句 (<句>) で集計関数を使用することはできません。 3098 GROUP BY 句 (<句>) で集計関数を使用することはできません。 3099 JOIN 操作 (<操作>) で集計関数を使用することはできません。 3100 結合キーに含まれるフィールド '<フィールド名>' は Null に設定できません。 3101 フィールド '<フィールド名>' とキーが一致しているレコードをテーブル '<テーブル名>' で探すことができません。 3102 '<クエリ参照>' から循環参照が発生しています。 3103 クエリ定義の SELECT で指定されている別名 '<別名>' が循環参照を発生させています。 3104 クロス集計クエリには、複数の固定列見出し '<値>' を指定できません。 3105 SELECT INTO ステートメント (<ステートメント>) に出力するフィールド名が見つかりません。 3106 UPDATE ステートメント (<ステートメント>) に出力するフィールド名が見つかりません。 3107 '<名前>' の挿入権限がないので、レコードを追加できません。 3108 '<名前>' の更新権限がないので、レコードを編集できません。 3109 '<名前>' の削除権限がないので、レコードを削除できません。 3110 テーブルまたはクエリ '<クエリ名>' の定義を読み取る権限がないので、定義を読み取ることができませんでした。 3111 テーブルまたはクエリ '<クエリ名>' のデザインを変更する権限がないので、作成できませんでした。 3112 '<参照名>' の読み取り権限がないので、レコードを読み取ることができません。 3113 フィールド '<フィールド名>' は更新できません。フィールドが更新可能ではありません。 3114 固有の値 (<ステートメント>) を選択した場合は、メモ型または OLE オブジェクト型のフィールドを含むことはできません。 3115 集計関数の引数 (<ステートメント>) にメモ型または OLE オブジェクト型のフィールドを指定することはできません。 3116 集計関数の抽出条件 (<条件>) にメモ型または OLE オブジェクト型のフィールドを指定することはできません。 3117 メモ型または OLE オブジェクト型のフィールド (<句>) で並べ替えを行うことはできません。 3118 メモ型または OLE オブジェクト型 (<名前>) のフィールドを結合することはできません。 3119 メモ型または OLE オブジェクト型 (<句>) のフィールドはグループ化できません。 3120 '*' (<テーブル名>) で選択したフィールドはグループ化できません。 3121 '*' で選択したフィールドはグループ化できません。 3122 集計関数の一部として指定された式 '<名前>' を含んでいないクエリを実行しようとしました。 3123 クロス集計クエリに '*' を使用することはできません。 3124 内部のレポート クエリ (<クエリ名>) から入力することはできません。 3125 '<名前>' が見つかりません。パラメータや別名が正しいこと、無効な文字や区切り記号が含まれていないこと、または名前が長すぎないことを確認してください。 3126 '<名前>' のかっこの使い方が正しくありません。 3127 INSERT INTO ステートメントに、認識できないフィールド '<フィールド名>' があります。名前が正しいことを確認して、再度実行してください。 3128 削除するレコードを含んだテーブルを指定してください。 3129 SQL ステートメントが正しくありません。'DELETE'、'INSERT'、'PROCEDURE'、'SELECT'、または 'UPDATE' を使用してください。 3130 DELETE ステートメントの構文エラーです。 3131 FROM 句の構文エラーです。 3132 GROUP BY 句の構文エラーです。 3133 HAVING 句の構文エラーです。 3134 INSERT INTO ステートメントの構文エラーです。 3135 JOIN 操作の構文エラーです。 3136 LEVEL 句が間違っている予約語や引数を含んでいるか、区切り記号が正しくありません。 3137 SQL ステートメントの最後には、セミコロン (;) が必要です。 3138 ORDER BY 句の構文エラーです。 3139 PARAMETER 句の構文エラーです。 3140 PROCEDURE 句の構文エラーです。 3141 SELECT ステートメントが間違っている予約語や引数を含んでいるか、区切り記号が正しくありません。 3142 SQL ステートメントの後に文字が見つかりました。 3143 TRANSFORM ステートメントの構文エラーです。 3144 UPDATE ステートメントの構文エラーです。 3145 WHERE 句の構文エラーです。 3146 ODBC--呼び出しが失敗しました。 3151 ODBC--'<名前>' への接続が失敗しました。 3154 ODBC--DLL '' が見つかりませんでした。 3155 ODBC--リンク テーブル '<テーブル名>' への挿入に失敗しました。 3156 ODBC--リンク テーブル '<テーブル名>' での削除に失敗しました。 3157 ODBC--リンク テーブル '<テーブル名>' での更新に失敗しました。 3158 ほかのユーザーによってロックされているので、レコードを保存できませんでした。 3159 ブックマークが正しくありません。 3160 このテーブルは開いていません。 3161 ファイルを解読できませんでした。 3162 バリアント型でない変数に Null 値を代入しようとしました。 3163 指定されたデータ量がフィールド サイズを超えています。データ量を減らし、挿入または貼り付けを行ってください。 3164 フィールドを更新できません。 3165 .INF ファイル を開くことができませんでした。 3166 指定された Xbase メモ ファイルを見つけることができません。 3167 レコードは削除されています。 3168 無効な .INF ファイルです。 3169 SQL ステートメントに無効なデータ型が使用されているので、実行できませんでした。 3170 インストール可能な ISAM ドライバが見つかりませんでした。 3171 ネットワーク パスまたはユーザー名が見つかりませんでした。 3172 PARADOX.NET を開くことができませんでした。 3173 ワークグループ情報ファイルの 'MSysAccounts' テーブルを開くことができませんでした。 3174 ワークグループ情報ファイルの 'MSysGroups' テーブルを開くことができませんでした。 3175 日付が範囲外であるか、書式が正しくありません。 3176 ファイル '<ファイル名>' を開くことができませんでした。 3177 テーブル名が正しくありません。 3179 EOF エラーです。 3180 ファイル '<ファイル名>' に書き込むことができませんでした。 3181 範囲が正しくありません。 3182 ファイル形式が正しくありません。 3183 テンポラリ ファイル用の空き容量が不足しています。 3184 リンクするテーブルが見つからないので、クエリを実行できませんでした。 3185 リモート データベース上で SELECT INTO ステートメントを使用して作成しようとしたフィールドが多すぎます。 3186 マシン '<マシン名>' のユーザー '<ユーザー名>' によってロックされているので、保存できませんでした。 3187 マシン '<マシン名>' のユーザー '<ユーザー名>' によってロックされているので、読み取れませんでした。 3188 このマシンのほかのセッションによってロックされているので、更新できませんでした。 3189 テーブル '<テーブル名>' は、マシン '<マシン名>' のユーザー '<ユーザー名>' によって排他ロックされています。 3190 定義されているフィールドが多すぎます。 3191 複数回フィールドを定義することはできません。 3192 出力テーブル '<テーブル名>' が見つかりませんでした。 3196 データベース '<データベース名>' はほかのユーザーまたはプロセスによって既に使用されています。データベースが使用可能になった時点で、再度実行してください。 3197 ほかのユーザーが同じデータに対して同時に変更を試みているので、プロセスが停止しました。 3198 アクティブなセッションが多すぎるので、セッションを開始できませんでした。 3199 参照が見つかりませんでした。 3200 リレーションシップが設定されたレコードがテーブル '<テーブル名>' にあるので、レコードの削除や変更を行うことはできません。 3201 テーブル '<テーブル名>' にリレーションシップが設定されたレコードが必要なので、レコードの追加や変更を行うことはできません。 3202 ほかのユーザーによってロックされているので、保存できませんでした。 3203 式 (<式>) にサブクエリは指定できません。 3204 データベースは既に存在しています。 3205 クロス集計する列のヘッダー (<値>) が多すぎます。 3206 同じフィールドの間でリレーションシップは作成できません。 3207 この操作は、主キーのない Paradox テーブルでは実行できません。 3208 レジストリの Xbase キーの Deleted 設定値が正しくありません。 3210 接続文字列が長すぎます。 3211 テーブル '<テーブル名>' は現在ほかのユーザーまたはプロセスで使用されているので、ロックできませんでした。 3212 テーブル '<テーブル名>' は、マシン '<マシン名>' のユーザー '<ユーザー名>' によって使用されているので、ロックできませんでした。 3213 レジストリの Xbase キーの Date 設定値が正しくありません。 3214 レジストリの Xbase キーの Mark 設定値が正しくありません。 3216 パラメータ '<名前>' にはテーブル名を指定してください。 3217 パラメータ '<名前>' にはデータベース名を指定してください。 3218 現在ロックされているので、更新できませんでした。 3219 無効な処理です。 3220 照合順序が正しくありません。 3222 クエリにはデータベースのパラメータを含めることはできません。 3223 パラメータ名 '<パラメータ名>' は正しくありません。名前が長すぎるか、無効な文字を含んでいます。 3227 レジストリの Xbase キーの Century 設定値が正しくありません。 3228 選択された CollatingSequence は OS でサポートされていません。 3230 古い Paradox のロック ファイルです。 3231 ODBC--フィールドが長すぎるので、データが切り捨てられました。 3232 ODBC--テーブルを作成できませんでした。 3234 ODBC--サーバーの応答がありません。 3235 ODBC--サーバーでサポートされていないデータ型です。 3238 ODBC--範囲外のデータです。 3239 アクティブ ユーザーが多すぎます。 3242 SELECT ステートメントの参照が正しくありません。 3243 インポートするフィールド名と一致するフィールドが追加先テーブルにありません。 3244 パスワードで保護されているワークシートはインポートできません。 3245 インポートしたテーブルの先頭行からフィールド名を解析できませんでした。 3246 この操作は、トランザクションには実行できません。 3247 ODBC--リンク テーブルの定義が変更されています。 3248 レジストリの NetworkAccess 設定値が正しくありません。 3249 レジストリの PageTimeout 設定値が正しくありません。 3250 キーを設定できませんでした。 3251 この操作は、このタイプのオブジェクトには実行できません。 3252 フォームを開くことができません。元になるクエリで、このフォームの RecordsetClone プロパティの設定または取得を行うユーザー定義関数が見つかりました。 3254 ODBC--すべてのレコードをロックできません。 3256 インデックス ファイルが見つかりません。 3257 WITH OWNERACCESS OPTION 宣言の構文エラーです。 3258 あいまいな外部結合が含まれているので、SQL ステートメントを実行できません。いずれかの結合を最初に実行するために、第一次結合を実行する分割クエリを作成し、SQL ステートメントにそのクエリを含めてください。 3259 フィールドのデータ型が正しくありません。 3260 マシン '<マシン名>' のユーザー '<ユーザー名>' によってロックされているので、更新できませんでした。 3261 テーブル '<テーブル名>' はマシン '<マシン名>' のユーザー '<ユーザー名>' によって排他的にロックされています。 3262 テーブルをロックできませんでした。 3263 データベース オブジェクトが正しくありません。 3264 フィールドが定義されていないので、テーブル定義またはインデックスを追加できません。 3265 このコレクションには項目がありません。 3266 既に Fields コレクションに属しているフィールドは追加できません。 3267 プロパティは、フィールドが Recordset オブジェクトの Fields コレクションに属していないと設定できません。 3268 オブジェクトがコレクションに属しているので、このプロパティを設定できません。 3269 既に Indexes コレクションに属しているインデックスは追加できません。 3270 プロパティが見つかりませんでした。 3271 プロパティの値が正しくありません。 3272 オブジェクトはコレクションではありません。 3273 このオブジェクトには使用できないメソッドです。 3274 外部テーブルのフォーマットが正しくありません。 3275 外部データベース ドライバ (<エラー番号>) で予期しないエラーが発生しました。 3276 データベース のオブジェクト参照が正しくありません。 3277 1 つのインデックスで使用できるフィールド数は 10 以下です。 3278 Microsoft Jet データベース エンジンが初期化されていません。 3279 Microsoft Jet データベース エンジンは既に初期化されています。 3280 インデックスとして使用されているフィールド、またはシステムに必要なフィールドは削除できません。 3281 このフィールドまたはテーブルは削除できません。カレント インデックスとして使用されているか、リレーションシップで使用されています。 3282 この操作は、データを含んでいるテーブルには実行できません。 3283 主キーは既に存在しています。 3284 インデックスは既に存在しています。 3285 インデックスの定義が正しくありません。 3286 メモ ファイルのフォーマットが、指定されている外部データベースのファイル フォーマットに対応していません。 3287 指定されたフィールドにはインデックスを作成できません。 3288 Paradox のインデックスが主インデックスではありません。 3289 CONSTRAINT 句の構文エラーです。 3290 CREATE TABLE ステートメントの構文エラーです。 3291 CREATE INDEX ステートメントの構文エラーです。 3292 フィールド定義の構文エラーです。 3293 ALTER TABLE ステートメントの構文エラーです。 3294 DROP INDEX ステートメントの構文エラーです。 3295 DROP TABLE または DROP INDEX ステートメントの構文エラーです。 3296 結合式がサポートされていません。 3297 テーブルまたはクエリをインポートできませんでした。レコードが何も見つからないか、すべてのレコードにエラーがあります。 3298 同じ名前のテーブルが複数見つかりました。'所有者.テーブル名' の形式で所有者を指定してください。 3299 ODBC の仕様適合エラー (<メッセージ>) です。アプリケーションの作成者に通知してください。 3300 リレーションシップを作成できません。 3301 この処理を実行できません。このバージョンの機能には、古いバージョンのデータベースでは使用できないものがあります。 3302 このテーブルに対する規則は現在使用されているので、変更できません。 3303 このフィールドは削除できません。1 つ以上のリレーションシップで使用されています。 3304 4 桁 (バイト) 以上、20 桁 (バイト) 未満の PID (パーソナル ID) を入力してください。 3305 パススルー クエリで使用されている接続文字列が正しくありません。 3306 メイン クエリの FROM 句の予約語 EXISTS を使用しないフィールドを複数返すサブクエリを作成しました。サブクエリの SELECT ステートメントを変更し、1 つのフィールドだけを指定してください。 3307 ユニオン クエリで選択した 2 つのテーブルまたはクエリの列数が一致しません。 3308 選択クエリの TOP 引数が正しくありません。 3309 プロパティは 2KB 以下で設定してください。 3310 このプロパティは、外部データ ソースまたは前のバージョンの Microsoft Jet データベース エンジンで作成されたデータベースではサポートされていません。 3311 指定されたプロパティは既に存在しています。 3312 システム テーブルとリンク テーブルには、入力規則と既定値を設定できません。 3313 指定された入力規則は、このフィールドには設定できません。 3314 フィールドに必要なプロパティが True に設定されているため、このフィールド '<フィールド名>' には Null 値は挿入できません。値を入力してください。 3315 フィールド '<フィールド名>' には、長さ 0 の文字列を格納できません。 3316 <テーブル レベルの入力規則のメッセージ>。 3317 '<フィールド名>' に設定されている入力規則 '<規則>' に違反する値が 1 つ以上あります。このフィールドの式で使用できる値を入力してください。 3318 削除クエリやレポートでは、TOP 句に指定された値は使用できません。 3319 ユニオン クエリの構文エラーです。 3320 テーブル レベル入力規則の <エラー>。 3321 接続文字列または IN 句にデータベースが指定されていません。 3322 クロス集計クエリに、無効な固定列見出しが 1 つ以上見つかりました。 3323 このクエリは、データ ソースとして使用することはできません。 3324 このクエリは DDL クエリなので、データ ソースとして使用することはできません。 3325 ReturnsRecords プロパティが True に設定されているパススルー クエリから、レコードが返されませんでした。 3326 このレコードセットは更新できません。 3327 フィールド '<フィールド名>' は式に基づいているので、編集できません。 3328 テーブル '<テーブル名>' は読み取り専用です。 3329 テーブル '<テーブル名>' のレコードは、ほかのユーザーによって削除されています。 3330 テーブル '<テーブル名>' のレコードは、ほかのユーザーによってロックされています。 3331 このフィールドを変更する前に、まずレコードを保存してください。 3332 外部結合の '一' 側の空白フィールドには値を入力できません。 3333 テーブル '<テーブル名>' のレコードに、'一' 側と対応するレコードがなくなります。 3334 使用できるのは、Version 1.0 形式だけです。 3337 DataCodePage オプションの設定値が正しくありません。 3340 クエリ '<クエリ名>' は破損しています。 3341 カレント フィールドは、一対多リレーションシップの '一' 側のテーブルにある結合キー '<キー名>' と一致する必要があります。 3342 サブクエリ '<サブクエリ名>' のメモ型または OLE オブジェクト型のデータが正しくありません。 3343 データベースの形式 <ファイル名> を認識できません。 3344 Microsoft Jet データベース エンジンで、入力検査の式にあるフィールド '<フィールド名>' またはテーブル '<テーブル名>' の既定値が認識されません。 3345 フィールドの参照 '<参照名>' が認識できません。または無効な参照です。 3346 クエリの値と出力するフィールドの数が一致しません。 3347 レコードを追加できません。テーブル '<テーブル名>' の主キーがレコードセットにありません。 3348 レコードを追加できません。テーブル '<テーブル名>' の結合キーがレコードセットにありません。 3349 数値フィールドがオーバーフローしました。 3350 オブジェクトが正しくありません。 3351 ORDER BY 式 (<式>) にクエリに選択されていないフィールドが含まれています。ORDER BY 式 (<式>) に含めることができるのは、最初のクエリで要求されたフィールドだけです。 3352 INSERT INTO ステートメント (<ステートメント>) に出力するフィールド名が指定されていません。 3354 このサブクエリでは 1 つのレコードしか返せません。 3355 既定値の構文エラーです。 3356 このデータベースは、マシン '<マシン名>' のユーザー '<ユーザー名>' が排他的に開いています。データベースが使用可能になった時点で、再度実行してください。 3357 このクエリは、正しく指定されたデータ定義クエリではありません。 3358 Microsoft Jet データベース エンジンのワークグループ情報ファイルを開くことができません。 3359 パススルー クエリには、1 文字以上指定してください。 3360 クエリが複雑すぎます。 3361 サブクエリでは UNION 句を使用できません。 3362 1 行の更新/削除により、1 行以上のリンク テーブルに影響がありました。固有インデックスに重複する値が含まれています。 3363 レコードを追加できません。'一' 側に対応するレコードがありません。 3364 ユニオン クエリの SELECT 句では、メモ型または OLE オブジェクト型のフィールド '<フィールド名>' を使用できません。 3365 REMOTE オブジェクトのプロパティの値が正しくありません。 3366 フィールドが定義されていないので、リレーションシップを追加できません。 3367 指定された名前と同じ名前のオブジェクトが既にコレクションにあるので、追加できません。 3368 リレーションシップは、同じデータ型で同じ数のフィールドに設定する必要があります。 3370 テーブル '<テーブル名>' のデザインは変更できません。データベースが読み取り専用になっています。 3371 テーブルまたは規則を見つけることができません。 3372 テーブル '<テーブル名>' に インデックス '<インデックス名>' が見つかりませんでした。 3373 リレーションシップを作成できません。参照先のテーブル '<テーブル名>' に主キーがありません。 3374 指定されたフィールドは、テーブル '<テーブル名>' の固有インデックスではありません。 3375 テーブル '<テーブル名>' には既に '<インデックス名>' という名前のインデックスがあります。 3376 テーブル '<テーブル名>' は存在しません。 3377 テーブル '<テーブル名>' にリレーションシップ '<リレーションシップ名>' はありません。 3378 カレント データベースには既に '<リレーションシップ名>' という名前のリレーションシップが存在します。 3379 参照整合性を設定したリレーションシップを作成できません。テーブル '<テーブル名>' にある既存のデータが、テーブル '<テーブル名>' の参照整合性に違反しています。 3380 フィールド '<フィールド名>' は、テーブル '<テーブル名>' に既に存在しています。 3381 テーブル '<テーブル名>' に '<フィールド名>' という名前のフィールドが見つかりません。 3382 フィールド '<フィールド名>' のサイズが長すぎます。 3383 フィールド '<フィールド名>' は削除できません。1 つ以上のリレーションシップで使用されています。 3384 組み込みプロパティは削除できません。 3385 ユーザー定義プロパティでは Null 値をサポートできません。 3386 このメソッドを使用するには、プロパティ '<プロパティ名>' を設定する必要があります。 3388 '<名前>' に設定されている入力規則または既定値の関数 '<関数名>' が見つかりません。 3389 クエリがサポートされていません。 3390 既に存在するアカウント名です。 3393 結合、グループ化、並べ替え、インデックスを実行できません。検索または並べ替えの対象である値が大きすぎます。 3394 プロパティを保存できません。このプロパティはスキーマ プロパティです。 3396 連鎖処理を実行できません。関連レコードがテーブル '<テーブル名>' に存在しているので、参照整合性の規則に違反することになります。 3397 連鎖処理を実行できません。テーブル '<テーブル名>' に関連レコードが存在する必要があります。 3398 連鎖処理を実行できません。実行すると、テーブル '<テーブル名>' のキーが Null 値になります。 3399 連鎖処理を実行できません。実行すると、テーブル '<テーブル名>' のキーが重複します。 3400 連鎖処理を実行できません。実行すると、テーブル '<テーブル名>' のフィールド '<フィールド名>' が 2 回更新されます。 3401 連鎖処理を実行できません。実行すると、フィールド '<フィールド名>' が Null 値になります。 3402 連鎖処理を実行できません。実行すると、フィールド '<フィールド名>' が長さ 0 の文字列になります。 3403 連鎖処理 '<入力規則テキスト>' を実行できません。 3404 連鎖処理を実行できません。入力された値は、'<名前>' に設定されている入力規則 '<規則>' で禁止されています。 3405 入力規則のエラー '<エラー テキスト>'。 3406 <エラー テキスト> のために、DefaultValue プロパティに使用している式は無効です。有効な式を使用して、このプロパティを設定してください。 3407 サーバーの MSysConf テーブルが見つかりました。ただし、正しい形式ではないので、システム管理者に確認してください。 3408 実行している高速検索のセッション数が多すぎます。 3409 インデックスまたはリレーションシップの定義で使用されているフィールド定義 '<フィールド名>' が正しくありません。 3411 無効なエントリです。フィールド '<フィールド名>' に入力された値が大きすぎ、テーブル '<テーブル名>' で連鎖処理を実行できません。 3412 このテーブルは現在ほかのユーザーによって使用されているので、連鎖更新を実行できません。 3413 テーブル '<テーブル名>' はマシン '<マシン名>' のユーザー '<ユーザー名>' によって使用されているので、連鎖更新を実行できません。 3414 テーブル '<テーブル名>' は現在使用されているので、連鎖更新を実行できません。 3415 長さ 0 の文字列を使用できるのは、テキスト型またはメモ型のフィールドだけです。 3416 <予約されているエラー警告>。 3417 アクション クエリをデータ ソースとして使用することはできません。 3418 <テーブル名> を開くことができません。ほかのユーザーが別のネットワーク コントロール ファイルまたは別のロック形式を使用してテーブルを開いています。 3419 レジストリで ParadoxNetStyle セクションが 3.x に設定されているので、Paradox 4.x または 5.x のテーブルを開くことはできません。 3420 オブジェクトが正しくないか、現在設定されていません。 3421 データ型の変換エラーが発生しました。 3422 テーブルの構造を変更できません。ほかのユーザーがテーブルを開いています。 3423 ODBC を使用して、外部 Microsoft Jet データベース エンジンのテーブルや組み込み可能な ISAM データベースのテーブルのインポート、エクスポート、またはリンクを行うことはできません。 3424 データベースを作成できません。データベースの並び順の設定が正しくありません。 3428 データベースでエラーが発生しました。データベースを修復し、最適化してください。 3429 組み込み可能な ISAM ドライバのバージョンに互換性がありません。 3430 Excel ISAM ドライバの読み込み中に、OLE を初期化できませんでした。 3431 Excel 5.0 形式のファイルではありません。 3432 Excel 5.0 形式のファイルを開くことができません。 3433 レジストリの Engines セクションの Excel キーに設定されている値が正しくありません。 3434 指定範囲を広げることはできません。 3435 ワークシートのセルを削除できません。 3436 ファイルを作成できませんでした。 3437 これ以上ワークシートに書き込むことはできません。 3438 エクスポートしているデータが SCHEMA.INI ファイルで設定されている形式と矛盾しています。 3439 Word の差し込み文書をリンクまたはインポートすることはできません。 3440 テキスト ファイルをインポートまたはリンクするには、ファイルにデータが含まれている必要があります。 3441 テキスト ファイル形式のフィールド区切り記号に、桁やテキストの区切り記号と同じ記号は使用できません。 3442 テキスト ファイルの指定 '<名前>' で、<オプション名> オプションの設定値が正しくありません。 3443 固定長の指定 '<名前>' で、列幅が指定されていません。 3444 固定長 '<名前>' の指定で、<列名> 列の列幅が指定されていません。 3445 正しくないバージョンの DLL ファイル '<ファイル名>' が見つかりました。 3446 Jet VBA ファイル (16 ビット VBAJET.DLL、32 ビット VBAJET32.DLL) が見つかりません。エラーが発生したアプリケーションを再度セットアップしてください。 3447 Jet VBA ファイル (16 ビット VBAJET.DLL、32 ビット VBAJET32.DLL) の初期化に失敗しました。エラーが発生したアプリケーションを再度セットアップしてください。 3448 OLE システム関数の呼び出しでエラーが発生しました。エラーが発生したアプリケーションを再度セットアップしてください。 3449 リンク テーブルへの接続文字列で、国番号が指定されていません。 3450 クエリの構文エラーです。クエリの句が不完全です。 3451 クエリの参照が不正です。 3452 このレプリカでは、データベースのデザインは変更できません。 3453 レプリケートされているテーブルとローカル テーブルの間にリレーションシップを設定したり、設定を変更することはできません。 3455 データベースをレプリケート可能にできません。 3456 コンテナ <コンテナ名> 内のオブジェクト <オブジェクト名> をレプリケート可能にできません。 3457 既にレプリケートされているオブジェクトの KeepLocal プロパティを設定することはできません。 3458 データベースの KeepLocal プロパティを設定することはできません。このプロパティは、データベース内のオブジェクトに対してだけ設定できます。 3459 データベースをレプリケートした後で、レプリケート不可能に設定し直すことはできません。 3460 実行を試みた操作は、レプリカ セットのメンバを含む既存の操作と矛盾します。 3461 設定または削除を試みたレプリケーション プロパティは読み取り専用であり、変更できません。 3462 DLL を読み込むことができません。 3463 DLL '<ファイル名>' が見つかりません。 3464 抽出条件でデータ型が一致しません。 3465 指定のディスク ドライブを読み取ることができません。 3468 ドロップボックス フォルダ '<フォルダ名>' へのアクセス中に、アクセスが拒否されました。 3469 ドロップボックス フォルダ '<フォルダ名>' のディスクがいっぱいです。 3470 ドロップボックス フォルダ '<フォルダ名>' へのアクセス中に、ディスク エラーが発生しました。 3471 シンクロナイザ ログ ファイルに書き込むことができません。 3472 パス '<パス名>' のディスクがいっぱいです。 3473 ログ ファイル '<ファイル名>' にアクセス中にディスク エラーが発生しました。 3474 ログ ファイル '<ファイル名>' を書き込み用に開くことができません。 3475 排他書き込みモードでログ ファイル '<ファイル名>' を開こうとしたときに、共有違反が発生しました。 3476 ドロップボックス '<ドロップボックス名>' のパスが正しくありません。 3477 ドロップボックスのアドレス '<アドレス名>' の構文が正しくありません。 3478 このレプリカは部分レプリカではありません。 3479 部分レプリカをレプリカ セットのデザイン マスターにすることはできません。 3480 部分フィルタの式に含まれるリレーションシップ '<リレーションシップ名>' が正しくありません。 3481 部分フィルタの式に含まれるテーブル名 '<テーブル名>' が正しくありません。 3482 部分レプリカのフィルタ式が正しくありません。 3483 ドロップボックス フォルダ '<フォルダ名>' のパスワードが正しくありません。 3484 シンクロナイザがドロップボックス フォルダに書き込むためのパスワードが正しくありません。 3485 データベースがレプリケートされていないので、このオブジェクトをレプリケートすることはできません。 3486 2 番目の Replication ID オートナンバー フィールドをテーブルに追加することはできません。 3487 レプリケートを試みているデータベースを変換できません。 3488 指定された値は、レプリカ セットのメンバに対する ReplicaID ではありません。 3489 必要なリソースがないため、指定したオブジェクトをレプリケートできません。 3490 コンテナ '<コンテナ名>' のオブジェクト '<オブジェクト名>' をレプリケートできないため、新しいレプリカを作成できません。 3491 データベースをレプリケートにするには、まず排他モードで開く必要があります。 3492 レプリカのデザインは変更できないので、同期できませんでした。 3493 指定されたシンクロナイザのレジストリ パラメータを設定できません。 3494 指定されたシンクロナイザのレジストリ パラメータの値を取得できません。 3495 2 つのシンクロナイザ間に同期スケジュールはありません。 3496 レプリケーション マネージャが、MSysExchangeLog テーブルで ExchangeID を見つけることができません。 3497 シンクロナイザのスケジュールを設定できません。 3499 レプリカ セットのメンバの絶対パス情報を取得できません。 3500 同じレプリカを管理するために、2 つの異なるシンクロナイザを指定することはできません。 3502 デザイン マスターまたはレプリカがシンクロナイザによって管理されていません。 3503 シンクロナイザのレジストリに必要なキー値が設定されていません。 3504 シンクロナイザ ID が、MSysTranspAddress テーブル内の既存の ID と一致しません。 3505 MSysFilters テーブルに存在しない部分フィルタに関する情報を削除または取得しようとしました。 3506 シンクロナイザがシンクロナイザ ログを開くことができません。 3507 シンクロナイザ ログに書き込むことができません。 3508 シンクロナイザに対するアクティブなトランスポートがありません。 3509 このシンクロナイザに対する有効なトランスポートが見つかりませんでした。 3510 同期を試みたレプリカ セットのメンバは、現在ほかの同期で使用されています。 3512 ドロップボックス フォルダを読み取ることができませんでした。 3513 ドロップボックス フォルダに書き込むことができませんでした。 3514 シンクロナイザは、スケジュールされた同期またはオンデマンドの同期を見つけることができませんでした。 3515 Microsoft Jet データベース エンジンはコンピュータのシステム クロックを見つけることができませんでした。 3516 デスティネーション シンクロナイザは間接同期をサポートするように設定されていません。また、デスティネーション レプリカは直接同期に使用できません。 3517 シンクロナイザは処理対象のメッセージを見つけることができませんでした。 3518 MSysTranspAddress テーブルでシンクロナイザを見つけることができませんでした。 3519 メッセージを送信できませんでした。 3520 レプリカの名前または ID が、現在管理されているレプリカ セットのメンバと一致しません。 3521 同期を開始する共通点がないため、この 2 つのレプリカを同期できません。 3522 シンクロナイザは、MSysExchangeLog テーブル内に特定の同期のレコードを見つけることができません。 3523 シンクロナイザは、MSysSchChange テーブル内に特定のバージョン番号を見つけることができません。 3524 レプリカのデザイン変更の履歴が、デザイン マスターの履歴と一致しません。 3525 シンクロナイザはメッセージ データベースにアクセスできませんでした。 3526 システム オブジェクト用に指定した名前は既に使用されています。 3527 シンクロナイザまたはレプリケーション マネージャはシステム オブジェクトを見つけることができませんでした。 3528 シンクロナイザまたはレプリケーション マネージャ用の共有メモリには、新しいデータはありません。 3529 シンクロナイザまたはレプリケーション マネージャは、共有メモリ上に未読のデータを見つけました。既存のデータは上書きされます。 3530 シンクロナイザは既にクライアントを起動しています。 3531 イベントの待ち時間は終了しました。 3532 シンクロナイザを初期化できませんでした。 3533 プロセスが終了した後も、このプロセスが使用したシステム オブジェクトが存在します。 3534 シンクロナイザはシステム イベントを検索しましたが、クライアントに報告するようなシステム イベントを見つけることができませんでした。 3535 クライアントはシンクロナイザに処理を終了するよう要求しました。 3536 シンクロナイザは、管理するレプリカ セットのメンバに対する無効なメッセージを受信しました。 3537 シンクロナイザのクライアントは現在存在していないので、認識されません。 3538 多くのアプリケーションが実行されているので、シンクロナイザを初期化できません。 3539 システム エラーが発生したか、スワップ ファイルの上限に達しました。 3540 スワップ ファイルの上限に達したか、ファイルが壊れています。 3541 シンクロナイザを正しくシャット ダウンできなかったので、アクティブのままです。 3542 シンクロナイザ クライアントを終了しようとしたときに処理が中断しました。 3543 シンクロナイザがセットアップされていません。 3544 シンクロナイザは既に実行されています。 3545 同期を試みた 2 つのレプリカは、異なるレプリカ セットのものです。 3546 実行しようとした同期の種類が正しくありません。 3547 同期を完了するために、シンクロナイザは正しいセットでレプリカを見つけることができませんでした。 3548 GUID が一致しないか、指定した GUID が見つかりません。 3549 指定したファイル名が長すぎます。 3550 GUID 列にはインデックスがありません。 3551 指定したシンクロナイザのレジストリ パラメータを削除できません。 3552 レジストリ パラメータのサイズが、上限値を超えています。 3553 GUID を作成できませんでした。 3555 レプリカ用の有効な名前はすべて使用されています。 3556 デスティネーション ドロップボックス フォルダのパスが正しくありません。 3557 デスティネーション ドロップボックス フォルダのアドレスが正しくありません。 3558 デスティネーション ドロップボックス フォルダでディスク I/O エラーが発生しました。 3559 出力するディスクがいっぱいなので、書き込むことができません。 3560 同期を試みたレプリカ セットの 2 つのメンバの ReplicaID が同じです。 3561 同期を試みた 2 つのレプリカ セットのメンバは両方ともデザイン マスターです。 3562 デスティネーション ドロップボックス フォルダでアクセスが拒否されました。 3563 ローカル ドロップボックス フォルダへのアクセス中に致命的エラーが発生しました。 3564 シンクロナイザはメッセージのソース ファイルを見つけることができません。 3565 ほかのアプリケーションがメッセージ データベースを開いているため、ソース ドロップボックス フォルダで共有違反が発生しました。 3566 ネットワーク I/O エラー。 3567 ドロップボックス フォルダ内のメッセージは不正なシンクロナイザのものです。 3568 シンクロナイザはファイルを削除できませんでした。 3569 このレプリカはレプリカ セットから論理的に削除されているため、使用できません。 3570 部分レプリカを定義するフィルタが変更されています。部分レプリカを再設定する必要があります。 3571 部分レプリカに適用される規則に違反するため、部分レプリカでは列を設定できません。 3572 環境変数 TEMP で指定されているフォルダの読み込みまたは書き込み中に、ディスク I/O エラーが発生しました。 3573 レプリカの一覧用のフォルダは管理されていません。 3574 このレプリカの ReplicaID は、移動またはコピーの処理中に再度割り当てられました。 3575 書き込みを試みたディスク ドライブはいっぱいです。 3576 開こうとしたデータベースは、既にほかのアプリケーションが使用しています。 3577 レプリケーションのシステム列を更新できません。 3578 データベースが排他モードで開いていることを確認できないため、データベースをレプリケートできません。 3579 データベースをレプリケート可能にするために必要なレプリケーション システム テーブルを作成できませんでした。 3580 データベースをレプリケート可能にするために必要な列を追加できませんでした。 3581 レプリケーション システム テーブル '<テーブル名>' は既に使用されているため、開くことができません。 3582 コンテナ <コンテナ名> 内のオブジェクト <オブジェクト名> をレプリケート可能にできないため、新しいレプリカを作成できません。 3583 コンテナ <コンテナ名> 内のオブジェクト <オブジェクト名> をレプリケート可能にできません。 3584 メモリ不足のため、操作を完了できません。 3585 列数が上限値を超えているため、テーブルをレプリケートできません。 3586 テーブル <テーブル名> の部分フィルタ式の構文エラーです。 3587 ReplicaFilter プロパティの式が正しくありません。 3588 部分フィルタの式を評価するときにエラーが発生しました。 3589 部分フィルタの式に未定義の関数が含まれています。 3590 部分レプリカに適用される規則に違反します。 3591 ログ ファイルのパス '<パス名>' が正しくありません。 3592 パスワードで保護されているデータベースをレプリケートすることはできません。また、レプリケートされたデータベースにパスワードを設定することはできません。 3593 レプリカ セットのデータのマスター属性を変更することはできません。 3594 レプリカ セットのデータのマスター属性を変更することはできません。データはデザイン マスターだけで変更できます。 3595 レプリカのシステム テーブルの信頼性がありません。このため、このレプリカを使用することはできません。 3600 集計関数の式では GUID を使用することはできません。 3605 レプリケートされていないデータベースと同期することはできません。データベース '<データベース名>' はデザイン マスターまたはレプリカではありません。 3607 削除を試みたレプリケーション プロパティは読み取り専用のため、削除できません。 3608 インデックス化された Paradox テーブルのレコードが長すぎます。 3609 主テーブルで参照されているフィールド用の固有インデックスが見つかりません。 3610 テーブル作成クエリで同じテーブル ('<テーブル名>') が、作成元になるテーブルおよび作成されるテーブルの両方として指定されています。 3611 リンクされているデータ ソースに対してデータ定義ステートメントを実行することはできません。 3612 サブクエリでは、マルチレベル GROUP BY 句は使用できません。 3613 リンク ODBC テーブル間にリレーションシップを設定することはできません。 3614 Find 系メソッドの抽出条件では、GUID は使用できません。 3615 式で型が一致しません。 3616 この ISAM では、リンク テーブル内のデータを更新することはできません。 3617 この ISAM では、リンク テーブル内のデータを削除することはできません。 3618 インポート/エクスポートで、例外テーブルを作成できませんでした。 3619 例外テーブルにレコードを追加できませんでした。 3620 リンクされている Excel のワークシートを表示するための接続が切断されました。 3621 共有モードで開いているテーブルのパスワードを変更することはできません。 3622 IDENTITY 列を持つ SQLServer テーブルにアクセスする場合は、OpenDatabase メソッドで dbSeeChanges オプションを使用する必要があります。 3623 DBF ファイル <ファイル名> に結合されている FoxPro 3.0 にアクセスできません。 3624 このレコードは現在ほかのユーザーによってロックされているので、読み取ることができませんでした。 3625 テキスト ファイルの指定 <名前> が存在しません。この指定を使用してインポート、エクスポート、またはリンクすることはできません。 3626 テーブル <テーブル名> にインデックスが多すぎるため、この操作を実行できませんでした。インデックスをいくつか削除して、再度実行してください。この操作を実行できませんでした。 3627 シンクロナイザの実行可能ファイル (MSTRAN40.EXE) が見つかりません。 3628 パートナー レプリカはシンクロナイザによって管理されていません。 3629 シンクロナイザ '<シンクロナイザ名>' も同じ File System ドロップボックス '<ドロップボックス名>' を使用しています。 3630 シンクロナイザ '<シンクロナイザ名>' も同じ File System ドロップボックス '<ドロップボックス名>' を使用しています。 3631 フィルタのテーブル名が正しくありません。 3632 インターネット トランスポートはリモート シンクロナイザ上では効果的ではありません。 3633 DLL '' を読み込むことができません。 3634 部分レプリカを使用してレプリカを作成することはできません。 3635 システム データベースの部分レプリカを作成することはできません。 3636 レプリカに競合またはデータ エラーがあるため、レプリカにレコードを読み込んだりレプリカのフィルタを変更することはできません。 3637 サブクエリに非固定列のクロス集計を使用することはできません。 3638 ソース コントロール データベースはレプリケート可能にすることはできません。 3639 システム データベースのレプリカを作成することはできません。 3640 要求したデータの量に対してフェッチ バッファが小さすぎます。 3641 レコードセットには、要求されたレコードより少ないレコードしかありません。 3642 この操作はキャンセルされました。 3643 レコードセットのレコードの 1 つがほかのプロセスによって削除されました。 3645 バインド パラメータの 1 つが正しくありません。 3646 列の長さの合計より短い長さが指定されました。 3647 要求された列はレコード セットに返されていません。 3648 部分レプリカとほかの部分レプリカを同期することはできません。 3649 言語固有のコード ページが指定されていないか、見つかりません。 3650 インターネットが遅すぎるか、インターネット サーバーのレプリケーション マネージャの設定に問題があります。 3651 インターネットのアドレスが正しくありません。 3652 インターネットのログインに失敗しました。 3653 インターネットがセットアップされていません。 3656 部分式の評価でエラーが発生しました。 3657 テーブル '<テーブル名>' のブール型フィルタの式の評価でエラーが発生しました。 3658 バイナリ列? '<列名>' はブール型フィルタでは使用できません。 3659 リレーションシップ '<リレーションシップ名>' は実行できません。部分フィルタ式のリレーションシップは実行する必要があります。 3660 のために要求された交換は失敗しました。 3661 <説明> のために要求された交換は失敗しました。 3663 この操作には別のカーソル ライブラリが必要です。 3664 非同期の OpenConnection 呼び出しはまだ完了していません。呼び出しが完了するまで返された Connection オブジェクトを参照することはできません。 3665 レプリケーション システム オブジェクト '<オブジェクト名>' を変更することはできません。 3666 レプリケーション システム オブジェクト '<オブジェクト名>' を変更することはできません。 3667 ほかの操作により、この操作は実行できなくなっています。 3668 アクティブな接続が存在しないので、この操作を実行することはできません。 3672 RDOCURS.DLL の読み込みに失敗しました。 3673 このテーブルには、このスプレッドシートで定義されている範囲外のセルが含まれています。 3674 インターネット DLL (WININET.DLL) が見つからないか、ロードできませんでした。 3675 インターネット ハンドルからの読み込みに失敗しました。再度実行してください。 3676 インターネット ハンドルへの書き込みに失敗しました。再度実行してください。 3677 HTTP 要求の実行に失敗し、インターネット サーバー上にあるインターネット シンクロナイザを起動できませんでした。Replication Manager を使用して、インターネット サーバー上のインターネット シンクロナイザを設定してください。 3678 インターネット サーバー上の FTP サービスへの接続に失敗しました。FTP サービスがサーバー上で正しく実行され、匿名での接続をサポートしていることを確認してください。 3679 FTP サービスを使用してファイルを開くことができませんでした。FTP ドロップボックスに読み取り権限があることを確認してください。 3680 FTP を使用してサーバーからファイルを取得できませんでした。FTP ドロップボックスに読み取り権限があることを確認してください。 3681 FTP を使用してサーバーにファイルを置くことができませんでした。FTP ドロップボックスに書き込み権限があることを確認してください。 3682 FTP を使用してサーバーのファイルを削除できませんでした。FTP ドロップボックスに読み取り/書き込み権限があることを確認してください。 3683 インターネット シンクロナイザがサーバー上で異常終了しました。インターネット サーバーにあるパートナー レプリカのデータ交換履歴を確認して、問題の原因を特定してください。 3684 データを交換する適切なレプリカがありません。 3685 HTTP アドレスが正しくありません。 3686 レプリカのパス、または名前が正しくありません。 3689 SQL 構文が正しくありません。正しいトークンは Privileges です。 3700 この精度は、decimal データ型には適用できません。 3701 この桁数は、decimal データ型には適用できません。 3702 UNICODE テキスト列の幅は、偶数バイト数であることが必要です。 3703 この操作は、現バージョンに変換されていないレプリケート可能なデータベースには実行できません。 3704 このデータベースは、マシン '<マシン名>' のユーザー '<ユーザー名>' が開いています。データベースが使用可能になった時点で、再度実行してください。 3705 列の数が多いので、<テーブル名> テーブルをレプリケートできません。 3706 インデックスの数が多いので、<テーブル名> テーブルをレプリケートできません。 3707 新しい参照に対する連鎖オプションが既存の参照 '<参照名>' と矛盾しています。 3708 Transaction ステートメントの構文エラーです。TRANSACTION または WORK を使用するか、何も入力しないでください。 3709 レコードに検索キーが見つかりませんでした。 3710 MAPI フォルダまたはアドレス帳が見つかりません。 3711 復旧されたレプリケート可能なデータです。この行は、破損したレプリケート可能なデータベースから復旧しました。レコードの内容が正しいことを確認し、レコードを再度挿入するか、この競合するレコードを削除してください。 3713 更新/更新の競合。ほかのレプリカもこのレコードを更新しました。このレコードには、競合がなくなりました。更新データを再発行するか、この競合データを削除してください。 3714 ロックされたテーブル。テーブルがほかのユーザーにロックされていたので、 このレコードは同期中には適用されませんでした。この競合レコードを再発行してください。 3715 一意なキーの規則に違反しています。 3716 TLV 違反です。 3717 削除/RI 競合です。 3718 更新/RI 競合です。 3719 外部キー違反です。 3720 フィールド '<フィールド名>' を変更できません。このフィールドは、1 つ以上のリレーションシップの一部です。 3721 SQL 構文が正しくありません。制約名が必要です。 3722 SQL 構文が正しくありません。正しいトークンは DEFAULT です。 3723 SQL 構文が正しくありません。WITH とその後に COMPRESSION が必要です。 3724 SQL 構文が正しくありません。正しいトークンは UPDATE または DELETE です。 3725 SQL 構文が正しくありません。正しいトークンは 'CASCADE'、'SET NULL'、または 'NO ACTION' です。 3726 SQL 構文が正しくありません。正しいトークンは NULL です。 3727 SQL 構文が正しくありません。使用できるのは、1 つの更新規則または 1 つの削除規則です。 3728 SQL 構文が正しくありません。正しいトークンは AS です。 3729 SQL 構文が正しくありません。正しいトークンは SELECT です。 3730 VIEW にはパラメータを使用できません。 3731 指定する別名の数は、出力列の数と同じにします。 3732 'EXECUTE' の後にクエリ名が必要です。 3733 認識できないユーザーがデータベースを開けない状態、またはロックできない状態にしています。 3734 マシン '<マシン名>' のユーザー '<ユーザー名>' がデータベースを開けない状態、またはロックできない状態にしています。 3736 更新/削除の競合。この更新されたレコードは、ほかのレプリカによって削除されました。この競合レコードを再度挿入するか、削除してください。 3737 指定されたソース レプリカからこのタイプのレプリカは作成できません。 3738 ローカルまたは匿名のレプリカは、レプリケーション元だけと同期する必要があります。 3740 競合テーブル '<テーブル名>' に新しい列を追加できません。古い列を削除して、データベースを最適化してください。 3741 無効なパートナー シンクロナイザです。ローカルまたは匿名のレプリカは、レプリケーション元だけと同期する必要があります。 3742 インターネット機能がタイムアウトしました。 3743 レプリカ セットの保有期間内に、レプリカが同期しませんでした。 3745 インターネット サーバー名、HTTP 共有名、および FTP 別名を合わせた文字数は、252 文字以下にします。 3746 パラメータ句の構文エラーです。パラメータが存在し、入力した値が正しいことを確認してください。 3747 パラメータにはデフォルト値はありません。 3748 パラメータ <パラメータ名> にはデフォルト値はありません。 3749 オブジェクトはストアド プロシージャではありません。 3750 オブジェクト <オブジェクト名> はストアド プロシージャではありません。 3751 データベースがページ ロック モードにあり、要求された行がロックされています。 3752 データベースが行ロック モードにあり、要求されたページがロックされています。 3753 Jet SQL レプリカのレプリカは作成できません。 3754 Prevent Deletes Replica からは削除できません。 3755 チェック制約 '<制約名>' は存在しません。 3756 チェック制約 '<制約名>' は既に存在します。 3757 Jet ソート DLL を正しくロードできませんでした。 3758 小数を丸めたために、データが切り捨てられました。 3759 小数を丸めたために、データが切り捨てられました。 3760 小数を丸めたために、データがオーバーフローしました。 3761 指定された数値は、小数フィールドの精度と合致しません。 3762 SQL 構文が正しくありません。正しいトークンは ACTION です。 3763 同時スキーマを変更したので、レプリカの作成に失敗しました。再度実行してください。 3765 チェック制約句の構文エラーです。 3766 VIEWS には、単純な SELECT クエリしか使用できません。 3767 テーブル '<テーブル名>' を排他的に開くことができなかったので、レプリケート可能にできませんでした。 3768 FastFind では、列ではない参照は検索できません。 3769 競合テーブルは、名前を変更できません。 3770 カウンタの定義が有効な範囲ではありません。 3771 ローカルまたは匿名のレプリカは、デザイン マスターにはできません。 3772 管理者の許可を得ていない場合は、レプリカの優先度は 0 - 1 の範囲にします。 3773 1 つ以上のオブジェクト <オブジェクト名> を削除できません。 3775 Jet SQL Server Reconciler (MSRPJT40.DLL) をロードできません。 3777 Jet SQL Server レプリカで不正な操作を行いました。 3778 Jet データベースがこの SQL/Jet レプリカ セットに対して正しくないか、見つかりません。 3779 既にレプリケート可能になっているオブジェクトでは、Column Level Tracking プロパティを変更できません。 3780 SQL 構文が正しくありません。ビュー名が必要です。 3781 SQL 構文が正しくありません。プロシージャ名が必要です。 3784 データベースは既にレプリケート可能になっています。 3785 SQL 構文が正しくありません。正しいトークンは Database です。 3786 SQL 構文が正しくありません。CREATEDB または CONNECT などのデータベース権限が必要です。 3787 この操作は、サブクエリでは実行できません。 3788 この MAPI フォルダ/アドレス帳には、インデックスを作成できません。 3789 列レベルの制約が正しくありません。 3798 チェック制約は、レプリケート可能なデータベースには使用できません。 3799 フィールド '<フィールド名>' が見つかりませんでした。 3800 '<インデックス名>' は、このテーブルのインデックスではありません。 3801 オブジェクト (<オブジェクト名>) は、CHECK CONSTRAINT 句には使用できません。 3802 <制約名> CHECK 制約の評価でエラーが発生しました。<付加情報> 3803 このテーブルで DDL を完了できません。この DDL は、テーブル? <テーブル名> の制約 <制約名> で参照されています。 3804 このマシンには MAPI クライアントがインストールされていません。Outlook などの MAPI クライアントをインストールしてください。 3805 テーブル? <テーブル名> のチェック制約はこのテーブルに転送されません。チェック制約を作成する場合は、SQL DDL ステートメントを使用する必要があります。 3806 NULL 属性および NOT NULL 属性は複数作成することはできません。 3807 クエリ <クエリ名> にあいまいな列名があり、関連名 (別名) と重複しています。 3808 この操作を実行するには、システム データベースの Version 4.x 以上が必要です。
これもマイクロソフトアクセス(Access)の話なのですが、テーブルを作成する時にPRIMARY KEYの設定も行うと思います。
競馬のデータベースへのセットアップ(Setup)時には、インデックスが作成してあったら削除してから行うのが基本のようです。
そうしないと、インデックスが作成してあるとインデックス処理も同時に行われるために、処理が遅くなると言われているからです。
プライマリィキーも指定しない方が処理が早いのではないかと試してみました。
データ数が少ない時は、どっちがどうだとの判断するほどの差は無いので無理なのですが、数万件を超えたあたりからプライマリィキーが設定していないととろくなるようなのです。
色々な要素も絡みあっているので、断定が出来ないのですがデータベースのテーブルの作成時には、インデックスは削除してから登録しますが、プライマリィキーの設定は必ず行うようにしています。
テーブルの作成時に関しての注意点は、文字型の指定です。
アクセス(Access)の場合は、CHAR型とTEXT型が使えるのですが、この違いと動作の関係がはっきりと判りません。
サイトの解説では、以下のようになっています。
char データ型とは、Access プロジェクトで、最大 8,000 字の ANSI 文字を格納する固定長のデータ型です。
TEXT型は、末尾のスペースがカットされるvharchar型です。
Jet 4.0においては、CHARは Unicodeの固定長文字列型、TEXTはUnicodeの自由長文字列型として扱われます。
使い方によっては、エラーも発生するようで、どっちをどう使うのが良いのだろうかと悩んでしまいます。
お手本にしている「馬吉」では、CHAR型を使っておりますが、オッズにはTEXT型のサイズ無指定(メモ型)を使用しています。
オッズの長さは一定だからと、CHAR型でサイズを指定してみた事があったのですが、エラーになったと記憶しております。
「馬吉」の場合はテーブルの作成時に、WITH COMPRESSION のオプションコードを全てのテーブルの作成時につけており、これがどのように作用しているのかもさっぱり判りません。
私自身は、このオプションコードは紛らわしいので付加しておりませんが、それで問題を感じた事はありません。
少なくともデータベースの作成時間やデータベースのサイズには関係ないようです。
検索時やインデックス作成時に有利なのかは同じ条件で比較してみないと判りませんので、手間が掛かります。
「馬吉」の場合は3連単のオッズはデータベースには登録せずに、別ファイルで保存しています。
データベースの容量を圧迫するからだと思っていたのですが、ひょっとしたらサイズの問題かも知れません。
3連単のオッズのサイズは、83232バイトもあるのですが、アクセスのTEXT型では65535バイトが最大なのではないかとも思っています。
この辺は勉強不足で良く判りませんが、アクセスでデータベースを作る際には「馬吉」を見習っておいた方が無難だろうとは思っております。
文字列を短くしてデータベースに記載するために、組み合わせ部分(6バイト×組み合わせ数)を削除してデータベースに登録しようと試した事があります。
つまり、MID$関数で抜き出す方法で、3連単の組み合わせ部分は順番になっていますからデータベースに記載しなくても大丈夫なので、我ながら良い考えだと思ったのですがデータの登録時に時間が掛かって使い物になりませんでした。
アイディアは良かったのですが、私のおんぼろパソコンではセットアップ時間は忍耐の限度を越える時間になってしまいましたから、これを公開すればクレームの嵐となるでしょう。
SQLite では、文字列型を TEXT にしてサイズを記入しなければ、3連単のオッズデータもすんなり入りました。
動作上も問題無い事が確認されています。
MySQL の場合は、以前のバージョンでは TEXT は 65535 バイトが最大でした。(今は変わっていると思いますが。)
Firebird も 65535 バイトが最大だったと認識しております。
データベースも常時バージョンアップをしておりますので、私の書いた内容を鵜呑みにせずに、使用する場合は御確認ください。
「馬吉」には理解不能なコードの記載が所々にあります。
最初に見た時は、これは記載ミスではないかと思っておりました。
例えば、ユーザーコントロールの ctlVRA に書いてある一例です。
' 最初に表示するタブを設定する If mViewerState.IsNoTouch Then mstTab.Tab = 2 mstTab.Tab = mData.FirstTabNumber Else LastTabNumber = mViewerState.LastTabNumber mstTab.Tab = (mViewerState.LastTabNumber + 1) Mod mstTab.Tabs mstTab.Tab = LastTabNumber End If
mstTab.Tab = 2
mstTab.Tab = mData.FirstTabNumber
の部分です。
こんなコードを書き馴れている方なら自然なプログラムなのでしょうが、私はこんな書き方をする事はありませんでしたので違和感を覚えました。
「馬吉」では文字コードの代入プロパティとかを数多く使用しております。
例えば以下のような書き方です。
' ' 機能: Year 代入プロパティ ' ' 備考: なし ' Public Property Let Year(RHS As String) Mid$(mstrKey, 1, 4) = RHS End Property 'Year ' ' 機能: Year 取得プロパティ ' ' 備考: なし ' Public Property Get Year() As String Year = Mid$(mstrKey, 1, 4) End Property 'Year
Let で数値を代入してから、Get で読みだすと言う方法ならば、書き方は理に適っております。
但し、一般的には、このような書き方でプログラムを作成する人は居ないと思います。
これでは、プログラムの見通しが悪くなるのと、場合によってはミスと思って削除してしまう場合もあるでしょう。
私は、プログラム作成ツールでも使用しているのではないかと感じる点の根拠がここにあります。
事実、上記の例ではプログラムを見渡して見ましたが、今もって意味が判りません。
恐らく、タブ切り替えのコマンドを発生させるための操作だとは思うのですが。
「馬吉」にはクールバー(cbrTop)があって、その中にctlTitleBandがあって、ラベル1(lblWrapped)にタイトルを表示するようになっています。
タイトルとは、出馬表を表示している場合は、出馬表などと表示されます。
このタイトルバーは、フォーム(frmBrowser)に属しているので、このタイトルバーにタイトルを記入する場合には、イベントで表示させるようになって
います。
イベントとは、"WindowTitle" イベントを発生するのですが、タイトルは最初の1回は問題なく記入されるのですが、2回目以降には正常にに記入されません。
記入されないと言うより、表示すると空白になるのです。
これには嵌りました。
タイトルの表示方法も少し変わっていて、Property Let Title(strTitle As String) で行っていますので、原因が判明するまでに時間が掛かりました。
結果的には、ユーザーコントロール(lblWrapped)の Property Let Caption で lblWrapped.Visible = False にしていたためでした。
従って、タイトルを記入しただけでは変更は表示されません。
なぜ、このようになっているのかと考えましたが、恐らくは表示に時間差を生じるのは不自然だと考えたのでしょう。
全ての内容が表示されてから、lblWrapped.Visible = True にしておりました。
確かに、「馬吉」では表示に時間の掛かる処理が多いですが、今回の場合は時間差を感じる程の差はありませんので、常時 lblWrapped.Visible = True にしております。
変更によって、タイトルが最初に表示される事は実感できますが、これが不自然と感じる程ではありません。
「馬吉」の使い勝手を向上させるために、改造を進めるていると「馬吉」落ちる事が多くなりました。
単なる移植では、全くと言って良い程落ちる事はなかったのですが、開催選択画面とレース内容の表示を同じタブストリップで行うようになってから多くなりました。
恐らくは、今までは1回だけ表示するとお終いでメニューに戻っていましたが、同じタブストリップだと連続してアクセスしますので単純な処理では収まらないからだと思っています。
固まってしまうのではなくて、画面が乱れてフレックスタブが2重、3重に現れるような現象が発生します。
最初はメモリー関係だろうと思って、プログラムの不要な部分を削除したりしてみたのですが、決定打にはなりませんでした。
なぜかユーザーコントロールのリサイズを頻繁に行っているようですので、その影響ではないかと思っているのですが、現在は原因が判明しておりません。
私のパソコンはメモリー関係は特に問題があるようで、OSのインストール時にも画面がブルースクリーンになったりして、メモリーボードの差すコネクターを変えてみたり、メモリーのメーカーを変えてみたりした経過がありますので、使用環境が良くないのは確かです。
このプログラムに限らず、動作中にメモリー関係のエラーが出る事はあります。
しかし、発生する頻度が全く違いますので、メモリーの解放を忘れているとか何らかの問題はありそうです。
発生する状況が一定ではありませんので、厄介な事です。
どうしても解消できなければ、開催選択は切り離して動作させる必要がありそうです。
ひょっとしたら、「馬吉」の開催選択も最初はレースデータと一緒だったのではないでしょうか。
そうでなければ、わざわざタブストリップに開催選択を入れる必要はなかった筈です。
うまくいかないと、あらぬ事を考えてしまいます。
【後記】
動作中に画面が乱れてしまうのは、やはりOSのメモリーが不足するのが関係しているようです。
データベースの SQLite が大量のメモリーを使用するのと、「馬吉」が動作中に使用するメモリーが蓄積されて、限界を超えた時に画面が乱れるのではないかと考えております。
SQLite が使用するメモリーの管理は、現バージョンでは出来ないようですから、「馬吉」の方で対策を考える事にしました。
「馬吉」のどの動作でメモリーの使用量が多いのかですが、画面が乱れるのは出馬表のレース選択を繰り返している場合に発生する事が多い事から、画面の制御関係で大量のメモリーを消費しており、そのメモリーが適切に解放されていないのではないかと考えました。
以前から気になっていたのは、「馬吉」では画面のリサイズを頻繁に行っております。
本来ならば画面の構成は、イニシャル時に1回行えば済むものですが、「馬吉」の場合はコントロールの配置を動的に行っているためにリサイズが必要となるのです。
私が気になっているのは、動的に変化させた場合に変化させたコントロールだけの再配置だけでなく全コントロールを再配置している点です。
これだけなら、単に無駄な時間を消費しているだけで済むのですが、再配置の時に多くのメモリーを新たに確保してそれが蓄積されているのではないでしょうか。
そうだとすれば、動作中に突然メモリー不足になって画面が乱れる事の説明がつきます。
「馬吉」で画面のリサイズを行っているのは、基本画面でタブを切り替えた時と成績画面を表示する時です。
そこで、まずこの部分を共通のリサイズ画面を呼び出すのではなく必要な部分だけを再配置するようにへんこうしました。
これで動作速度の向上も図れますので、一石二鳥です。
これでどうなるのか、しばらく様子を見る事にしました。
【結論】
プログラムの変更をする等して色々試行錯誤してみましたが、根本的には解決しませんでした。
やはり大量のメモリーを使用する事が原因と考えられ、順調に動作しているようでも時折落ちてしまいます。
やはり開催選択をレース表示のタブストリップの中に組み込むのは無理と結論致しました。
「馬吉」がそのようにしているのも、そのような理由も含まれているのでしょう。
開催選択を切り離す事で動作の安定度は格段に向上します。
移植した「馬吉」も快調に動くようになってきました。ある不満点を除けばですが。
それは、オッズデータを表示すると別ウィンドウで開くのですが、その新しく開いたウィンドウを閉じると「馬吉」も終了してしまうのです。
最初の頃はつまらないバグ残っているのだろうぐらいに考えておりましたが、そうではなさそうです。
新しいウィンドウを閉じると本体が終了してしまうのは、開いているウィンドウの数を数えられないためであるのは判っておりましたが、なぜ同じプログラムにしているのに数えられないかです。
調べてみると心当たりがありました。
「馬吉」のオリジナルでは、標準モジュールのメイン(Main)から、クラスモジュール(clsApp)のStartを呼び出してプログラムを組んでおりましたが、Startのプログラムはたかだか数行のプログラムなので、全てMain に移して起動させておりました。
これで何の問題もなく動くのですが、1点だけ問題点があったのです。
同じクラスにブラウザマネージャー(clsBrowserMgr)があるのですが、clsApp からこのクラスを呼び出すのとMain からこのクラスを呼び出すのでは大きな差があるのです。
実は、ブラウザマネージャーはコレクション(Collection)を使って開いている新しいウィンドウの数を数えていて、標準モジュールから呼び出したのではコレクションが正しく動作しないようなのです。
私は、コレクションなど使う事はありませんので、正確な事は判りませんが「馬吉」のオリジナルのスタート方法に戻したら期待通りの動作をしましたので間違いないと思います。
尚、「馬吉」ではメニューパレットが開いていると「馬吉」が終了できないプログラムの書き方になっているようですが、私はメニューパレットが開いている場合は、メニューパレットを閉じて終了するように変更しました。
この方が自然だろうと私は思っているのですが。
「馬吉」の改造を行っていると、ツールバーに新しいアイコンを追加して表示させたりする事になります。
「馬吉」ではツールバーの表示領域を2ブロックに分けて1ブロック目は常時表示させ、2ブロック目は表示をオン・オフしています。
2ブロックだけで表示させている場合は、このままでも良いのですが、これを3ブロック化するにはどうしたら良いのだろうかといじったりしているとツールバーの画像が表示されなくなる事があります。
一旦表示されなくなると元に戻しても回復しません。
この回復方法は実は判りません。
どこかのファイルが書き換わっているのか、元の状態に戻してコンパイルすると大丈夫なのかも調べておりません。
私の対処方法は以前に正常に動いていた時のバックアップしておいた全ファイルをに戻しています。
「馬吉」ではツールバーも独自のコントロールを作成して変わった使い方をしていますので、深く原因を追求しようとは思いません。
改造を行っていれば、必ずこの現象に1度や2度は遭遇する事でしょう。
【追記】
色々と試行錯誤しましたが、結局は以下のような方法でツールバーのアイコンをセットするのが確実でした。
これは、ユーザーコントロール(ctlVRA)のツールバーのアイコンのセット方法をコピーしたものです。
' ' 機能: ツールバーを設定する ' ' 備考: ブラウザからツールバーを受け取り、ツールバーをセットアップする ' RA, OD のみ、必須プロパティ ' Public Property Set ToolBar(RHS As ctlToolBars) Dim rc As New clsRCSearch Dim rcG1 As New clsRCSearch Dim p As Long Set mToolBar = RHS rc.CurrentRecordKeyStr = mData.RCKey rcG1.CurrentRecordKeyStr = mData.RCG1Key With ilsTbrSmall .ListImages.Clear .ImageHeight = 16 .ImageWidth = 16 .ListImages.Add 1, , LoadResPicture(201, vbResIcon) .ListImages.Add 2, , LoadResPicture(413, vbResIcon) .ListImages.Add 3, , LoadResPicture(411, vbResIcon) End With With mToolBar.ToolBar(1) .Buttons.Clear .ImageList = ilsTbrSmall p = 1 .Buttons.Add p, "ODDS", "オッズ", tbrDefault, 1 .Buttons.item(p).ToolTipText = "このレースのオッズ表を開きます" .Buttons.item(p).Image = 1 p = p + 1 .Buttons.Add p, "HYO", "票数", tbrDefault, 1 .Buttons.item(p).ToolTipText = "このレースの票数表を開きます" .Buttons.item(p).Image = 1 p = p + 1 .Buttons.Add p, "HENKO", "変更情報", tbrDefault, 1 .Buttons.item(p).ToolTipText = "この日の変更情報を開きます" .Buttons.item(p).Image = 3 p = p + 1 .Buttons.Add p, "RECORD", "レコード", tbrDefault, 1 .Buttons.item(p).ToolTipText = "この条件のレコードを開きます" .Buttons.item(p).Image = 2 Set mRecKey = rc.PreviousRecordKey(True) If mRecKey Is Nothing Then .Buttons.item(p).Enabled = False Else .Buttons.item(p).Enabled = True End If p = p + 1 .Buttons.Add p, "G1RECORD", "GIレコード", tbrDefault, 1 .Buttons.item(p).ToolTipText = "この条件のGTレコードを開きます" .Buttons.item(p).Visible = mData.IsG1() .Buttons.item(p).Image = 2 If mData.IsG1() Then Set mG1RecKey = rcG1.PreviousRecordKey(True) If mG1RecKey Is Nothing Then .Buttons.item(p).Enabled = False Else .Buttons.item(p).Enabled = True End If End If End With With mToolBar.ToolBar(2) .Buttons(1).Caption = "開催情報取得" .Visible = mData.IsPrompt() End With End Property
プロパティ(Property)でセットする方法で、リソースエディターに登録してるアイコンを読み込んで表示させるものです。
このプログラムを基ににしてアイコンを表示させましたら、問題なく表示させる事が出来ました。
アイコンをクリックした場合の動作については、クリックするとタイマーが起動して処理をする「馬吉」のやり方のままで問題ないと思います。
なぜ、わざわざタイマーで処理させているのかについては理由が今一つ判りませんが、動けば良しとしましょう。
「馬吉」では出馬表の開催選択画面で開催年をコンボボックスで表示して選択できる。
コンボボックスなので、普通の人は開催年はコンボボックスのリストから選択しているだろうと思います。
その方法で特に不満はないのですが、コンボボックスに直接年度を入力してみると動作がおかしい。
入力はできるのだが、入力した数字の後に金魚の糞みたいに数字が付加されてしまうのです。
そこで、この部分のプログラムがどうなっているのか調べてみました。
以下がプログラムの部分です。
' ' 機能: 開催年コンボボックスキー入力イベント ' ' 備考: なし ' Private Sub cmbYear_KeyPress(KeyAscii As Integer) On Error GoTo ErrorHandler If KeyAscii = 13 Then Call cmbYear_Click ElseIf (KeyAscii < Asc("0") Or KeyAscii > Asc("9")) And Not KeyAscii = 8 Then KeyAscii = 0 ' 文字を取り消します。 Beep ' エラー音を鳴らします。 End If cmbYear.Text = Format$(val(cmbYear.Text), "0000") Exit Sub ErrorHandler: gApp.ErrLog End Sub
見た感じでは特におかしいようには思えなかったので、最初は以下のようにやってみました。
cmbYear.Text = Left$(Format$(val(cmbYear.Text), "0000"), 4)
一見落着のように思えるるのですが、これでは全く駄目です。
そこで、入力する年度を変数にして、処理してみたりしましたが、これも全く駄目でした。
やがて解決させるのが面倒くさくなってきました。
以前の状態でも、金魚の糞がついてくるだけで、動作は一応行いますのでそのままにしておこうと思いましたが、ここでふと考えました。
cmbYear.Text = Format$(val(cmbYear.Text), "0000") が存在しないとどのような動作になるのかです。
当然コンボボックスには何の表示も行わないだろうと思っていたのですが、驚いた事にちゃんと表示を行うし金魚の糞もついてきません。
期待する通りの動作を行うのです。
どうやら、コンボボックス側で必要な処理を行ってくれているみたいです。
VBのバージョンによっては記載が必要なのかも知れませんが、私の所有しているVB6では必要ありませんでした。
必要ないどころか余計な動作をしてしまいます。
早速、この部分は削除しました。
「馬吉」の公開版には、オッズ表示で人気順に表示させた時に、馬単、3連複、3連単の表示にバグがあります。
バグと言っても、トップのオッズの表示幅が狭いために、左端の1桁分が隠れてしまい、オッズの順位を正確に表示出来ないように見えるバグです。
オッズのフレックスグリッドの表示幅は、ctlVODで設定するようになっているので、簡単だわいと思って設定を広くしたのですが、それが反映されません。
おかしいなあと思って、よくよく見ると、以下のようになっています。
途中を省略して、馬単部分から記載 Case 3: flexTab(1).Grid.ColWidth(0) = 360 flexTab(1).Grid.ColWidth(1) = 630 flexTab(1).Grid.ColWidth(2) = 540 For intLoop = 3 To 9 Step 3 flexTab(i).Grid.ColWidth(intLoop) = 360 flexTab(i).Grid.ColWidth(intLoop + 1) = 630 flexTab(i).Grid.ColWidth(intLoop + 2) = 630 Next For intLoop = 12 To flexTab(i).Grid.Cols - 1 Step 3 flexTab(i).Grid.ColWidth(intLoop) = 450 flexTab(i).Grid.ColWidth(intLoop + 1) = 630 flexTab(i).Grid.ColWidth(intLoop + 2) = 720 Next flexTab(i).Grid.ColWidth(flexTab(i).Grid.Cols - 1) = 810 Case 4: flexTab(1).Grid.ColWidth(0) = 360 flexTab(1).Grid.ColWidth(1) = 900 flexTab(1).Grid.ColWidth(2) = 540 For intLoop = 3 To 9 Step 3 flexTab(i).Grid.ColWidth(intLoop) = 360 flexTab(i).Grid.ColWidth(intLoop + 1) = 900 flexTab(i).Grid.ColWidth(intLoop + 2) = 630 Next For intLoop = 12 To 24 Step 3 flexTab(i).Grid.ColWidth(intLoop) = 450 flexTab(i).Grid.ColWidth(intLoop + 1) = 900 flexTab(i).Grid.ColWidth(intLoop + 2) = 630 Next For intLoop = 27 To flexTab(i).Grid.Cols - 1 Step 3 flexTab(i).Grid.ColWidth(intLoop) = 450 flexTab(i).Grid.ColWidth(intLoop + 1) = 900 flexTab(i).Grid.ColWidth(intLoop + 2) = 720 Next Case 5: flexTab(1).Grid.ColWidth(0) = 360 flexTab(1).Grid.ColWidth(1) = 900 flexTab(1).Grid.ColWidth(2) = 540 size1 = 360 size3 = 630 For intLoop = 3 To flexTab(i).Grid.Cols - 1 Step 3 If intLoop = 12 Then size1 = 450 ElseIf intLoop = 27 Then size3 = 720 ElseIf intLoop = 54 Then size3 = 810 ElseIf intLoop = 108 Then size3 = 900 End If flexTab(i).Grid.ColWidth(intLoop) = size1 flexTab(i).Grid.ColWidth(intLoop + 1) = 900 flexTab(i).Grid.ColWidth(intLoop + 2) = size3 Next End Select
このコードの、どこがミスっているか分かりますか?
実は、flexTabは、単・複・枠、馬連、ワイド、馬単、3連複、3連単の6種類があって、0〜5迄の番号が振ってあります。
ところが、馬単から3連単の幅を設定している最初のコードは全てflexTab(1).Grid.ColWidth(0) = 360のように馬連の設定になっています。
これでは設定が反映しないのも当然です。
早速、Case 3は flexTab(3).Grid.ColWidth(0) = 360、Case 4は flexTab(4).Grid.ColWidth(0) = 360、Case 5は flexTab(5).Grid.ColWidth(0) = 360のように変更しました。
トータルで9箇所の変更になります。
気が付けばつまらないミスですが、単に同じだと思ってコピペすると、こんな結果になります。
正規版はどうなのかと見たら、正常に表示されておりました。
言っている内容を確認していただくために、下の画像をご覧いただきたいと思います。
「馬吉」のオリジナルでは馬体重やオッズデータの項目はレース前の状態でも表示されるのですが、私のプログラムではデータが提供される前では、馬体重やオッズの項目は表示されないようになっています。
これは、画面の有効利用と言う点では優れていると思うのですが、レース当日の速報データを表示させた時に文字が豆粒の大きさになってしまって内容が見えないのです。
そしてこの状態は、突如直るので原因の特定が難しく悩みました。
文字の大きさが変わるのだから、文字のフォントサイズを指定してやれば良いのだろうと関係する部分に記載したりしましたが、一向に直りません。
それでは、どこに文字のサイズを小さくしているプログラムが書いてあるのかと探すとありました。
ユーザーコントロール(ctlWrappedGrid)に文字の大きさを1にしている部分があるのです。
' 空白セルのソート順を最後にする為
If Trim(.Text) = "" Then
.Text = Chr(&HFFFF)
.CellFontSize = 1
item.FRColor = .CellForeColor
.CellForeColor = item.FRColor
End If
InsertGridの中に内容が空白の場合は、文字の内容と文字の大きさを変えているのです。
理由は冒頭に記載のように、空白セルのソート順を最後にする為となっています。
試しにこの部分の文字の大きさを1から10に変更したら見事に直りました。
その代わり空白セルに変なドットマークが現れるようになりました。
確かにソートする場合は空白セルは最後にしたい場合はよくある事です。
競馬データの場合でも馬番が0の場合や空白は出走取り消しの場合などが多いですから、この処理は有効です。
しかし、何が何でも空白のデータの場合に文字の大きさを小さくしたり内容を変える必要があるのでしょうか。
私には必要な場合のみ変更するのが正統派的なやり方ではないかと思えるのです。
単純にこの部分の文字の大きさを変えただけでは、おかしな動作をするようですが、取敢えず変えてから対策を考える事にしました。
【追記】
最終的にはこのコードはコメントアウトにしました。
ソート処理が必要な場合にコードを考えれば済む話です。