[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2007/04/14(Sat) 09:05
投稿者名:やまちゃん
Eメール:
URL :
タイトル:
ファイルの最終更新日の変化を取得?
はじめまして。
初めて投稿します。初心者です。
VB6,Xpです。

現在作成中のシステムで、Accessにレコードを追加して、その更新内容をグリッドコントロール
に反映させようとしています。

が…、

少々複雑な計算後のレコード追加なので、グリッドコントロールの更新が先に処理されてしまい
、表示が正しく更新されていません。

計算などで、標準モジュールを使っているのでDoEventsは使えない(?)と思い、下記のように
フォームにタイマーを1つ貼り付けファイルの最終更新日を取得してこれが変化するまでは
待機させる、という作戦でもうまく行きませんでした(LAST_UPDATEがうまく取得できません)。


Public CURRENT_FILE As String
Public LAST_UPDATE As Single

Private Sub Timer_Update_Timer()
    Dim Fso     As New FileSystemObject
    Dim FsoFile As File
    
    If Len(CURRENT_FILE) > 1 Then
        Set FsoFile = Fso.GetFile(CURRENT_FILE)
        LAST_UPDATE = FsoFile.DateLastModified
        Set FsoFile = Nothing
    End If
    
End Sub

Private Sub Command_Update_Click()
    Dim mySQL         As String
    Dim myDB          As String
    Dim sngLastUpdate As Single
    
    (略)
    
    '=== 現在の最終更新日を取得 ===
    'Timerの所と同じ処理をする関数です。
    sngLastUpdate = fLastUpdateYMD(App.Path & "\dat\" & myDB)
    LAST_UPDATE = 0
    CURRENT_FILE = App.Path & myDB
    Timer_Update.Interval = 500
    
  「ここでAccessファイルを更新します。長いので省略します。」
    
    '=== 更新が終了するまで待機 ===
    Do While LAST_UPDATE <= 1
        DoEvents
    Loop
    Do While sngLastUpdate - LAST_UPDATE = 0
        DoEvents
    Loop
        
    CURRENT_FILE = ""
        
    '=== グリッドコントロール更新 ===
    'グリッドコントロールを更新する処理を呼んでます。
    Call sGrid_SiireZaiko_Input(SUB_CAPTION)
            
End Sub


sngLastUpdateでAccessファイルを更新する前の最新更新日を取得し、ファイル更新後に
再びLAST_UPDATEで取得し双方を比較しています。

どなたかアドバイスをよろしくお願いします。

_| ̄|○

投稿時間:2007/04/15(Sun) 16:46
投稿者名:やまちゃん
Eメール:
URL :
タイトル:
Re: ファイルの最終更新日の変化を取得?
すみません。
説明不足だったのでしょうか?
簡単に言うと

@MDBデータの更新

A様々なデータの再計算(これに時間がかかります)

Bグリッドコントロールの表示更新

という順序を望んでいるにもかかわらず、Aの計算が終わる前に
Bでグリッドコントロールが再表示されてしまい、MDBは最新データに更新されても
グリッドコントロールの表示は古いままのデータが表示されてしまうということです。

こういった経験がある方がいらっしゃいましたらアドバイスお願いいたします。

本日いろいろと試した結果、FileDateTime関数を使用して表示は最新のものが表示される
ようになりましたが、1回の処理に5秒ほどかかります。Aの計算自体は1秒弱で完了する
のですが、………。

よろしくお願いいたします。

投稿時間:2007/04/16(Mon) 10:04
投稿者名:GOD
Eメール:
URL :
タイトル:
Re^2: ファイルの最終更新日の変化を取得?
タイマーを使用して更新日を確認している理由が良く分かりません。
ACCESSの更新処理をした後にグリッドへ表示すればよいと思うのですが、それではなぜダメだったのか。
----
Sub データ更新プッロシージャー
  ACESSへの更新処理
  グリッドへの表示処理
End Sub
----
あとグリッドはどんなのを使用してますか。MSFlexGridみたいにデータを見ながらプログラム側で行,列を追加するタイプですか?
もしそうなら始めに行を大きく取って(1000行とか)データを全て表示した後、行数を調整すれば速度向上できるかも。

投稿時間:2007/04/16(Mon) 10:09
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^2: ファイルの最終更新日の変化を取得?
> 説明不足だったのでしょうか?
「mdbにレコードを追加する」と「グリッドへ表示している」という点までは
わかるのですが、それと「ファイルの最終更新日」の間に、何の関係が
あるのかがさっぱりわかりませんでした。
(というよりも、最終更新日の監視が、「手段」なのか「目的」なのかわからない…)


> グリッドコントロールの表示は古いままのデータが表示されてしまうということです。
> こういった経験がある方がいらっしゃいましたらアドバイスお願いいたします。
グリッドというのが、どのコントロールの事かがわかりませんが、
mdb に記録する際に、明示的にトランザクションを利用していますか?
また、グリッドに表示するためのコネクションと、更新のためのコネクションは
同一の物ですか? それとも、一つの mdb に複数のコネクションがある状態ですか?
また、表示前にキャッシュをクリアしたり、グリッドの再更新などを行っていますか?
http://www.canalian.com/workshop/access/JetCache.html

投稿時間:2007/04/16(Mon) 10:25
投稿者名:やまちゃん
Eメール:
URL :
タイトル:
Re^3: ファイルの最終更新日の変化を取得?
GODさん、魔界の仮面弁士さんありがとうございます。

グリッドコントロールというのは「階層フレキシブルグリッドコントロール(MSHFlexGrid)」
のことです。

今から、仕事で外出します。夕方には戻る予定ですので、改めてじっくり読ませていただき、
回答させていただきます。

本当にありがとうございます。

投稿時間:2007/04/16(Mon) 13:13
投稿者名:ダンボ
Eメール:
URL :
タイトル:
Re^4: ファイルの最終更新日の変化を取得?
「MDBデータの更新」が別プロセスなのでWaitを噛ませてACCESS終了の同期をとろう
という話だと思います。


(1)「MDBデータの更新完了」=「MDBファイルの更新時刻が変わる」ですか?
  MDB更新中は刻々と変わっているのでは?
(2)上記がOKだとしても、更新時刻の判定が極めて怪しい。
  Public LAST_UPDATE As Single
  LAST_UPDATE = FsoFile.DateLastModified
  Do While sngLastUpdate - LAST_UPDATE = 0
  コンパイルラーとはならなくても多分Waitしていない(憶測)

投稿時間:2007/04/16(Mon) 15:26
投稿者名:やまちゃん
Eメール:
URL :
タイトル:
Re^5: ファイルの最終更新日の変化を取得?
説明不足ですみません。
まず、何をしようとしているのか?ですね。

やまちゃんこと私は、牛乳販売店を経営しているものです。
ここで質問させて頂いた処理は、仕入(あるいは在庫)のレコード
(フィールドは、日付,商品コード,繰越数,仕入数,『販売数』,営業使用数,
棚卸数,その他(破損など),登録日,更新日)を登録(新規レコード作成時)したときに、
顧客の契約内容(月曜日に○○牛乳1本配達するなど。別MDB)を元に
その日の販売数を計算しています。(←これに時間がかかっています。)

ですので、二つのMDBに複数のコネクションがある状態になります。
グリッドコントロールの更新は、固定行・列以外のテキストを

For intRow = 1 To .Rows - 1
    For intCol = 1 to .Cols - 1
        .TextMatrix(intRow,intCol) = ""
    next intCol
next intRow

のような感じで消去しているのみです(中央揃えにしたりする再設定に時間がかかったためです)。

GODさんのおっしゃる通り、タイマーを使用したのは、レコードの更新の
完了とコントロールの表示のタイムラグを解決しようとした苦肉の策です。

ダンボさん、コメントありがとうございます。
おっしゃる通り、DateLastModifiedとタイマーを使ってすると、LAST_UPDATEが取得
出来ません。

皆様、お忙しい中ありがとうございます。

投稿時間:2007/04/16(Mon) 17:59
投稿者名:GOD
Eメール:
URL :
タイトル:
Re^6: ファイルの最終更新日の変化を取得?
> For intRow = 1 To .Rows - 1
>     For intCol = 1 to .Cols - 1
>         .TextMatrix(intRow,intCol) = ""
>     next intCol
> next intRow
>
列数が何列あるのかな。
もし列数が多い様なら↓にすると多少早くなりますよ。(Rows-1)*(.Cols-1)回の処理が(Rows-1)*2回の処理になります。
もし、列0が数字のカウントだけなら保存する必要もないかな。
    Dim lngRow As Long
    Dim strCol0() As String
    Dim lngSaveRows As Long

    With MSHFlexGrid1
        '行数を保持
        lngSaveRows = .Rows
        '列0の文字列を保存
        ReDim strCol0(lngSaveRows)
        For lngRow = 1 To lngSaveRows - 1
            strCol0(lngRow) = .TextMatrix(lngRow, 0)
        Next
        '見出し行以外は削除(データクリア)
        .Rows = 1
        '行数を復活
        .Rows = lngSaveRows
        .FixedRows = 1
        '列0のデータを復活
        For lngRow = 1 To lngSaveRows - 1
            .TextMatrix(lngRow, 0) = strCol0(lngRow)
        Next
    End With

投稿時間:2007/04/16(Mon) 19:50
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^6: ファイルの最終更新日の変化を取得?
> ですので、二つのMDBに複数のコネクションがある状態になります。
ならば、先に紹介した URL にもあるように、BeginTrans / Commit が必須です。
そうしないと、書き込みが非同期で行われることになるので、編集結果が
mdbファイルに反映されるまでに、タイムラグが生じる結果となります。

その上で、厳密性を高めるために、先の URL の手順に従って読み書きそれぞれの
キャッシュを強制更新してやればベターかと。

> のような感じで消去しているのみです
ループさせずとも、消去だけなら MSHFlexGrid.Clear メソッド一発で済むのでは。

消去ではなく、同じデータを一括指定するという意図であれば、
TextMatrix プロパティよりも、Text プロパティを使った方が高速です。
(FillStyle プロパティを併用)

また、各セルに異なるデータを与える場合は、Clip プロパティを使うと、
ループさせずに、複数のセル範囲を一括で高速設定する事ができます。

投稿時間:2007/04/17(Tue) 06:51
投稿者名:やまちゃん
Eメール:
URL :
タイトル:
Re^7: ファイルの最終更新日の変化を取得?
GODさん、魔界の仮面弁士さんお世話になります。

> ならば、先に紹介した URL にもあるように、BeginTrans / Commit が必須です。
> そうしないと、書き込みが非同期で行われることになるので、編集結果が
> mdbファイルに反映されるまでに、タイムラグが生じる結果となります。
>
> その上で、厳密性を高めるために、先の URL の手順に従って読み書きそれぞれの
> キャッシュを強制更新してやればベターかと。

私も、このあたりが原因ではないか?という気がしてきました。
グリッドコントロール(MSHFlexGrid)に関しては、問題にしている箇所では、せいぜい
100行×8列ですが、顧客マスターの処理の部分などで非常に参考になりました。

私が、これからどのあたりを勉強して理解していかなければならないか?という
方向性を示していただき非常に助かっています。

これから先は、「そんなことは自分で調べろ!」という内容になってきてしまいそうなので
自分で頑張ってみようかと思います。

本当にありがとうございました。