単一のボタンをクリックして、そのシートにあるクエリテーブルを更新するコードを作成しています。
今、私の問題は、情報の一部をコピーするフレッシュ後にさらにコードがあることですが、このコードは更新が開始され、情報がまだ置き換えられていない直後に実行されています。
更新が完了するのを待って、残りのコードを続行できます。
インターネットの速度などに応じて、長すぎたり短すぎたりしないように、5秒間だけ待機するのではなく、リフレッシュ期間だけ待機したいのです。
これどうやってするの?
編集:
簡単なコード:
ActiveWorkbook.RefreshAll
ここでは、すべての更新が完了するまで遅延または待機コードが必要です...
MsgBox("The Refreshing is Completed!")
その方向に何か。しかし、実際に終了する前にmsgboxを言うことはできません。インターネットの速度によっては、リフレッシュにかかる時間が短くなったり長くなったりするため、実際のリフレッシュ時間の変数にしたいのです。
Webクエリの外部データ範囲プロパティには、「バックグラウンド更新を有効にする」などのチェックボックスがあります。このチェックボックスをオフにして、目的の効果を実現します。
このページの下部をご覧ください: http://www.mrexcel.com/tip103.shtml for pictures
編集:
目的の効果を示す2つのマクロを次に示します。
Sub AddWebquery()
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;http://de.selfhtml.org/html/tabellen/anzeige/table_tr_th_td.htm", _
Destination:=Range("$A$1"))
.Name = "table_tr_th_td"
.BackgroundQuery = False
.RefreshStyle = xlInsertDeleteCells
.WebSelectionType = xlSpecifiedTables
.WebFormatting = xlWebFormattingNone
.WebTables = "1"
.Refresh BackgroundQuery:=False
End With
End Sub
Sub TestRefreshing()
Range("A1").Clear
ActiveWorkbook.RefreshAll
Debug.Print "Test: " & Range("A1").Value
End Sub
AddWebqueryを実行してクエリを追加し、TestRefreshingを実行して効果をテストします。行を変更できます.BackgroundQuery = False
をTrue
に変更すると、間違った結果になります。
10秒スリープのテストページ:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>SO-Test</title>
</head>
<body>
<?php
sleep(10);
?>
<table border="1">
<thead>
<tr><th>1</th></tr>
</thead>
<tbody>
<tr><td>2</td></tr>
</tbody>
</table>
</body>
</html>
同様の問題が発生しましたが、次の方法で解決しました。
For i = 1 To ActiveWorkbook.Connections.Count
ActiveWorkbook.Connections(i).OLEDBConnection.BackgroundQuery = False
'MsgBox ActiveWorkbook.Connections(i).OLEDBConnection.BackgroundQuery
Next
ActiveWorkbook.RefreshAll
このように、更新を呼び出す前に、すべての接続backgroundQuery
プロパティが確実にfalse
になるようにすることができます。
PowerPivotモデルを使用していたため、モデルを保存して閉じる前にデータを更新したかった。ただし、Excelは更新が完了する前にモデルを閉じただけであり、モデルは開いたときに更新を再開しました。
RefreshAllメソッドの直後に次の行を追加すると、うまくいきました。
ThisWorkbook.RefreshAll
Application.CalculateUntilAsyncQueriesDone
それがあなたにも役立つことを願っています。
速度を上げるために、必ずイベントを無効にしてください。
私はExcel 2010を使用していることに注意してください、この方法が古いバージョンで利用可能かどうかはわかりません。
別の方法としては、Workbooks.Openコマンドを使用して、代わりに別のワークブックとしてURLをロードします。
これにより、通話が終了した直後に、Webリクエストのデータにフルアクセスできます。さらに、Webクエリのようにフリーズする代わりに、Excelは読み込み中に進行状況バーを表示します。
この質問に関する私の答えを参照してください: クエリが完了したときにExcel Webクエリからのデータを後処理するにはどうすればよいですか?
そのアプローチのトレードオフは、自分で取り戻したデータの処理を管理する必要があることです。Excelは、指定された宛先にデータを配置しません。
あなたがやっているように見えるものとかなり似たものを試した後、私たちはこのルートに行きました。
「[email protected]から2014-08-11「これは、完全な制御を可能にするシンプルなバージョンです。 'RefreshAllを使用する代わりに、次のサブルーチンを作成します。'ExclVBAから実行したい場所でルーチンを呼び出します。 「もう1つの利点は、ピボットテーブルを更新しないため、干渉しないことです」そして、更新されたデータに依存するピボットがある場合、クエリの更新が完了した後にピボットに対して同様の更新を実行できます。
sub RefreshQueries()
dim ws as worksheet
dim qt as QueryTable
For each ws in thisworkbook.worksheets
For each qt in ws.querytables
qt.refresh
next qt
next ws
end sub
ActiveWorkbook.RefreshAll
Do While Application.CalculationState <> xlDone
DoEvents
Loop
私はその古い質問を知っていますが、これは私のために働いた。数式の計算中の待機にも機能します。
VBAでスクリプトを待機させたい場合は、スリープを使用する必要があります。ただし、Excel vbaでは睡眠が機能しない場合があります。
http://99students.com/macro-sleep-vba/
その代わりに
Application.Wait (Now + TimeValue("0:01:00"))
サンプルコード
Sub Setting_Sleep_Without_Sleep_Function()
MsgBox Now
Application.Wait DateAdd("s", 10, Now)
MsgBox Now
End Sub
このアプローチを試してください:
With Selection.ListObject.QueryTable
.BackgroundQuery = False
.Refresh
End With
このように記述した場合、BackgroundQuery = FalseはBackgroundQueryプロパティをFalseに変更しないようです。
Selection.ListObject.QueryTable.Refresh BackgroundQuery = False ' doesn't work