1

いくつかのドロップダウン メニュー/ユーザー アクションに応じて、いくつかのデータ フィードがパラメーターを SQL クエリに戻すワークブックがあります。これにより、ワークブックのトリムが維持され、計算が改善されます。アイテム レベルの詳細をすべてワークブックにローカルに保持することは実際的ではありません。

VBA の一部の要素は、これらのパラメーター化されたクエリから得られるデータの評価に依存しています。ここで問題が発生します。VBA は、マクロ内のすべてを評価する前に、パラメータがクエリに返されるのを待ちません。

フィードが更新されるまで VBA の実行をプログラムで「一時停止」するためのベスト プラクティスについて、何か考えやアドバイスがあるかどうか知りたいです。私の現在の回避策は、VBA を 2 つの部分にチャンクし、変更されたデータに依存するものを別の関数にスローし、application.ontime を使用して X 秒間一時停止することです。

Application.OnTime Now + TimeSerial(0, 0, 10), "Restart"

これは 90% の解決策ですが、理想的とは言えません。時間の長さは任意です。非常に遅い接続では長さが不十分であり、高速な接続では不必要に遅くなります。

理想的には、Excel の準備が整うまで待ってから続行する何らかの方法があるでしょう。MS Internet Controls ライブラリを使用する場合と同様に、使用できます

Do Until .document.ReadyState = "complete"

IE が準備完了状態を返すまで実行を一時停止します。よりエレガントなソリューションのための戦略はありますか?

編集:以下の jon ごとに、コードを追加し、SQL クエリがどのように機能するかを説明します。

select sts1.studentid, sts1.alphascore as testcycle, 
sts2.numscore as lexile, sts3.alphascore as gleq, sts4.numscore as nce

from ps.studenttestscore sts1
join ps.students stu on (sts1.studentid = stu.id)
join ps.studenttestscore sts2 on (sts1.studenttestid = sts2.studenttestid)
join ps.studenttestscore sts3 on (sts1.studenttestid = sts3.studenttestid)
join ps.studenttestscore sts4 on (sts1.studenttestid = sts4.studenttestid)

where (stu.id = ? ) and (sts1.testscoreid = 578) and (sts2.testscoreid = 575) 
and (sts3.testscoreid = 577) and (sts4.testscoreid = 576)

? 関連する学生 ID を渡すパラメーターです。MS クエリは、そのパラメーターのセル値を使用します。表示されるセルには、選択された学生に基づいたルックアップがあります。

=IFERROR(INDEX(Stu!$B:$F,MATCH(Student!B2,Stu!$F:$F,0),1),999999)

(iferror は、何らかの理由で不適切な値が選択された場合に厄介なダイアログ ボックスがポップアップするのを防ぐために、任意の数値を渡すだけです)。

4

1 に答える 1

2

あなたの間違いはMS-Queryを使用しています。ADODBを使用してデータベース呼び出しをコーディングし、ADODB.CommandオブジェクトのExecuteメソッドを待ちます。

...それがあなたが実際にやっていることなら。ここにはある程度の当て推量がありますが、クエリのステータス(埋め込まれているシートではなく)が必要な情報であるように見えます。

このコードはSQLクエリを非同期的に呼び出します-概念的にはコマンドオブジェクトに似ていますが、これは(私が思うに)実際に行っていることです-粗い「スリープ」ループはプログレスバー、またはフラグをポーリングするためのコードに置き換えることができます他の場所での計算。

参考までに、ADOオブジェクトの状態とステータスのプロパティは混乱を招く可能性があります。一般に、0は閉じることを意味し、1は開いていることを意味し(開いている接続またはデータセットを返すオブジェクトの場合)、1より大きい値は待機または実行に対応します。

もちろん、クエリを同期的に呼び出すこともできます。

'DataConnection'のコードを提供することもできますが、そのためにConnectionStrings.comにアクセスする方がはるかに優れています。

パブリック関数FetchRecordSet(SQL As String、オプションのCursorType As CursorTypeEnum = adOpenForwardOnly)As ADODB.Recordset
エラー時に次を再開

FetchRecordSet =NewADODB.Recordsetを設定します

FetchRecordSetを使用

    .CacheSize = 8
    .ActiveConnection=DataConnectionを設定します
    .Open SQL 、、 CursorType、adLockReadOnly、adCmdText + adAsyncFetch

    Do While .State> 1
        Application.StatusBar="データを取得しています..."
        スリープ250
    ループ

で終わる

Application.StatusBar = False

終了機能





[更新]

この回答を投稿してから、何かを学びました。

コマンドの名前、行セットを返す関数、またはMS-Accessデータベースの名前付きクエリがわかっている場合は、次のようにわざわざ呼び出す必要はありません。

    SQL = "SELECT * FROM MyQuery"
    .Open SQL 、、 CursorType、adLockReadOnly、adCmdText + adAsyncFetch

adCmdStoredProcコマンドを名前で呼び出し、定数を使用して名前付きコマンドであることをデータベースエンジンに通知します。

    SQL = "MyQuery"
    .Open SQL 、、 CursorType、adLockReadOnly、adCmdStoredProc + adAsyncFetch

それははるかに速く実行されます。

MSDNでCommandTypeEnumを検索し、最適なものを使用してください。

https://msdn.microsoft.com/en-us/library/ms675946(v=vs.85).aspx

名前付きテーブルに使用 adCmdTableし、それが「ビュー」オブジェクトよりもうまく機能するかどうかを確認しadCmdStoredProcます。データベースエンジンによって異なることがわかりました。

[/アップデート]

于 2011-03-08T16:23:17.640 に答える