• ベストアンサー

”ブック間の3D集計の式をExcelVBAでセルに入力”で実行時間が遅くて困っています

枝番号の一番大きいファイルパス("C:\Documents and Settings\集計ファイル_3.xls")を引数で受け取り、 数式セルを対象にフォントカラー番号よって、 シート内参照の数式、もしくはブック間の3D集計をセルに入力する モジュールを作成しています。 現在実行に1時間以上かかってしまい困っているのですが、 なんとか改善する方法をご存知ないでしょうか? アイデアだけでもかまいませんので、是非何かご教授よろしくお願いいたします。 '引渡値 oTargetSheet :処理対象のシート '引渡値 s3DFormura :集計したい枝番最大ブックのパス Dim oFomulaRange As Range Dim oFomulaCell As Range Dim sFormura As String Dim sCurrentFile As String Dim iMaxFileNo As Integer Dim iFileNameStart As Integer Dim i As Integer '数式セルのみ選択します Set oFomulaRange = oTargetSheet.Cells.SpecialCells(xlCellTypeFormulas, 23) '引数より枝番号を取得 例)3 iMaxFileNo = CInt(Mid(s3DFormura, Len(s3DFormura) - 4, 1)) 'ブックが1つしかない場合は何もせずExit If iMaxFileNo = 1 Then Exit Sub 'ブック間集計の場合のブックパス途中までをセット '例)"C:\Documents and Settings\[集計ファイル_" iFileNameStart = InStrRev(s3DFormura, "\") sCurrentFile = sCurrentFile & "'" & Left(s3DFormura, iFileNameStart) & "[" sCurrentFile = sCurrentFile & Mid(s3DFormura, iFileNameStart + 1, Len(s3DFormura) - iFileNameStart - 5) For Each oFomulaCell In oFomulaRange With oFomulaCell Select Case .Font.ColorIndex Case 10 '数式の生成 sFormura = "=SUM(" For i = 1 To iMaxFileNo If i > 1 Then sFormura = sFormura & "," sFormura = sFormura & sCurrentFile & i & ".xls]計'!" sFormura = sFormura & .Address(ReferenceStyle:=xlR1C1) Next i sFormura = sFormura & ")" 'セルに数式を入力 '例)=SUM('C:\Documents and Settings\[集計ファイル_1.xls]計'!!$A$1 ' ,'C:\Documents and Settings\[集計ファイル_2.xls]計'!!$A$1 ' ,'C:\Documents and Settings\[集計ファイル_3.xls]計'!!$A$1) .Formula = sFormura Case 14 '文字色を緑に変更 .Font.ColorIndex = 10 '10と同じ処理 sFormura = "=SUM(" For i = 1 To iMaxFileNo If i > 1 Then sFormura = sFormura & "," sFormura = sFormura & sCurrentFile & i & ".xls]計'!" sFormura = sFormura & .Address(ReferenceStyle:=xlR1C1) Next i sFormura = sFormura & ")" .Formula = sFormura Case 43 '文字色を青に変更 .Font.ColorIndex = 5 '=IF(数量<>0,ROUNDUP(金額/数量,0),0) .FormulaR1C1 = "=IF(RC[1]<>0,ROUNDUP(RC[2]/RC[1],0),0)" End Select End With Next

noname#32244
noname#32244

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

  • ベストアンサー
  • pkh4989
  • ベストアンサー率62% (162/260)
回答No.2

こんにちは。 件数(回数)が少ないExcelのセル参照及び書き込みの時は、普段遅いとは感じません。 その参照及び書き込み件数(回数)が多くなると、非常に遅くなります。 特にセルに色を設定する処理が遅いですね。 以下の処理を試してみてください。 セル「A1~J10000」へ単純に数字を書き込み処理です。 test1は、セルにそのまま書き込み、test2は配列を利用して書き込みした処理です。 Sub test1()   Dim wR   As Long   '   Application.ScreenUpdating = False   With ActiveSheet     For wR = 1 To 10000       For wC = 1 To 10         .Cells(wR, wC) = wR * wC       Next     Next   End With   Application.ScreenUpdating = True   MsgBox "終了" End Sub Sub test2()   Dim wR   As Long   Dim tBuf  As Variant   '   tBuf = ActiveSheet.Range("A1:J10000")   For wR = 1 To 10000     For wC = 1 To 10       tBuf(wR, wC) = wR * wC     Next   Next   ActiveSheet.Range("A1:J10000") = tBuf   MsgBox "終了" End Sub test1とtest2の処理速度の差が全然違うのが分かります。 ようするに、Excelのセルをそのまま参照及び、書き込みするのではなく、配列及び変数などを利用すれば、 早く処理が出来ると思います。 但し、セルに色を設定するのは、配列又は変数には出来ません。 気が付いたところがあれば、 With oFomulaCell Select Case .Font.ColorIndex Case 10 '数式の生成 sFormura = "=SUM(" For i = 1 To iMaxFileNo If i > 1 Then sFormura = sFormura & "," sFormura = sFormura & sCurrentFile & i & ".xls]計'!" sFormura = sFormura & .Address(ReferenceStyle:=xlR1C1) '← ここですね Next i 変数を使えば、毎回セルを参照しなくても良いと思います。 Dim wAdr as String With oFomulaCell   wAdr = .Address(ReferenceStyle:=xlR1C1) '←変数に代入   Select Case .Font.ColorIndex   Case 10     '数式の生成     sFormura = "=SUM("     For i = 1 To iMaxFileNo       If i > 1 Then         sFormura = sFormura & ","         sFormura = sFormura & sCurrentFile & i & ".xls]計'!"         sFormura = sFormura & wAdr '←変数値を代入       End If     Next i セルの参照及び書き込みの件数(回数)が多いと思いますので、なるべく、変数又は配列を利用するように 変えてみてください。

noname#32244
質問者

お礼

本当です。 test2のほうが全然速いです! 10000レコードごときで体感できるほど違うもんなんですね! ActiveSheet.Range("A1:J10000") = tBuf で書き込む際にtest1と同じことなのかと思い、 かえって配列の1手間が無駄そうに思ったのですが、 全然理解が浅いってことなんですね! まだちょっと不思議な感じはしてしまうのですが。。。 ありがとうございます。 大変勉強になります。 左寄せになってしまった読みにくいコードを読んでいただいて 貴重なお時間を本当にありがとうございます。 今日は、上記を踏まえコードを修正してみたいと思います。 pkh4989さん、わかりやすい丁寧なご指導ありがとうございました。

その他の回答 (1)

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.1

こんにちは。 あまりコードの内容はみてませんが、一般論で言えば、 ■ 画面描写を停止する   Application.ScreenUpdating = False   ~処理~   Application.ScreenUpdating = True ■ 数式の再計算を停止する   ループの先頭で再計算を Manual にして再計算発生に   よる実行速度の低下を防ぐもの。      コードの実行完了時、エラー発生時に Automatic に   戻す処理を忘れないで下さい。   Application.Calculation = xlCalculationManual   ~処理~   Application.Calculation = xlCalculationAutomatic   注意)   ループ処理の中でセルの値が変化し、その値を使った   数式の計算結果を参照しながら条件分岐させるような   場合は、適所で再計算を実行する必要があり。 Excel VBA は、この2点だけでもパフォーマンスの向上が 非常に期待できます。  

noname#32244
質問者

お礼

早速のご回答ありがとうございます。 ご指摘の方法(画面描写停止、数式再計算停止)は、 メインルーチンのほうで制御しておりまして、 書き込みさせていただいたのはサブルーチンになっております。 このサブルーチンのロジックそのものがあまりスマートではなく 遅いのではなかろうかと思って、ご質問させていただいた次第です。

関連するQ&A

  • VBAでブックの集計の仕方を教えてください。

    H22.12月度と言う名前のフォルダーにA店~E店と集計と言う名前のブックがあります。 集計のブックでA店~E店の集計をしてくるマクロを組んでいますが上手く作動しません。 集計のブックには、セルの書式設定をしていますので、A店~E店の売上一覧のシートから 値だけをコピーして集計したいのですが、罫線やパターン、数式までコピーしてきたり、 最後のE店だけ2重にコピーしてきたりと変な動作をします。 初心者で本やネットで調べながら作ったので、どこの記述がおかしくて、そうなるのかがさっぱりわかりません。 どなたか教えていただけませんでしょうか。よろしくお願いします。 Sub 集計() Workbooks.Open Filename:="C:\Documents and Settings\デスクトップ\H22.12月度\A店.xls" Sheets("売上一覧").Select Range("E5:Q24").Select Selection.Copy Application.WindowState = xlMinimized Windows("集計.xls").Activate Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False If Range("E5").Value <> "" Then Range("E65536").Select Selection.End(xlUp).Select Selection.Offset(1, 0).Select End If ActiveSheet.Paste Windows("A店.xls").Activate Range("E5").Select Application.CutCopyMode = False ActiveWindow.Close     ・     ・     ・(B・C・D店も同じ記述)     ・     ・   Workbooks.Open Filename:="C:\Documents and Settings\デスクトップ\H22.12月度\E店.xls" Sheets("売上一覧").Select Range("E5:Q24").Select Selection.Copy Application.WindowState = xlMinimized Windows("集計.xls").Activate Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False If Range("E5").Value <> "" Then Range("E65536").Select Selection.End(xlUp).Select Selection.Offset(1, 0).Select End If ActiveSheet.Paste Windows("E店.xls").Activate Range("E5").Select Application.CutCopyMode = False ActiveWindow.Close    Windows("集計.xls").Activate Application.WindowState = xlMaximized Range("E5").Select End Sub

  • ブックの集計方法について

    複数ファイルにある特定のシートのA列に記載がある時だけ、その行のA列からJ列までを、一つのファイルにコピーしたいと思っています。 ネットで調べてみたところ、エクセルで複数ファイルにある特定のシートの 特定した範囲を一つのファイルにコピーするマクロを探すことができました。 複数のシートから特定のシートのA列に文字がある場合は、J列までを一つのファイルの同じシートにコピーするようなことは出来ないでしょうか? (例えば、各ブックA列に10行ずつ文字がある場合は、このようなとりまとめをできないかと考えています。) ブック1(シート名:Q2)⇒集計シートのA1:J10 ブック2(シート名:Q2)⇒集計シートのA11:J20 ブック3(シート名:Q2)⇒集計シートのA21:J30 Sub ブック集合() Dim FileName As String Dim c As Integer Dim OpenedBook As Workbook Dim IsBookOpen As Boolean ChDir "c:/test" FileName = Dir("*.xls") Application.ScreenUpdating = False Application.DisplayAlerts = False c = 0 Do While FileName <> "" If FileName <> ThisWorkbook.Name Then IsBookOpen = False For Each OpenedBook In Workbooks If OpenedBook.Name = FileName Then IsBookOpen = True Exit For End If Next If IsBookOpen = False Then Workbooks.Open (FileName) End If Workbooks(FileName).Sheets("Q2").Range("A1:J500 ").Copy _ ThisWorkbook.Sheets(3).Cells(c * 500 + 1, 1).PasteSpecial(xlPasteValues) c = c + 1 If IsBookOpen = False Then Workbooks(FileName).Close End If End If FileName = Dir() Loop Application.DisplayAlerts = True Application.ScreenUpdating = True End Sub

  • ExcelVBA ブック全データを別ブックにコピー

    お世話になります。 自分のPC環境のC:\test\配下にある"練習.xls"というブックがります。 ボタンが押された時にこのブックの全データをデスクトップにある"集計.xls"のA1から張り付けたいのです。 あるサイトで下記のようなロジックが公開されていましたので、ファイル名を変えて実行しましたが 下記★箇所で"インデックスが有効範囲にありません"とエラーが出てしまいます。 どなたか改善方法をご教授いただけませんでしょうか? よろしくお願い致します。 環境 windows XPSP3  Excel2003 Sub ボタン1_Click() Dim a As Variant Dim b As Variant Workbooks.Open Filename:="C:\test\練習.xls" ★Set a = Workbooks("\C:\test\練習.xls").Worksheets("sheet1").UsedRange Set b = Workbooks("集計.xls").Worksheets("sheet1").Range("A1") a.Copy (b) Set a = Nothing Set b = Nothing End Sub

  • マクロFormulaで入力する式に変数を使うと定義のエラーと出る

    価格表を元に、型番から価格を検索するマクロを作りたいのですが、 i = kakakuretu - katabanretu Selection.FormulaR1C1 = "=IF(ISNA(VLOOKUP(RC[i],'C:\Documents and Settings\@\My Documents\東京購入分\[東京購入分.xls]sheet1'!C2:C5,4,FALSE)),"""",VLOOKUP(RC[i],'C:\Documents and Settings\@\My Documents\東京購入分\[東京購入分.xls]sheet1'!C2:C5,4,FALSE))" とすると、iが定義エラーになってしまいます。 初心者でネットを見ながら記録マクロをいじるくらいしか出来ないので 定義などよくわかりません。教えて下さい。

  • ExcelVBAで、選択範囲内で同じ値が入力されたセルを調べる

    選択範囲内(縦一列)で同じ値が入力されたセルの色を黄色にするプログラムを作りました。 Sub 選択範囲内で同じ値が入力されたセルを調べる_縦() Dim startrow As Byte Dim lasrow As Byte Dim i As Long Dim j As Byte Dim atai If TypeName(Selection) <> "Range" Then Exit Sub startrow = ActiveCell.Row '最初のセルの列番号を取得 lasrow = Selection.Rows(Selection.Rows.Count).Row '最終列番号を取得 '同じ値が入力されているセルを黄色にする For i = startrow To lasrow - 1 If ActiveSheet.Cells(i, ActiveCell.Column).Interior.ColorIndex = xlNone Then atai = ActiveSheet.Cells(i, ActiveCell.Column).Value For j = i + 1 To lasrow If atai = ActiveSheet.Cells(j, ActiveCell.Column).Value Then ActiveSheet.Cells(i, ActiveCell.Column).Interior.ColorIndex = 6 ActiveSheet.Cells(j, ActiveCell.Column).Interior.ColorIndex = 6 End If Next End If Next End Sub 但し、上記のプログラムでは選択範囲内に結合セルがあるとエラーになってしまいます。 どなたか、解決方法をご教授頂けませんでしょうか? 宜しくお願い致しますm(._.)m

  • VBA フォルダ内にあるブックをすべて開く

    いつもお世話になります。 デスクトップ上にフォルダ「新しいフォルダ」があり、その中に6つエクセルブックがあります。 Book1.xls Book2.xls Book3.xls Book4.xls Book5.xls と test.xls です。 test.xlsに、Book1~Book5を開く というマクロを作り実行したところ、実行時エラー1004 『Book1.xlsがみつかりません』と表示されます。 Sub test() Dim buf As String, i As Long buf = Dir("C:\Documents and Settings\tsasaki\デスクトップ\新しいフォルダ\*.xls") Do While buf <> "" i = i + 1 Workbooks.Open Filename:=buf 'Cells(i, 1) = buf buf = Dir() Loop End Sub どのが間違っているか教えてもらえますか。

  • VBAマクロ、パスがありませんでとまります。

    Excel2003 VBAのコードを作成して、 実行しましたら ”実行時エラー'76' パスが見つかりません。" と表示されて Open pase ...... の行でとまってしまいます。 なにが原因とかんがえられますか? すいませんが、ご回答よろしくおねがいいたしますm(_ _)m Sub Macro1() Dim strarray() As Variant Dim counter As Integer Dim i As Long pase="C:\Documents and Settings\user\My Documents\" myname=Dir("C:\Documents and Settings\user\My Documents\",vbNormal) Do While myname <> "" If (GetAttr("C:\Documents and Settings\user\My Documents\" &_ myname) And vbNormal) = vbNormal Then ReDim Preserve strarry(counter+1) strarray(counter) = myname counter = counter + 1 End If myname = Dir Loop For i = 1 to counter Open pase & strarray(i) For Input As #1 Do Until EOF(1) ・ '処理 ・ ・ Loop Next i

  • リンクのVBAを教えてください。

    いつも、御指導ありがとうございます。 売掛金元帳のセル(J3)に数式1で、[得意先登録.xls]得意先登録から社名を表示させています。 ●数式1  '=IF($C$2="","",IF(ISERROR(VLOOKUP($C$2,'C:\Documents and Settings\aaa\My Documents\販売管理 \登録 (台帳)\[得意先登録.xls]得意先登録'!$D$7:$E$65536,2,FALSE)),"未登録です", VLOOKUP($C$2,'C:\Documents and Settings\aaa\My Documents\販売管理 \登録 (台帳)\[得意先登録.xls]得意先登録'!$D$7:$E$65536,2,FALSE))) 売掛金元帳のセル(E2)に数式2で、[自社情報登録.xls]自社情報'!$C$3から自社名を表示させています。 ●数式2  '='C:\Documents and Settings\aaa\My Documents\販売管理\登録 (台帳)\[自社情報登録.xls]自社情報'!$C$3 ●数式1及び数式2をVBAで記述したいのですがど、うしても記述出来ません。 ●まるなげになってしまいますが、数式1及び数式2と、社名変更があった場合は売掛金元帳へ反映させるVBAを教えてください。 宜しく御願いいたします。

  • 各ブックの集計値を自動的に他のブックに総合計として表示させたい。

    エクセルで各ブックの集計値を他のブックに集計したいのですが、フォルダを移動させると数値が違ってしまう。どうすればいつ見ても正しい集計値を見れるか教えて下さい。 現在1つのファイルの中にある、ブック1・2・3にそれぞれ数値を入力して合計値をブック3の別シートに合計表示させていますが、同じブックのシート間の集計ではないため、毎回数値が変わってしまい、その都度計算式を(=ブック1 D60+ブック2 d80+・・・など)を入れなおしています。 間違いなく集計できる方法を教えて下さい。ちなみに全くの初心者なので細かく説明していただけると有難いです。 VBAで検索して下記を見つけ、セル範囲やシート名など変更して試してみましたが、内容がよくわからないため 変な数字がでてきました。初心者にはやはり無理でしょうか? Sub Test() Dim MyName As String, wb As Workbook On Error Resume Next MyName = Dir(ThisWorkbook.Path & "\*.xls", vbNormal) Do While MyName <> ""   If UCase(MyName) <> UCase(ThisWorkbook.Name) Then    Application.ScreenUpdating = False    Set wb = Workbooks.Open(ThisWorkbook.Path & "\" & MyName)    ThisWorkbook.Worksheets("Sheet1").Range("A65536").End(xlUp) _      .Offset(1, 0).Value = wb.Worksheets("物件").Range("d90:k90").Value    wb.Close   End If   MyName = Dir Loop Application.ScreenUpdating = True End Sub

  • ワイルドカードの記述が、原因でしょうか?

    下記コードが、ついこの前までは、きちんと "A?07??????.CSV" を読み込んでたんですが、 今は、 "検索条件を満たすファイルはありません。"  となってしまいます。 1、ワイルドカードの記述が、おかしいでしょうか? 2、フォルダ名は、漢字等はやめて、半角英数字にしたほうがよいのでしょうか? 3、このような、現象は、よくあることでしょうか? 以上 原因がわかりませんので、何卒ご教示くださいませ。 ----------------- Private Sub TEST() Dim myFS As FileSearch Dim i As Long ChDir "C:\Documents and Settings\Owner\デスクトップ\ああ" Set myFS = Application.FileSearch With myFS .LookIn = "C:\Documents and Settings\Owner\デスクトップ\ああ" .Filename = "A?07??????.CSV" If .Execute > 0 Then For i = 1 To .FoundFiles.Count '見つかったファイルを一つずつ開く Workbooks.OpenText Filename:=.FoundFiles(i), _ StartRow:=1, _ DataType:=xlDelimited, _ TextQualifier:=xlDoubleQuote, _ ConsecutiveDelimiter:=False, _ Comma:=True 'ああ.xlsブックに移動 Sheets(1).Move after:=Workbooks("ああ.xls").Worksheets(Workbooks("ああ.xls").Sheets.Count) Next i Else MsgBox "検索条件を満たすファイルはありません。" End If End With End Sub