質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
ActiveX

ActiveXは、Microsoft社が開発したプログラミング技術群の総称。特定の技術ではなく、さまざまな技術を指しますが、一般的にActiveXといった場合は「ActiveXコントロール」を指します。

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

1回答

1827閲覧

Recordsetをエクセルに貼り付ける処理を高速化したい(VBA)

shiki_968

総合スコア24

ActiveX

ActiveXは、Microsoft社が開発したプログラミング技術群の総称。特定の技術ではなく、さまざまな技術を指しますが、一般的にActiveXといった場合は「ActiveXコントロール」を指します。

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

1グッド

0クリップ

投稿2023/08/09 05:56

実現したいこと

VBAを使用し、DBからデータを取得して、エクセルに貼り付けたいです。
RecordSetからエクセルに貼り付ける処理に時間がかかりすぎて困っています。

どのようにしたら高速化できますか。

前提

DB : SQLserver
データ数:15列3000行程度
今の処理時間:90秒
目標の処理時間:10秒

SQL文の処理時間は問題ないです。
再計算や描画はオフにしてます。

試したこと

VBA

1Dim SQL As String 2Dim rst As Recordset 3 4Set rst = DB.getRecordSet(SQL) 5Call Range("A1").CopyFromRecordset(rst) 6 7Public Function getRecordSet( _ 8 OpenSQL As String, _ 9 Optional CursorType As ADODB.CursorTypeEnum = ADODB.CursorTypeEnum.adOpenKeyset, _ 10 Optional LockType As ADODB.LockTypeEnum = ADODB.LockTypeEnum.adLockReadOnly _ 11 ) As ADODB.Recordset 12 Set getRecordSet = New ADODB.Recordset 13 getRecordSet.Open OpenSQL, conn, CursorType, LockType 14End Function
Huginn👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hatena19

2023/08/09 07:16

「RecordSetからエクセルに貼り付ける処理に時間がかかりすぎ」 「SQL文の処理時間は問題ないです。」という根拠は? 15列3000行程度でCopyFromRecordsetにそんなに時間がかかるとは思えないです。 Set rst = DB.getRecordSet(SQL) と Call Range("A1").CopyFromRecordset(rst) のそれぞれの処理時間は計測しましたか。 計測方法は下記を参考に。 https://www.limecode.jp/entry/speed/timer-measure-processtime
shiki_968

2023/08/10 00:42

回答ありがとうございます。計測すると Set rst = DB.getRecordSet(SQL)       0.5秒 Call Range("A1").CopyFromRecordset(rst)   72秒 という結果になりました。
hatena19

2023/08/10 04:13 編集

データのシートへの貼り付け自体はそれほど時間がかかるとは考えにくいです。 RecordSet.Open だけでは、まだレコードセットにデータを読み込んでいません。 CopyFromRecordset するときにレコードセットにデータを読み込んで、貼り付けている推測されます。 そのレコードセットにデータを読み込むのに時間がかかっているのかな、という気がします SQLではなく、15列3000行程度のテーブルを作成してそれを読み込んで貼り付けた場合の時間も計測してみてください。
shiki_968

2023/08/10 03:10

計測しました。 RecordSet → テーブル 0.1秒 テーブル → RecordSet 0.6秒 ご指摘どおり、データの貼り付け自体は時間はかかりません。
hatena19

2023/08/10 03:43

SQL、テーブルの設計に原因があるということになりますね。 その設計を見直しましょう。 
shiki_968

2023/08/10 05:34

SQL自体はDB管理ツールで問題ないことを確認しています。 他を調べた結果、adOpenKeysetが原因でした。 adOpenKeysetを使うと、キーがレコード内を移動するために処理が遅くなることがわかりました。 今回はテーブルをそのまま貼り付けるだけなので、adOpenKeysetは不要なため不使用にしたところ、高速化が実現できました。 ご相談にのっていただきありがとうございました。
guest

回答1

0

自己解決

adOpenKeysetを使うと、レコード内を移動できるようになるが、VBAでエクセルに貼り付けると時間がかかる。
adOpenForwardOnlyを使うと高速に貼り付けが可能になる。
↓参考サイト
http://www7b.biglobe.ne.jp/~cbcnet/ADO/recordset.html

投稿2023/08/10 05:47

shiki_968

総合スコア24

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hatena19

2023/08/10 06:45

どのくらい改善できたのでしょうか。 90秒から目標の10秒以内に短縮できたということでしょうか。 adOpenForwardOnlyが高速なのはわかりますが、それほど違いがあるとは。
shiki_968

2023/08/10 08:45

全体としては4秒、問題にしていたrecordsetの処理は1秒になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問