Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


3897 / 13645 ツリー ←次へ | 前へ→

【59578】ADO RecordSet.UpDateのタイムラグについて みそじのおじさん 08/12/23(火) 16:33 質問[未読]
【59579】Re:ADO RecordSet.UpDateのタイムラグにつ... neptune 08/12/23(火) 19:25 発言[未読]
【59590】Re:ADO RecordSet.UpDateのタイムラグにつ... みそじのおじさん 08/12/24(水) 12:05 発言[未読]
【59604】Re:ADO RecordSet.UpDateのタイムラグにつ... neptune 08/12/24(水) 17:19 発言[未読]
【59610】Re:ADO RecordSet.UpDateのタイムラグにつ... みそじのおじさん 08/12/25(木) 8:28 お礼[未読]
【59612】Re:ADO RecordSet.UpDateのタイムラグにつ... neptune 08/12/25(木) 10:37 発言[未読]
【59617】Re:ADO RecordSet.UpDateのタイムラグにつ... みそじのおじさん 08/12/25(木) 19:23 お礼[未読]

【59578】ADO RecordSet.UpDateのタイムラグについ...
質問  みそじのおじさん  - 08/12/23(火) 16:33 -

引用なし
パスワード
   毎度お世話になっております。

現在、EXCEL,ADO,ACCESSを用いて、車の整備会社で、顧客管理、請求書・見積書作成、
部品管理、売上管理などをするものを作成しております。EXCELをユーザーインターフェースとして使用(Excel自体にデータを保存しない)しています。

 顧客の中には、車を複数台所有してる方が多いので顧客データを表示するユーザーフォ
ームに、所有する車名を表示するComboBoxを配置しております。車名を選択すると同フォ
ーム内にある車検証データを表示するTextBox群にその車の車検証データが表示されるようになっています。

 
その車が廃車になった時の処理を一例としてあげると、

Dim CN as New ADODB.Connection
Dim Res as New ADODB.RecordSet
Dim SQL as String

SQL="select * from T_車検証マスタ where F_顧客ID =" & ID & " AND F_車名 ='"
  & strCarName & "' ;"

Res.Open SQL, CN, adOpenKeyset, adLockOptimistic

If Not Res.EOF then
 .... 
 ....
 Res.Fields(F_車台番号).Value = Null
 ....
 ....

End If

このような感じで該当フィールドにNullを代入しています。
通常削除する場合、Res.Deleteですが訳あって、Nullを代入しております。
(テーブルの設計ミスです。リレーションで他のデータが消えてしまうので...)

この後

Res.UpDate をして

Call Control_Refresh(引数省略)

車検証データを表示するTextBox群のリフレッシュをするSubを呼んでいます。


/////////////////////////////////////////////////////////
Sub Control_Refresh(引数省略)

'Res.Fields(****).ValueがNULLならテキストボックスを空に、
'Nullでないなら、その値を表示する。

 .....
 .....

 If IsNull(Res.Fields(F_車台番号).Value)=False Then 'ここにブレークポイント設置
   TextBox1.Clear
 Else
   TextBox1.Text=Res.Fields(F_車台番号).Value
 End If

 .....
 .....
End Sub

/////////////////////////////////////////////////////////

このプログラムを実行すると、ブレークを張ってない場合に
IF IsNull(Res.Fields(F_車台番号).Value)=False の部分がFalseですり抜けてしまう場合がありあます。

ブレークを張って見ていると、止まった瞬間はRes.Fields(F_車台番号).ValueにNullを代入する前の車台番号が入っていて、その後、1秒ほどしてからNullになるといった具合
でした。

 Res.UpDateをしてから、実際にRecordSetがNullになるまでには、タイムラグがあるのでしょうか?(あって当たり前のような気がしていますが...)今はその場しのぎで、Application.Wait Now()+TimeValue("00:00:02")を入れて対応していますが、2秒という数字は環境によってまちまち(私のテスト環境では2秒で大丈夫ですが、本番の環境はPC2台のネットワークで使用しますので、条件が悪くなるかもしれません)だと思いますので、この待ち方はできれば回避したいです。
 
  Excel+ADO+Accessにおける待ちの常套手段とは、どういったものなのでしょうか?
アドバイス頂けると幸いです。よろしくお願い致します。
 

テスト環境 会社のPC Excel2003 Access2000 OS Xp RAM128MBのロースペックPC
      待ちをいれなくてもFalseですり抜ける事はありません。
      主にこちらで作成しているので、自宅でやるまで気づきませんでした。

テスト環境 自宅のPC Excel2003 Access2000 OS Vista CORE 2Quo 4GB
      待ちを入れないとかなりの確立ですり抜けます。

本番の環境 2台のPC共に、Excel2003 OS Xp Accessはインストールされていません
       LANケーブル接続
      ネットワークフォルダに1つのmdbファイルを置いて、それぞれのPCの  
      excelファイルからADOで接続して同時に使用します。

【59579】Re:ADO RecordSet.UpDateのタイムラグに...
発言  neptune  - 08/12/23(火) 19:25 -

引用なし
パスワード
   ▼みそじのおじさん さん:
こんにちは
私も知らないんですが、エラーは発生しないんですよね?
>Res.Open SQL, CN, adOpenKeyset, adLockOptimistic
>
>If Not Res.EOF then
> .... 
> ....
> Res.Fields(F_車台番号).Value = Null
から
>Res.UpDate
までの処理はどのような処理してますか?もっと情報があった方が識者も
Resを付け易いかと思います。

>Call Control_Refresh(引数省略)

>車検証データを表示するTextBox群のリフレッシュをするSubを呼んでいます。
なんですが、このプロシージャで、SQLを投げるか、パラメータクエリ
(作成しておいてですが)などをキックして再度取得しなおすとどうなりますか?

それと最初に全レコード取得してますが、必要なレコードだけは抽出出来ないので
しょうか?無駄です。特にネットワークが噛んで来ると。


>このプログラムを実行すると、ブレークを張ってない場合に
>IF IsNull(Res.Fields(F_車台番号).Value)=False の部分がFalseですり抜けてしまう場合がありあます。

>ブレークを張って見ていると、止まった瞬間はRes.Fields(F_車台番号).Valueに
>Nullを代入する前の車台番号が入っていて、その後、1秒ほどしてからNullになる
>といった具合でした。
>
> Res.UpDateをしてから、実際にRecordSetがNullになるまでには、タイムラグがあるのでしょうか?(あって当たり前のような気がしていますが...)今はその場しのぎで、Application.Wait Now()+TimeValue("00:00:02")を入れて対応していますが、2秒という数字は環境によってまちまち(私のテスト環境では2秒で大丈夫ですが、本番の環境はPC2台のネットワークで使用しますので、条件が悪くなるかもしれません)だと思いますので、この待ち方はできれば回避したいです。
> 
mdbのデータをメモリ上に読み込むまでは遅いときもありますが、メモリ上に
データがあるときはそれはおかしいですね。

>  Excel+ADO+Accessにおける待ちの常套手段とは、どういったものなのでしょうか?
recordsetはExcelで持っているんで、待ちなんか無いはずですが・・・?

以下の話は昔の話ではありませんので紹介しておきます。
ht tp://www.naboki.net/access/achell/achell_02.html
今なら、SQLServer2008Expressが無償でDLできますからそちらを使うことを
お勧めします。2008ではやったこと無いですが、2005では可能でした。

識者のアドバイスを待ちましょう。

【59590】Re:ADO RecordSet.UpDateのタイムラグに...
発言  みそじのおじさん  - 08/12/24(水) 12:05 -

引用なし
パスワード
   neptuneさん こんにちは

>エラーは発生しないんですよね?


If IsNull(Res.Fields(F_車台番号).Value)=False Then
   TextBox1.Text=""
Else
   TextBox1.Text=Res.Fields(F_車台番号).Value 'こちらに入ってきて、Nullを代入しようとしての
                        エラーにはなります。   
End If

>Res.UpDate
>までの処理はどのような処理してますか?

すいません。みなさんに分かりやすくと思い出来るだけ抜粋して書いていたつもりですが
間違っていましたね。UpDateはEnd IF 前に、Nullを代入したすぐ後になっています。
他の処理は、間には一切入っていません。

If Not Res.EOF then
 .... 
 ....
 Res.Fields(F_車台番号).Value = Null
 Res.Update
End If

>Call Control_Refresh(引数省略)

>>車検証データを表示するTextBox群のリフレッシュをするSubを呼んでいます。
>なんですが、このプロシージャで、SQLを投げるか、パラメータクエリ
>(作成しておいてですが)などをキックして再度取得しなおすとどうなりますか?

自宅のPCでしか起きない現象なので、帰ったら試してみます。
パラメータはまだ扱えないので、SQLの方で試してみたいと思います。
(今日は、クリスマスに長女の誕生日ときたもんで、ご報告が遅くなるかもしれません。
 質問しておいてなんですが、私事で申し訳ありません)


>それと最初に全レコード取得してますが、必要なレコードだけは抽出出来ないので
>しょうか?無駄です。特にネットワークが噛んで来ると。

一応、あのSQLで取れるのは1レコードだけなんですけど全フィールドって言う意味合いでしたか?
16あるフィールドの内Nullにしないのは2個のフィールドだけなので、"*"で取ったほうが書く量が少なく
なると思い使用していました。意味合いを取り違っていたらすいません。

>recordsetはExcelで持っているんで、待ちなんか無いはずですが・・・?
なるほど、そういう事ですか。

excelの持ち物ということは、例えば

1 Set Wb = WorkBooks.Open("******") 多少時間がかかる処理でもSetされるまで次にいかない

2 UserForm1.Show(vbModeless) すぐ次の処理にいってしまう。

1のような考え方でよろしいでしょうか?(例えが悪かったですかね?)


>今なら、SQLServer2008Expressが無償でDLできますからそちらを使うことを
>お勧めします。2008ではやったこと無いですが、2005では可能でした。
明後日、我が家にもついにネット環境が工事が入って整います。
SQLサーバー非常に興味ありますね。整いしだいDLしてみたいと思います。

【59604】Re:ADO RecordSet.UpDateのタイムラグに...
発言  neptune  - 08/12/24(水) 17:19 -

引用なし
パスワード
   ▼みそじのおじさん さん:▼みそじのおじさん さん:
こんにちは


>一応、あのSQLで取れるのは1レコードだけなんですけど全フィールドって言う意味合いでしたか?
>16あるフィールドの内Nullにしないのは2個のフィールドだけなので、"*"で取ったほうが書く量が少なく
>なると思い使用していました。意味合いを取り違っていたらすいません。
すみません。私の間違いでした。WHERE条件が目に入ってませんでした。

>>recordsetはExcelで持っているんで、待ちなんか無いはずですが・・・?
>なるほど、そういう事ですか。
なんですが、DBに働きかける場合は基本的に同期処理なんで、例えば、接続が
完了するまでとか、SQLを投げて、返ってくるまでとか、レコードセットを開くまでとかは制御が返ってきません。
今回のUpDateも多分DBに書き込むはずですから、変更が保存される間は
DBに制御がわたっているのではないでしょうか?
 但し、
Sub Control_Refresh(引数省略)内で
> If IsNull(Res.Fields(F_車台番号).Value)=False Then 'ここにブレークポイント設置
・・・
> End If
とする場合は、既に制御が返ってきてますし、そもそもExcel側のrecordsetでの処理になり、そういう意味で
recordsetは、UPDateを実行しなくても既にExcel側のバッファに持ってますから待つと言う事は
ないと思います。又、recordsetのカレントレコードを変更したらその時点で変更は保存されます。
・・・・詳しくはHelpでお願いします。

>SQLサーバー非常に興味ありますね。整いしだいDLしてみたいと思います。
それなら
「Microsoft? SQL Server? 2008 Express with Advanced Services」
ht tp://www.microsoft.com/downloads/details.aspx?familyid=B5D1B8C3-FDA5-4508-B0D0-1311D670E336&displaylang=ja
が、SQL Server 2008 Management Studio Basicが付属していて楽チンです。

この際、VB2008Express EditionもDLしてインストールてはどうですか。これも無償だし。
初心者、アマチュア向けとはいえ、プロで無い限りこれで充分。
開発用だから可能性はExcelの比ではないですよ。
但し、SQL Server EEもVB2008EEもそれなりの勉強は必要ですけどね。

所でうらやましいPC環境ですねぇ〜。
#娘さん・・誕生日おめでとうございます。
#誕生日とクリスマスか^ ^ まっ正月が誕生日より良いかも^ ^;

【59610】Re:ADO RecordSet.UpDateのタイムラグに...
お礼  みそじのおじさん  - 08/12/25(木) 8:28 -

引用なし
パスワード
   neptuneさん おはようございます。

SQLを再度投げつける方法で試してみました。

IF Not Res.EOF Then
 ......
 ......
 Res.Fields(F_車台番号).Value=Null
 Res.UpDate
 Res.Close '一度レコードセットを閉じて
End IF

Call Contol_Refresh(引数省略)


Sub Control_Refresh(引数省略)

Dim SQL as String

'もう一度新たにSQLを投げつける

SQL="select * from T_車検証マスタ where F_顧客ID =" & ID & " AND F_車名 ='" & strCarName & "' ;"

Res.Open SQL, CN, adOpenKeyset, adLockOptimistic

IF Not Res.EOF Then

  If IsNull(Res.Fields(F_車台番号).Value) = False Then
   TextBox1.Text = ""
  Else
   TextBox1.Text = Res.Fields(F_車台番号).Value
  End IF

End IF

Res.Close
Set Res = Nothing

End If

この場合、問題なくNullが帰ってきて、正常に動作するのを確認いたしました。
今回はこの方法で対応したいと思います。

>以下の話は昔の話ではありませんので紹介しておきます。
>ht tp://www.naboki.net/access/achell/achell_02.html

ご紹介のサイト読ませてもらいました。
mdbファイルをネットワークで使用した場合の破損の可能性とファイルの最適化に

ついてでしたが現在、テスト環境ですとAccessがインストールしてありますので

終了時に最適化をする にチェックをいれていますが、本番の環境では、Access

が入っていないためプログラムで最適化をするというのは、無理なのかなと思っ

ています。私が時々出向いて、backupを持って帰ってきて最適化をするという流

れになると思います。

 backupに関しては、excel起動時にmdbのファイルコピーを自動でするというプ

ログラムを組んでいます。(壊れたmdbファイルを上書きしない為に、いくつかの

チェック項目をもうけてチェックがOKだった時だけファイルのバックアップを取

る仕組みにしてあります。ですがまだ壊れたmdbに遭遇していないので、私のロジ

ックで間違いなく動くかは不安ですが)

実は、現在のシステムを作成しているのは、excelファイルが破損した為でした。

作成までの経緯を箇条書きで書きますと

1 2年ほど前、自分の嫁の兄貴が整備工場を立ち上げるということで、できるだけ 整備に集中してもらいたいと思い、 Excelで請求書を作成するファイルを作成した。(excelファイルを3つ,4つをからめて使用する感じで今見返すと、とても人に見せれないようなマクロがズラリってかんじです。人生初のexcel VBAでした。)

2 2ヶ月ほど前にその請求書を保存していたファイルが破損した。(シート約200
 枚、8MBぐらいまでいってました... 動作もメチャメチャ遅くなっていて、早
 めに手を打っておけばよかったのですが。一番やってはいけない シートの雛
 形コピー(マクロを含んだままの状態で)1つのエクセルブックに保存していま
 した...)
 
3 会社を立ち上げたときは兄貴1人だったが、従業員が1人増えた。

4 破損ついでに、新しい物を作ってほしいと言われた。

5 作り直す条件が、使いなれたExcelの請求書の雛形は残して欲しい。

6 2人で同時に作業できるタイプの物にして欲しい。(これがADO,mdbを選択した最
 大の理由ですね)今後も従業員が増える可能性がある

7 無論今まであったexcelのデータを引き継いで欲しい。(請求書データは飛びま
 したが、顧客データ、部品の管理データや整備工賃データなどは無事だった
 ので)

8 これは言われた条件ではないですが、2台のPCにはAccessは入っていない

このような条件で、私はexcel+ADO+Access(mdb)の選択をしましたが
今度はmdbファイルの破損の可能性....ん〜SQL serverも視野にいれないと駄目っ
ぽいですね。

アドバイスありがとうございました。まだまだ精進いたします。(VBも必ずDLしますね!! 正直最近では、早く本家VBに移行がしたく、Excelを使っているという意識をさせないという作り方をしています。セルを使わない。データの読み書きはINIファイルから、WorkSheetFunctionを使わない、など本家にないものは
一切排除しております。オートフィルターなんかも排除したおかげで、ソートのロジック(クイックソート、
バブルソートなど)なんかも勉強できましたし。人にはエクセル使っている意味ないんでないのと言われま
すが..)

>所でうらやましいPC環境ですねぇ〜。

なんとか冬のボーナスで買ってもらいました。(って自分で稼いだお金なんですけどね(苦笑) ヤ○ダ電気のPC売り場で3時間ほど迷いました。)

>#娘さん・・誕生日おめでとうございます。
お心遣いありがとうございます。

>#誕生日とクリスマスか^ ^ まっ正月が誕生日より良いかも^ ^;
親としては、プレゼントが1つという訳にもいかず、おまけに下の子は
 10日生まれとあって、12月の出費はハンパないっす。
 さーて父ちゃんがんばるぞー!!

ではでは失礼致します。

【59612】Re:ADO RecordSet.UpDateのタイムラグに...
発言  neptune  - 08/12/25(木) 10:37 -

引用なし
パスワード
   ▼みそじのおじさん さん:
こんにちは

読んでくれると良いんですが、
>本番の環境では、Access
>が入っていないためプログラムで最適化をするというのは、無理なのかなと思っ
>ています。私が時々出向いて、backupを持って帰ってきて最適化をするという流
>れになると思います。
私自身はAccessなしでの経験は無いのですが、mdbの最適化はAccessなしでも
出来ますよ。CompactDatabase を使います。
「ADO 経由で Microsoft Access データベースを最適化する方法」
ht tp://support.microsoft.com/kb/230501/ja

>4 破損ついでに、新しい物を作ってほしいと言われた。
幸せなお兄さんですね。ご存知でしょうが、自前のソフトなんか発注すると
最低ん10万はかかるでしょうから。ネットワークが絡んでくると、一桁上がる
かも???メンテナンスが、又めちゃくちゃ高い。

後、経験談ですが、私も知り合いの人にソフトが動かんから見てくれと
言われて、見たことあるんですが、コンパイルされたmdeが壊れて、OSから
mdeとして認識もされないことがありました。勿論私にはバイナリレベルで
救うスキルはないのでご愁傷様と宣告しました。
これはローカルmdeで顧客、見積もり、請求書など管理するソフトでした。
・・・紙にも書いていたようで地獄には陥りませんでしたが、キツイですよ。

私も本家VB万年初心者ですが、頑張りましょう。
#VB6(VBA)とは別言語と思ってください。私自身の感覚では書式は
#違いますが、frameworkを扱う点ではC#もVBも同じ感じです。
#正直印刷までこなすと実に面倒と思います。
#でもDB操作自体はExcelより楽チンかも?^ ^;;

【59617】Re:ADO RecordSet.UpDateのタイムラグに...
お礼  みそじのおじさん  - 08/12/25(木) 19:23 -

引用なし
パスワード
   ▼neptune さん:
こんばんは

>読んでくれると良いんですが、
今日は外回りをしておりました。遅れてすいません。


>私自身はAccessなしでの経験は無いのですが、mdbの最適化はAccessなしでも
>出来ますよ。CompactDatabase を使います。
>「ADO 経由で Microsoft Access データベースを最適化する方法」
>ht tp://support.microsoft.com/kb/230501/ja

ありがとうございます。これで最適化もできそうです。
私は行き詰まった時には、まずhelpに目を通して、それからググリに入りますが、
MSDNのそこまで、なかなかたどり着けないんですよね。つくづく自分から出てく
る検索キーワードのボキャブラリーの少なさと検索の下手さを感じています...

>幸せなお兄さんですね。ご存知でしょうが、自前のソフトなんか発注すると
>最低ん10万はかかるでしょうから。ネットワークが絡んでくると、一桁上がる
>かも???メンテナンスが、又めちゃくちゃ高い。

私が車の修理をお願いすると、いつも
「妹のダンナから、修理代なんかもらえるわけねーだろっ」 って言われ
せめて掛かった実費だけでも、と言っても受け取らないような粋な兄貴なもんで
私の持てる力全てを(全てでも足りないんですが)注ぎ込んで作成しております。

>私も本家VB万年初心者ですが、頑張りましょう。
>#VB6(VBA)とは別言語と思ってください。私自身の感覚では書式は
>#違いますが、frameworkを扱う点ではC#もVBも同じ感じです。
>#正直印刷までこなすと実に面倒と思います。
>#でもDB操作自体はExcelより楽チンかも?^ ^;;

励ましの言葉ありがとうございます。本家をやり始めたら、そちらでもお世話に
なるかもしれません。ハンドルは変えませんので見かけた時はよろしくお願いい
たします。

neptuneさんみたいな人が身近にいればなーと最近つくづく思います。
(身近にプログラムをする人が1人もいないもので)

 私は札幌の人間なのですが、すすきのあたりで酒を飲みながら、プログラム談義
に花をさかせて って、  えっ酒の席で仕事の話はヤダって....(笑)
 これは冗談として(半分本気でしたけど)

今年一年大変お世話になりました。それではよいお年をお迎え下さい。

3897 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free