2011-02-24 5 views
1

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

私のVBAのいくつかの要素は、これらのパラメータ化されたクエリに由来するデータの評価に依存します。ここで問題が発生する - VBAは、マクロ内のすべてを評価する前に、パラメータがクエリに返されるのを待たない。

フィードが更新されるまでVBAの実行をプログラムで「一時停止」するためのベストプラクティスについてのご意見やアドバイスがあれば、私は不思議です。今私の仕事は、私のVBAを2つの部分にチャンクし、変更されたデータに依存するものを別の関数にスローし、application.ontimeを使用してX秒間ポーズすることです。

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

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

Excelが準備完了するまで待ってから、続行するのが理想的です。 MSインターネットを使用する際にどのようにと同様に、あなたはIEがレディ状態に戻るまで実行を一時停止する

Do Until .document.ReadyState = "complete" 

を使用することができ、ライブラリを制御します。より洗練されたソリューションのための戦略?

編集:以下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だけで不適切な値が何らかの形で選択されます場合はポップアップするから厄介なダイアログボックスを防ぐために、任意の番号を渡します) 。

+0

あなたはSQLの呼び出しや、周囲のコードの長い一例を与えることができますしてください - それは、実行を待っていることだろう、なぜ私はわかりません。歓声 –

+0

あなたはそのSQLをどのように実行しているのかは不明です - あなたのVBAコードを表示できますか?正確にあなたの "データフィード"には何を使用していますか? –

答えて

2

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

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

このコードは、概念的にはコマンドオブジェクトと似ていますが、実際に何をしているのかはわかりませんが、粗い 'スリープ'ループはプログレスバーやコードに置き換えることができます他の場所でフラグや計算をポーリングするためのものです。

FYIでは、ADOオブジェクトの状態とステータスのプロパティが混乱する可能性があります。一般にゼロはクローズを意味し、1はオープン(オープン接続またはデータセットを返すオブジェクト)を意味し、1より大きい値は待機または実行に対応します。

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

私はあなたに 'DataConnection'のコードを与えることができましたが、あなたはConnectionStrings.comに行く方がずっと良いでしょう。私はこの答え掲載以来、私は何かを学んだ

 

Public Function FetchRecordSet(SQL As String, Optional CursorType As CursorTypeEnum = adOpenForwardOnly) As ADODB.Recordset 
On Error Resume Next 

Set FetchRecordSet = New ADODB.Recordset 

With FetchRecordSet 

    .CacheSize = 8 
    Set .ActiveConnection = DataConnection 
    .Open SQL, , CursorType, adLockReadOnly, adCmdText + adAsyncFetch 

    Do While .State > 1 
     Application.StatusBar = "Retrieving data... " 
     Sleep 250 
    Loop 

End With 

Application.StatusBar = False 

End Function 





[更新]:

を使用すると、コマンドの名前を知っている場合は、rowset-関数を返す、または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より良い動作するかどうかを確認 - 私は」データベースエンジンごとに異なることがわかりました。

[/更新]

関連する問題