Webクエリのダウンロード時間がかかるようになった

Webクエリを使い続けていると、3秒程度だったダウンロード時間が1分以上になることがあります。あちこちのサイトを検索してもはっきりした原因はどこにも書いてありませんが、やっと原因を特定できたので情報公開することにします。おそらくこれがファイナルアンサーです。どこのブログにも書いてないので、これが初公開のはず!

 

500個以上の名前がいつのまにか・・・!?

イミディエイトウィンドウ(CTRL+G)でたまたま ?Thisworkbook.Names.Countとやってみたところ500個以上の数字が表示されました。2個くらいなら名前を定義したけど、500個も定義した覚えがなかったので、?Thisworkbook.Names(1)で中身を表示させてみたら、”=Sheet3!$A$1:$A$136” のような名前が山ほど定義されていました。

明らかに犯人はWebクエリでした。とりあえず、こんなコードを書いて名前を全部消してみたら、あれだけ遅かったWebクエリがなんと3秒でダウンロード完了できるようになったんです。あとは、Webクエリを実行したあとでClearNamesをコールすればいいだけです。

 

Public Sub ClearNames()

    Dim oName As Name
    For Each oName In ThisWorkbook.Names
        if oName.Name Like "*deleteme*" Then oName.Delete
        DoEvents    ' <== 500個以上だとエクセルが応答しない状態になります
    Next oName
End Sub

 

 

なぜ名前が残ってしまうのか?

Webクエリのパフォーマンス遅延問題が解決したので、増えていく名前問題は忘れることにしました。ただ、今回ブログの記事を書こうと思ってサンプルのVBAを作っていた時に、この消えない名前の原因も分かりました。

 

おそらく、ほとんどの人はこんなコードを書いていると思います。QueryTable.Deleteで前回のクエリ結果を消して、ClearContentsでシートをきれいにしてから、Webクエリを実行。

On Error Resume Next
wksTmpSheet.Cells.QueryTable.Delete
wksTmpSheet.Cells.ClearContents

 

With wksTmpSheet.QueryTables.Add(Connection:="URL;" _ & sURL, Destination:=wksTmpSheet.Range("$A$10"))
  .Name = "deleteme"
  .FieldNames = True
  .RowNumbers = False
  ....
  ....
  .Refresh BackgroundQuery:= False

End With

 

シートの名前からも分かるとおり、Webクエリ専用のシート(wksTmpSheet)を作っています。そして、それは非表示にしています。当然ですよね。作業用のシートですから。

ここで面白いことが起こります。QueryTable.Deleteを実行すると前回のWebクエリで追加された名前が削除されます。つまりThisworkbook.Names.Countがゼロになります。え? だったら名前が消えない問題はどういうこと?? ということになります。

察しのいい人はもう分かりましたよね。はい、そうです。非表示のワークシートが問題だったんです。

QueryTable.Deleteは、ワークシートが非表示だと名前を削除してくれません。そのためWebクエリを実行すればするほど名前がどんどん増えていったわけです。

ちなみに、.Name = "" にしても名前は残ります。

 

結論

Webクエリ専用のシートは非表示にしてもよいが、実行後に前述のClearNames相当のコードを実行すること。