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

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

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

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

Q&A

解決済

3回答

13766閲覧

ACCESS VBAでExcel出力

MotohiroSuzuki

総合スコア16

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

0グッド

1クリップ

投稿2018/01/22 09:37

編集2018/01/22 09:38

###前提・実現したいこと
Access VBAでExcel出力をしようとしています。
対象レコードが3万件ほどあり、出力にかなり時間が掛かってしまっています。
今はセル一つずつに書き込んでいるので、遅くなっていると思うのですが、
速度改善の方法として、レコードセットの内容をまとめて書き込む方法等ありましたら
ご教授頂けますでしょうか?

###該当のソースコード

ACCESS

1Dim sql As String 2Dim cn As ADODB.Connection 3Dim rs As ADODB.Recordset 4Dim tmpField As ADODB.Field 5Dim app As Excel.Application 6Dim book As Excel.Workbook 7Dim sheet As Excel.Worksheet 8Dim fName As String 9Dim data() As String 10Dim cnt As Integer 11Dim rows As Long 12Dim cols As Integer 13 14Set cn = CurrentProject.Connection 15fName = CurrentProject.Path & "\export\PV数(月別)_" & Format(Now, "yyyymmddHHMMSS") & ".xlsx" 16Set app = CreateObject("Excel.Application") 17app.Visible = False 18Set book = app.Workbooks.Add 19Set sheet = book.Worksheets(1) 20sheet.Name = "DATA" 21 22Set rs = New ADODB.Recordset 23rs.CursorLocation = adUseClient 24sql = "SELECT * FROM PV数" 25rs.Open sql, cn, adOpenDynamic, adLockOptimistic 26 27rows = 8 28Do Until rs.EOF 29 cols = 1 30 For Each tmpField In rs.fields 31 If rows = 8 Then 32 sheet.Cells(rows - 1, cols).Value = tmpField.Name 33 End If 34 sheet.Cells(rows, cols).Value = tmpField.Value 35 cols = cols + 1 36 Next 37 38 rows = rows + 1 39 rs.MoveNext 40Loop 41cn.Close 42Set cn = Nothing 43Set rs = Nothing 44 45book.SaveAs (fName) 46 47app.Quit 48Set book = Nothing 49Set app = Nothing

###試したこと
ループの部分を以下のように変更して、一行ずつ配列に入れてから書き込むようにしました。
速度改善の効果は出たのですが、出力したエクセルを開いてみると、全てのセルが文字列扱いになってしまい、
数値のセルも文字列として扱われてしまっています。
エクセル上である列をオートSUMしたりしたいのですが、文字列のためできなくなってしまいました。
書き込む際にこのセルは数値として指定したりできるのでしょうか?

Do Until rs.EOF
cols = 1

cnt = 0 ReDim data(cnt) If rows = 8 Then For Each tmpField In rs.fields ReDim Preserve data(cnt) data(cnt) = tmpField.Name cnt = cnt + 1 Next sheet.Range(sheet.Cells(rows - 1, 1), sheet.Cells(rows - 1, UBound(data) + 1)) = data End If cnt = 0 ReDim data(cnt) For Each tmpField In rs.fields ReDim Preserve data(cnt) If IsNull(tmpField.Value) Then data(cnt) = "" Else data(cnt) = tmpField.Value End If cnt = cnt + 1 Next sheet.Range(sheet.Cells(rows, 1), sheet.Cells(rows, UBound(data) + 1)) = data rows = rows + 1 rs.MoveNext

Loop

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

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

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

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

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

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

guest

回答3

0

解決済みですけど、処理方法によって速度は異なるようです。
さまざまなエクスポート方法の比較

投稿2018/01/22 14:57

sazi

総合スコア25173

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

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

0

ベストアンサー

Office TANAKA - Excel VBA高速化テクニック[無駄な表示を止める]
が最有力かなぁ。その他、高速化テクニックのまとめは
Office TANAKA - Excel VBA高速化テクニック[目次]
など。Withステートメントは地味に効いてくる。
あと、Excel.Applicationのインスタンス自体を非表示にするのもアリ。

Office TANAKA - Excel VBA高速化テクニック[型を指定する]
も重要。郵便番号の文字列を普通に書き出すと先頭の0が欠落したり、
電話番号の先頭の0が欠落したりするのを防げる。

Excelに計算式を埋め込んであるなら特に、
再計算を止めるのも有効。詳しくは:
遅い…重い…そんなエクセルVBAプログラムの処理速度を劇的に改善する方法

投稿2018/01/22 10:38

編集2018/01/22 10:43
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

MotohiroSuzuki

2018/01/22 12:18

ありがとうございます。 まだ試せてませんが、速度改善の参考サイト非常に参考になりました。 明日になってしまうと思いますが、実際に試してみて結果をご報告させて頂きます。
guest

0

CSV で出力して Excel で開けばいいと思います。

投稿2018/01/22 09:49

Zuishin

総合スコア28660

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問