Excel2010VBAのセルの入力が遅い

このQ&Aのポイント
  • Excel2010のVBAでセルの入力処理が遅い問題について解決方法を教えてください。
  • Excel2010のVBAでセルにデータを入力する処理が遅いです。特に以下のコード部分の処理時間がかかっています。どのように改善すればよいでしょうか?
  • Excel2010のVBAで大量のデータを処理してセルに入力する際、処理時間が非常に遅いです。特に以下のコード部分の処理が時間を要しています。解決策を教えてください。
回答を見る
  • ベストアンサー

Excel2010VBAのセルの入力が遅い

Excel2010のVBAなんですが、処理時間が非常に遅いです。プログラムの中でも遅い部分はセルに入力する部分です。多分24時間ぐらいプログラムを走らせておきましたがそれでも終わっていませんでした。 シートは6個あり、それぞれ関数の計算がされており、シート1からシート3までの計算されたものがシート4に出力され、そのシート4からプログラムで計算してシート5に出力されるコードです。 シート5に出力するデータは、「年」、「月」、「日にち」、「時刻」、「データ1」、「データ2」、「データ3」、「データ4」の8つの項目です。これは全ての行に入力するわけではなく、入力しなくてもいい空白の部分もあります。空白でもいいセルには入力の処理はしないようになっています。 処理時間が遅いというのは、データ量が非常に多いということもあるのですが最初に参照するデータは50万件以上(実際はこれよりはるかにあるのですが区切っています。)あります。 全てのコードはここには記載しませんが、特に遅いセルの入力の部分は、次の通りです。 For~ With Workbooks("ブック名.xlsm").Worksheets("シート5") .Cells(b, 1) = Year(日付) .Cells(b, 2) = Month(日付) .Cells(b, 3) = Day(日付) .Cells(b, 4) = TimeValue(日付) .Cells(b, 5) = Application.Round(データ1, 3) .Cells(b, 6) = Application.Round(データ2, 3) .Cells(b, 7) = Application.Round(データ3, 3) .Cells(b, 8) = Application.Round(データ4, 3) End With Next この部分の処理を早くするにはどうしたらいいでしょうか? 回答よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.1

とりあえず次のようにすると,早くなります application.screenupdating = false For~ With Workbooks("ブック名.xlsm").Worksheets("シート5") application.calculation = xlcalculationmanual .Cells(b, 1) = Year(日付) .Cells(b, 2) = Month(日付) .Cells(b, 3) = Day(日付) .Cells(b, 4) = TimeValue(日付) .Cells(b, 5) = Application.Round(データ1, 3) .Cells(b, 6) = Application.Round(データ2, 3) .Cells(b, 7) = Application.Round(データ3, 3) .Cells(b, 8) = Application.Round(データ4, 3) application.calculation = xlcalculationautomatic End With Next application.screenupdating = true もっと途中で再計算が必要な場合は,もちろんそこで再計算させます。

miya_HN
質問者

お礼

回答ありがとうございます。 「application.screenupdating」というのは画面描画(関数などの)で、「application.calculation」は、関数の自動更新機能のことなんですね。 試してみます。 ありがとうございました。

その他の回答 (3)

  • 374649
  • ベストアンサー率38% (203/527)
回答No.4

Excelをマクロで処理するプログラムを多用しています、処理の重さという問題に苦労しています。 同じマクロを実行すると Excel2003 > Excel2007 > Excel2010 という現実が有ります、昔は表計算は上から読み込まれるので上下に作るより横長にシート設計をするほうが処理が速いと教わりましたがメモリーもCPUの能力もアップしている現代では事情が違ってます。 しかし関数を多用すればそれだけ処理に時間が掛かりますし、マクロの書き方でも差が出てきます。マクロの一部分をみて速くしたいといってもそれだけではアドバイスは難しいと思います。 具体的には関数の数を減らす、処理を分散して処理速度を上げる(同じ処理はルーチン化するなど)など基本的にシートの設計から見直すことも処理速度を上げます。 >処理時間が遅いというのは、データ量が非常に多いということもあるのですが最初に参照するデータは50万件以上(実際はこれよりはるかにあるのですが区切っています。) これではExcelの処理の問題というよりアクセスなどのデータベース処理のソフトが向いているのでは。 PCに付いては何も書かれていませんがExcelは多コアに対応しているのでCPUの能力を上げるのも一手段です私も場合Excel2010では特に重たくなるのでExcel2007で走らせています、2コアより4コアの方が明らかに処理能力は優れてます。 回答にはなりませんが上記のようなことをやってます。

miya_HN
質問者

お礼

回答ありがとうございます。 データ量が多くて本当はExcelでは行数が足りないと思っていたのですがデータベース処理のソフトですか。ちょっとお金の方がなくて考えていないないのですが、確かにその方がそのような処理に向いていますね。 パソコン自体の性能も重要ですね。約1年前に購入したのですがその時は最新のものだったので性能の方は大丈夫だろうと思っていたのですが、思いのほかメモリを食っています。 関数の数を減らすというのは、これから考えてできるかどうかやってみることにします。 お金があればほとんど満足できるものが手に入れることができるんでしょうが今のExcelで何とか頑張ってみます。 ありがとうございました。

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.3

書き忘れました。 言わずもがなですが,マクロの「実行中」にシートのどこが再計算「されている必要があるか」に応じて,最大 application.screenupdating=false application.calculation = xlcalculationmanual for 行のループ cells(b, 1) =  : cells(b, 8) = next 行 application.calculation = xlcalculationautomatic application.screenupdating=true まで再計算を省略できます。 つまりご質問のマクロだと8×行数回イチイチ再計算が走っていたのを,いちばん最後に1回だけ再計算するとこまで手間を減らすワケですね。 先のマクロはご質問で掲示を省略したマクロの部分で,とりあえず1行分記入する都度一回,セルへの記入を受けてナニかしなきゃならない状況があるかもしれない?を想定しています。 #余談 折角マクロを使うのでしたら,いまシートに埋めている「ナニか不明の重たい関数式」をそもそももっと軽くて高速化できるようにもっと工夫し,「それを実現できるためのシートの処理」をマクロで実現するのも合理的な解決策です。 今回のご質問は「掲示されたマクロ部分に関する改善策」なので,ここではこれ以上は突っ込みませんが,必要に応じて具体的な状況を添えて別途ご相談を投稿してみてください。

miya_HN
質問者

お礼

2度も回答をいただき、ありがとうございます。 再計算しなければならないのは質問で記載したコードの最後のみです。今までセルの入力のたびに再計算の処理が行われていたということになります。 ということは、 application.calculation = xlcalculationautomatic application.screenupdating=true は、一番最後にくればいいということですね。 >先のマクロはご質問で掲示を省略したマクロの部分で,とりあえず1行分記入する都度一回,セルへの記入を受けてナニかしなきゃならない状況があるかもしれない?を想定しています。 これは質問に書いていなかったので説明不足でして、すいません。セルに入力するたびにプログラムで何かをしなければならないということではありません。 あくまで、入力し終わったら最後に再計算させればよいということです。 「余談」で書いていただきましたが、また何か分からないことがあればより具体的に質問させていただきます。 大変感謝しております。ありがとうございました。

  • mu2011
  • ベストアンサー率38% (1910/4994)
回答No.2

一例です。 セルの更新に処理時間が割かれるので一旦、内部配列経由としては如何でしょうか。 Dim wk(7) Application.ScreenUpdating = False For~ With Workbooks("ブック名.xlsm").Worksheets("シート5") wk(0) = Year(日付) wk(1) = Month(日付) wk(2) = Day(日付) wk(3) = TimeValue(日付) wk(4) = Application.Round(データ1, 3) wk(5) = Application.Round(データ2, 3) wk(6) = Application.Round(データ3, 3) wk(7) = Application.Round(データ4, 3) With Workbooks("ブック名.xlsm").Worksheets("シート5") .Cells(b, 1).Resize(1, 8) = wk End With Application.ScreenUpdating = True

miya_HN
質問者

お礼

回答ありがとうございます。 セルに入力するところで、「.Resize」というのを使うんですね。 試してみます。 ありがとうございました。

関連するQ&A

  • VBA 検索したセルに入力

    ExcelのVBAを使用して データの入力されたファイルに行列から検索したセルに数値を入力したいのです。 例えば、名前(行)と、日付(列) 2つの条件で、セルを検索し、該当するセルに、データ(数字とか)を 入力したいのです ------------------------------------  6/1 6/2 6/3 6/4 ・・・ a b c ・ ・ ------------------------------------ 例えば、A5に名前、B5に日付、データエリアがB10:Z20の場合 =INDEX(B10:Z20,MATCH(A5,A10:A20,0),MATCH(B5,B9:Z9,0)) で、該当するセルを探すことはできたのですが、 このセルに、データを入力したいときは、 ROWやCOLUMNで、行番号、列番号を取り出して Cellsで、入力すればいいのかな?と考えていますが もっと簡単にできるのでしょうか? (FIND関数は、使ったことがなく、どうなんだろう?と) それでいいよ とか、こっちの方が簡単 とかあれば、教えてください 

  • エクセル2000のVBAで、入力セルのデータを転記したい

    シート1の5行目あたり(例えばBの5)に入力用セルを置き、値を入れてボタンを押したら 11/6の部分にその値が表示されるようにしたい。 同じシート1の10行目に題名を入れている(下記ではABCD・・・の部分) 11行目からデータ内容を下に記載していく。 10    A      B     C       D 11 2007/11/1 $2000 月平均  半月平均 12 2007/11/2 $2300 月平均  半月平均 13 2007/11/3        月平均  半月平均 14 2007/11/4 $2350 月平均  半月平均 15 2007/11/5        月平均  半月平均 16 2007/11/6        月平均  半月平均 このデータは日付A列がもともと入っています。 毎日の為替相場をデータにしていきたいと考えてください。 土日祝日等は入力しませんので、入力しない日(休祝日だった場合)はそのまま空欄に していくと言う形です。11/5が休みだといって11/4の次のセルを11/6にすると言うのではありません。 1年365日あるのでデータとしては日付部分に365行分先に入力されている形です。 Bだけが空欄で、CとDはアベレージ計算式が入っています。 下のマクロを組みましたが、これだと17行目の指定した列から入力されてしまいます。 どのようにしたらいいのか教えていただけますか? 入力セルに日付も必要ですか? Sub ボタン1_Click() Application.ScreenUpdating = False Sheets("シート1").Select Range("B5").Select Selection.Copy Sheets("シート1").Select Range("A65536").Select Selection.End(xlUp).Select Selection.Offset(1, 0).Select Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=True Application.CutCopyMode = Flase Sheets("シート1").Select Range("C10").Select Selection.ClearContents Range("B5").Select End Sub

  • VBAの処理が遅くて困っています!

    VBAの処理が遅くて困っています! Excel VBAで1つのExcelファイルに3つのシートがあります。 1つ目のシートにデータが入力されています。 2つ目のシートには条件を入力できるようになっています。  例えば車速と記入してあるセルには手入力で30と入力できるようになっています。 3つ目のシートは、1つ目のデータから2つ目の入力値と比較して その条件にあう結果を3つ目のシートに計算結果として反映しています。 それが下記の処理です。 但し、処理が遅すぎて困っています。 下記式が20個ありB列の結果を元にまた次の計算をさせています。 誰か、教えて頂けませんでしょうか? よろしく御願い致します。 Set J1Sheet = Worksheets("条件設定1") Set K1Sheet = Worksheets("計算1") Set DataSheet = Worksheets("データ")  2つ目のシートの入力値を格納しています  TMPCAT = J1Sheet.Cells(11, 4) VSP下限 = J1Sheet.Cells(9, 4) 水温下限 = J1Sheet.Cells(13, 4) ST1_下限Ne = J1Sheet.Cells(17, 4) ST1_上限Ne = J1Sheet.Cells(15, 4) ST1_下限TP = J1Sheet.Cells(21, 4) ST1_上限TP = J1Sheet.Cells(19, 4) ST1_上限QM = J1Sheet.Cells(23, 4) ST1_許可ディレイ = J1Sheet.Cells(35, 4) ST1_診断周期 = J1Sheet.Cells(37, 4) ST1_診断回数 = J1Sheet.Cells(39, 4)   今回はデータ数が14000行ありました  RowEnd = K1Sheet.Range("A65535").End(xlUp).Row Application.ScreenUpdating = False Application.Calculation = xlCalculationManual  Dim i As Long   For i = 3 To RowEnd 'B列の計算:2 strAns = "●" If K1Sheet.Cells(i - 1, 2) <> "●" Then If DataSheet.Cells(i + 1, 10) < TMPCAT Then strAns = "" End If End If K1Sheet.Cells(i, 2) = strAns Next i

  • VBAに詳しい方に質問です。

    VBAに詳しい方に質問です。 私はVBA初心者です、お力添えのほどよろしくお願いいたします。 エクセルで入力し、それを一覧表に転記し、最終的に出力フォームにデータを呼び出し印刷するプログラムを作成しています。 1つの項目のデータを表に転記したり、呼び出すVBAはなんとか作成できました。 しかし、複数のセルのデータを表に転記するVBAが作ることができません。 ☆シート1 入力フォームがあり、 氏名・電話番号・住所等の項目を100人ほど表で入力します。 それらをシート2へ転記します。    1     2      3    4…   1  日付    名前    年齢   電話番号 2 2010/07/01 石川花子   12才  090-×× 3 4  ↓以下100名ほど入力 5  ※列も行も数値で表すように設定してあります。 ・ ・ ・ ☆シート2 これまでに入力したデータをすべて一覧表にします。 シート1のデータはこれまでに入力されたデータの下に転記されます。    1     2     3   4… 1 日付    名前    年齢  電話番号 902010/06/28 山田太郎  33才 090-×× 912010/07/01 石川花子   12才  090-××   92  ↑このように日付欄に空白を見つけ、そこからデータを転記する。 93 ・ ・ ・ 私が考えたVBAは、 sub 転記マクロ() set 入力 = worksheet("シート1") set 一覧 = worksheet("シート2") 日付1=入力.cells(2,1) 名前1=入力.cells(2,2) 年齢1=入力.cells(2,3) 電話1=入力.cells(2,4) 日付2=入力.cells(3,1) 名前2=入力.cells(3,2) 年齢2=入力.cells(3,3) 電話2=入力.cells(3,4) '以下○○100まで ※一覧.(縦,2)に縦+1をしていき""の場所を探す。 (すみません、データを会社に置いてきたので表記の仕方を忘れてしまいました^^;) 一覧.(縦,1)=日付1 一覧.(縦,2)=名前1 一覧.(縦,3)=年齢1 一覧.(縦,4)=電話1 一覧.(縦+1,1)=日付2 一覧.(縦+1,2)=名前2 一覧.(縦+1,3)=年齢2 一覧.(縦+1,4)=電話2 '以下+100まで end sub 何も見ずに思い出しながら書いたので、もしかしたらどこか間違っているかもしれませんが、 このような感じで書いていきました。 さすがにこのようなことを100回繰り返すのは大変なので、for next関数でなんとかならないか試行錯誤したのですがなかなか解明できず困っています。 詳しい方、どうか教えてください。

  • EXCEL-VBA の round関数

    EXCEL-VBAで Cells(1, 1) = Round(Cells(3, 3), 0) として、 C3 に28.5 を入力し、上のマクロを実行すると、 A1には、28と表示されてしまいます。 ワークシート関数の =round(c3,0) を他の適当なセルに入力すると、 その返り値は、29 とちゃんとなります。 c3が 28.5001 とかだと両者ちゃんと 29 となります。 これは、VBA関数のバグなりスペックなのでしょうか?

  • Excel2002でセルへの数値代入

    使用しているのはExcel2002なんですが 関数などを使用して空白セルへ数値及び文字列を 代入することって可能でしょうか? 例を挙げると、 セルA1に7という値を入力すると、 セルC1にある関数が「10-A1」という計算を行って セルB1に3という値を返すようにしたいのです。 また、セルB1に4という値を入力すると、 セルC1で計算を行い、セルA1には6が返る。 このようにセルA1、B1ともに、人の手で数値の 入力が行われる可能性があるので、表示部分のセルに 関数式を記述せず、空白としておく。 C1に入力する関数は IF(B1="",10-A1,10-B1) として、この結果を、またIFなどを使って 空白の方のセルに入力してあげればいいかなー というところまでは考え付いたのですが・・・ どなたか教えてください。

  • VBA セルに入力されている数値でセルを指定する

    Excel VBA初心者です。 Sheet1のA1セルに10、A2セルに3を入力しています。 この入力したセルの数値を参照して、 Sheet2の「Cells(10,3)」(C10セル)を青(Interior.ColorIndex = 5)に 書式変更したいのですが、「Cells(”Sheet1.A1の値”,”Sheet1.A2の値”)」の 書き方がわかりません。 Excel2010を使用しています。 よろしくお願いします。

  • VBAを使ってセルを検索後別シートのデータを自動入力したいです。

    見ていただきありがとうございます。 エクセルの2000VBAを使って次のようなことを考えています。 シート2に以下のようなデータがあります。 2006/7/20 コード 数量  100  200   200  400 データの数は日によって違います。 シート1には以下の表があります。横軸にはコード縦軸には日付が入っており各対応するセルに数量が入っています。       100  200  300  400 ....←コード 2006/7/1  20  40  100  800 2006/7/2  50  60  200  500   .   .   . 2007/6/30  このような場合、シート2にコマンドボタンを設けて押したときシート2の日付とコード番号によりシート1の表の検索を行って対応するセルにシート2のデータを転記したいのです。シート2のデータは本日分のデータが入った時点でシート1への転記を行います。(1日一回です) また、シート1の表は2007/6/30(これ以降は必要ないので)までの日付がすでに入力されており明日以降のデータの入るセルは空白になっております。 よろしくお願いします。

  • EXCEL2007 VBA アクティブでないワークシートの名前を取得したい

    Sheet1とSheet2の【A1セル】【B1セル】には以下の処理が入っています。また2つのシートにはVBAを使って、再計算がされるたびに自身のシート名を表示するメッセージボックスを出力する処理を記述しています。 【A1セル】  リアルタイムで値が送られてくる。 【B1セル】  A1セルの値を使った式 【VBA】  Private Sub Worksheet_Calculate()   MsgBox **************  End Sub ここからが質問なんですが、Sheet3をアクティブシートにしている場合、VBAの「*****」の部分に何と記述すれば、再計算されたシート名を取得できますか?

  • VBA スペースが入力されていても、空白セルと判断する方法

    VBAで、空白ではないときに処理するようなマクロを組みたいのですが、空白のはずのセルにスペースが入っている場合があり、 IF cells(i,j)<>empty then のような記述では、スペースが入力されているセルも該当してしまいます。 スペースのみのセルを消去するか、それか、数値か文字列の何かが入力されていることを判断するような方法はありますか? よろしくお願いします。

専門家に質問してみよう