Excel2003のVBAでメモリを効率的に使用する方法

このQ&Aのポイント
  • Excel2003のVBAで大量のグラフを作成した際にエラーが発生し、ブックを閉じることもできなくなる問題が発生しています。メモリの使用状況を確認したところ、使用できるメモリの空き容量が20%以下しかないことがわかりました。メモリを効率的に使用するための方法やメモリ解放方法について教えてください。
  • Excel2003のVBAで大量のグラフを作成するとエラーが発生し、ブックを閉じることもできなくなる問題があります。マクロを実行してメモリの使用状況を確認したところ、使用できるメモリの空き容量が20%以下しかないことがわかりました。メモリを効率的に使用するための方法やメモリ解放方法について教えてください。
  • Excel2003のVBAで大量のグラフを作成した際にエラーが発生し、ブックを閉じることもできなくなる問題が起きています。マクロを実行してメモリの使用状況を確認したところ、使用できるメモリの空き容量が20%以下しかありません。メモリを効率的に使用する方法やメモリ解放方法について教えてください。
回答を見る
  • ベストアンサー

メモリを使いすぎている? VBA

Excel2003です。 いつも大変お世話になっております。 以前、 大量のグラフ(項目数50のグラフを30個以上) などを作った際にエラーが出て、 ブックを閉じることも、デバックをキャンセルすることも 保存することも出来なくなったことがありました。 今後二度とこのようなことが無いようにしたいのですが、 何が原因でしょうか? 原因の特定のため、 拾ってきたマクロを実行しました。 Sub Sample1() Dim n As Long, msg As String n = Application.MemoryTotal msg = msg & "Excelが使用できるメモリの総容量:" & Format(n / 1024, "#,##0") & "KB" & vbCrLf n = Application.MemoryUsed msg = msg & "Excelが使用しているメモリの総容量:" & Format(n / 1024, "#,##0") & "KB" & vbCrLf n = Application.MemoryFree msg = msg & "Excelが使用できるメモリの空き容量:" & Format(n / 1024, "#,##0") & "KB" MsgBox msg End Sub 実行したところ、 「使用できるメモリ総量:5,256KB  使用してるメモリ総量:4,232KB  使用できるメモリ空き:1,024KB」 と表示されました。 メモリ空きは少しありますが、 残り20%以下しかありません。 これが普通でしょうか? メモリ解放方法や、何かメモリをあまり使わないようにする為に 見るポイントなどありましたら教えてください。 よろしくお願い致します!

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

  • ベストアンサー
  • jcctaira
  • ベストアンサー率58% (119/204)
回答No.3

satoron666 さん こんにちは。 メモリは結構あるので大きなプログラムを作っても大丈夫です。 パソコン(Windows)はメモリに余裕があってもリソース・メモリの方が影響が大きです。 http://www5.plala.or.jp/vaio0630/win/resource.htm  ・オブジェクト(データベースのアクセス用のADO、グラフ等のChartObjects等々)  ・グラフィック用のリソース  等々が問題になることが多いです。 今回はグラフの図形、グラフオブジェクトの両方を大量に使っているのが問題なように思えます。 私は昔、次の方法(グラフを画像化に変換)でプログラム対応をしました。 注)昔作成したソースそのままなので、分かりにくいですがヒントになればと思います。   ActiveSheet.ChartObjects("業種月別グラフ").Chart.CopyPicture _    Appearance:=xlPrinter, Size:=xlScreen, Format:=xlPicture   複写シート.Select   ActiveSheet.Pictures.Paste.Select   Selection.Name = "グラフ" & NO   With ActiveSheet.Shapes("グラフ" & NO)    .Shadow.Type = msoShadow6    .Left = Range("A3").Left + ((NO - 1) Mod 4) * .Width    .Top = Range("A3").Top + Int((NO - 1) / 4) * .Height   End With          : ちなみにNo.1の方には申し訳ありませんが「LongをIntegerに変えるだけで半分」は 間違いではありませんが、メモリにはほとんど影響がないかと思います。 理由:使用できるメモリ空き:1,024KB とのことですが、Longを100個確保しても    100×4バイト=400バイト 1KBの半分程度なので1,024KBの0.05%です。    ※Integerは200バイトになりますのでLongより0.025%減る程度です。    また計算速度ですが、最近CPUが32ビットや64ビットになっているのでLongの方が    早くなっているようだし大きな数値も扱えるのでオススメです。 話は遠回りしましたが、グラフを少なくしたり、グラフオブジェクトを減らしたり…等々 色々工夫して対応するしかないかと思います。 ご検討ください。

satoron666
質問者

お礼

回答ありがとうございました! 違うタイトルで再度質問したいと思います。 また、図として貼り付けるのを試してみましたが 速度が遅くなるため使うのを避けたいところです… 画像は、保存する場所が無いため、避けたいです。 上記のことを考慮し、 良いプログラムを作れればなと思います! ありがとうございました!

satoron666
質問者

補足

回答ありがとうございます。 グラフが原因でしたか… 画像化するにあたり、 グラフの位置を読み取り、 その上に画像を載せた後 グラフを全消去という方式にしたいと思っています。 グラフにし終わった段階で画像化したら 早いですかね… とりあえず、方法を考えてみたいと思います!

その他の回答 (2)

  • tachin
  • ベストアンサー率29% (134/454)
回答No.2

 50項目を30もグラフ処理した事がないのでわかりませんが、グラフ20個ではどうですか?。10個ではどうですか?5個ではどうですか?。簡単なシステムチェックです。数を大きく減らしてもダメとなると項目数が多いのか、1項目の大きさが多きすぎるのかです。  また、マクロを組まれている場合、Redimでワークをとっている場合、Eraceしないとメモリ解放されません。使うたびにメモリ消費しているのではないですか?。  あるいは、別プログラムがやたらと立ち上がっているとか。

satoron666
質問者

お礼

回答ありがとうございました! グラフが原因そうなので 対応を考えて見ます。

satoron666
質問者

補足

回答ありがとうございます。 グラフの表示個数が増えると、 使っているメモリが減ります(たぶん) 空きメモリの容量は何故か減りませんが… グラフの個数は減らせないです。 Redimも使っていません。 でも、グラフが原因かもと分かってよかったです!

  • usami33
  • ベストアンサー率36% (808/2210)
回答No.1

まずは、型の見直しから たとえば、LongをIntegerに変えるだけで半分になりますよね。 計算途中でLongの精度が必要な場合は計算のみLongで行い、計算結果はIntegerに格納 配列ばど、たくさんのメモリを消費する宣言は、 各関数の内部で宣言する。 ※使用するときだけ宣言する VB系は関数を抜けると解放します。

参考URL:
http://www.nda.co.jp/memo/dim.html
satoron666
質問者

お礼

回答ありがとうございました! グラフが原因そうなので 対応を考えて見ます。

satoron666
質問者

補足

回答ありがとうございます。 型を全てLong→Integerに変更してみましたが、 メモリ使用容量は全く変わりませんでした。 うーん、なぜなのでしょうかね…

関連するQ&A

  • Excel2007VBAプロシージャの引数について

    ●質問の主旨 下記コードのうち、 buf = buf & msg & vbCrLfについて 1.右辺の変数bufはどんな役割があるのでしょうか? 2.右辺のbufを省略したら、メッセージボックスに 表示される「Excel」の文字は3つから1つになります。 これはなぜでしょうか? ご存知の方ご教示よろしくお願いします。 ●コード Sub Sample8() Call Sample9("Excel", 3) End Sub Sub Sample9(msg As String, n As Long) Dim i As Long, buf As String For i = 1 To n buf = buf & msg & vbCrLf Next MsgBox buf End Sub

  • エクセルVBAにて保存するとき

    Private Sub Workbook_BeforeClose(Cancel As Boolean) If MsgBox("エクセルを終了してもよろしいですか?", vbYesNo) = vbNo Then Cancel = True Exit Sub End If Application.DisplayAlerts = False Application.Quit End Sub Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) MsgBox "そのボタンでは保存できません。" & vbCrLf & _ "雛形は残しておきましょう" & vbCrLf & _ "" & vbCrLf & _ "ツールバーの「マクロなし出力」から保存できます。" Cancel = True End Sub という二つのマクロをThisworkbookにいれてあるんですが、 この二つを有効(今は2つ目を'でコメント状態にしてあるので保存可)にすると保存できなくて困っています。 二つを有効にした時はどのようにほぞんすればいいですか?

  • なぜ2007じゃできないのか?

    エクセル2007を使っています。 Sub test() 'Excel が使用できるメモリの空き容量 Debug.Print Format(Application.MemoryFree, "#,###") & "Byte" End Sub を実行すると、型が一致しません。(Error 13)になります。 2003なら問題ありません。 2007年ではできない理由を教えてください。

  • エクセルVBAを中断する場合

    簡略化してますが、下記のVBAコードはDATAシートから1行ずつデータをBBBシートに読み込み、プリントまたはプリントプレビューするものです。 予期したとおりに作動するのですが、1点不満があります。 途中でやめることが出来ないのです。もちろんEscキーを長押しすればエラーになって止まりますが、そうするとステータスバーの表示が残ったままになります。 On Error GoTo で、Application.StatusBar = ""に飛ぶようにしているのですがEscキー長押しのエラーでは飛ばないようです。 1.どうやったらすんなり止めることができるでしょうか? 2.その他、改善点がありましたらご指摘ください。 Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Option Explicit Sub DM_OutPut() Dim myYN As Integer, myYN2 As Integer, s As Long, n As Long, x As Long, tx As String Dim ds As Worksheet, bs As Worksheet, base As Range s = 300 myYN = MsgBox("データはDATAシートに切れ目なくセットされてますか?", vbYesNo + vbQuestion, " (^∇^)?") If myYN = vbNo Then Exit Sub Else myYN2 = MsgBox("本番印刷行きますか?" _ & vbCrLf & "すぐ行っちゃうなら「はい」を、" _ & vbCrLf & "テストでプレビュー画面出すなら「いいえ」をクリックしてください。" _ & vbCrLf & "" _ & vbCrLf & "プレビューは1画面 約" & Format(s, "#,##0") & "ミリ秒間表示します。", vbYesNo + vbQuestion, " (^∇^)?") End If Set ds = Sheets("DATA") Set bs = Sheets("BBB") Set base = ds.Range("B3") '基準点 bs.Rows(3).ClearContents Do While 1 On Error GoTo line If base.Offset(n).Value = "" Then Exit Do '基準点以下にデータのある限り続ける bs.Rows(3).Value = base.Offset(n).EntireRow.Value n = n + 1 'カウント Application.StatusBar = Format(n, "#,##0") & "件目を処理しました。" If myYN2 = vbNo Then SendKeys "%C" 'デモ用 ActiveSheet.PrintPreview tx = "プレビュー" Else ActiveSheet.PrintOut Copies:=1 '本番用 tx = "プリント指示" End If Sleep s '休みを入れる Loop MsgBox Format(n, "#,##0") & "件を" & tx & "しました。", vbInformation, " (o^-')v " line: Application.StatusBar = "" End Sub

  • Outlookのメールを送信するマクロ

    お世話になっております。 Microsoft Outlook2003使用で メール送信のマクロを見様見真似で作ってみたのですが、本文部分がうまくいきません(Best regardsしか表示されません)。 どうすれば正しく反映されるでしょうか? シートのB1にToアドレスを記入していてTo_addressと名前付 以下、Cc_addressとSubjectも同様にしています。 本文の文章は何行かあり、途中で空白行も入れたいのですが、そこまでまだ手がつけられていません。 本文の文章が3行あるとすると、このマクロではComment1、Comment2、Comment3と名前付しています。 Sub SendEmail() Dim OlApp As Outlook.Application Dim mItem As Outlook.MailItem Dim cell As Range Dim Subj As String Dim EmailAddr As String Dim Recipient As String Dim Msg As String Dim Message As String Dim Sender As String Dim Comments As String Dim Comments2 As String Dim report As String Worksheets("Sheet1").Activate 'Create Outlook object  Set OutlookApp = New Outlook.Application 'Get the data Subj = Range("Subject") EmailAddr = Range("To_address") CCAddr = Range("Cc_address") Body = Range("Comment1") & ("Comment2") & ("Comment3") 'Compose message Msg = Msg & Comment1 & vbCrLf & vbCrLf Msg = Msg & Comment2 & vbCrLf & vbCrLf Msg = Msg & "Best regards," & vbCrLf & vbCrLf 'Create Mail Item Set mItem = OutlookApp.CreateItem(olMailItem) With mItem .To = EmailAddr .CC = CCAddr .BCC = BCCAddr .Subject = Subj .Body = Msg .Display End With End Sub 宜しくお願い致します。

  • VBA初心者なのですが(Userformについて)

    まずは質問ご覧いただきありがとうございますm(_ _)m さっそくなのですが、次のプログラムを打つとSelect Caseのところで”指定されたオブジェクトは見つかりません”と出てしまうのですがなぜでしょうか。回答お待ちしております。 Private Sub CommandButton2_Click() Dim msg As String, i As Integer Dim ii As Integer, msg2 As String For i = 1 To 3 If Controls("CheckBox" & i).Value = True Then msg = msg & Controls("CheckBox" & i).Caption & vbCrLf End If Next i For ii = i To 2 If Controls("OptionBotton" & i).Value = True Then msg2 = msg2 & Controls("OptionBottob" & i).Caption & vbCrLf End If Next ii Select Case Controls("CheckBox" & i).Value & Controls("OptionBotton" & i).Value Case Controls("CheckBox" & i).Value = True & Controls("OptionBotton" & i).Value = False MsgBox msg & "がチェックされてます" Case Controls("CheckBox" & i).Value = False & Controls("OptionBotton" & i).Value = True MsgBox msg2 & "オン" Case Controls("CheckBox" & i).Value = True & Controls("OptionBotton" & i).Value = True MsgBox msg & "がチェックされています" & vbCrLf & msg2 & "オン" Case Else MsgBox "チェック又は、オンにしてください" End Select End Sub

  • メモリ不足のエラーをなんとかしたい

    オフィス97のエクセルでグラフを作っています。 元のデータは3つのシートにわかれており、それらからデータを引っ張ってきて別シートにグラフを作っています。 さほどグラフの数を作っていないにも関わらずメモリ不足とエラーが出て先にすすめなくなってしいます。 無論メモリは最低でも128MB、最高で256MBあるマシン両方で試してみました。 ほかのアプリケーションも立ち上げてませんし、保存したファイルも290kb程度ととてもメモリ不足になるとは思えないんです。 また、1ページずつでもやれればいいかと思って、1ページ分のグラフ9個でやってみましたが、状況はほとんどかわりません。しかもそれで保存してもファイルサイズが280kbとほとんど小さくなっていません。 何がいけないんでしょうか? アドバイスでもいただければと思います。

  • Excel VBAでユーザーフォームだけ表示したい

    Excel VBAでユーザーフォームを作成し、ファイルを起動時にSheetを非表示にしてユーザーフォームのみ表示させるようにしました。 そうしたところ、 (1)実行ボタンをクリックすると作成されるExcelファイルも表示されなくなる (2)終了ボタンをクリックするとユーザーフォームを含むExcelファイルだけが閉じるのではなく、Excelのアプリ自体が終了してしまう(実行ボタンで作成したExcelファイルは表示したままにしたいのに閉じてしまう) という現象になってしまいました。 某書籍を参考にしてコードを書いたのですが、なぜかこのようになってしまいました。 ※「★」が書籍に指示があった箇所です。 <ThisWorkbook> Private Sub Workbook_Open() Application.Visible = False '★ myForm.Show '★ myForm.MultiPage1.Value = 0 'マルチページ構成のため End Sub Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) '========== [×]ボタン,[Alt]+[F4]キーを無効にする ========== Dim msg As String, title As String msg = "[画面を閉じて終了する]ボタンから終了してください。" title = "終了方法" Dim res As Integer Select Case CloseMode Case vbFormControlMenu res = MsgBox(msg, vbOKOnly + vbCritical, title) Cancel = True End Select ActiveWorkbook.Save '★ Application.Visible = True '★ Application.Quit '★ End Sub 実行したいのは、 (1)ユーザーフォームを含むExcelファイルを起動したときは、起動時にユーザーフォームだけが表示されるようにしたい  ※ワークシートを非表示としたい (2)「実行」ボタンをクリックすると、プログラムが実行されExcelファイルが新規で作成され表示される  ※上記で記載した「★」の部分をコードをコメントアウトしてユーザーフォームから実行ボタンをクリックすると、プログラムが実行され正常にExcelファイルが新規で作成されることは確認済みです。 (3)ユーザーフォームが閉じても、ユーザーフォームのExcelファイルのみ閉じ、新規で作成されたExcelファイルは閉じない。  ※実行ボタンをクリックして新規ファイルを作成しなかったり、他にExcelファイルがなかった場合は、Excelは終了する。 それとあわせて、 (1)を実行できた場合に、再度コードを編集する時はどうしたらExcelの画面が表示できるのか教えて下さい。  ※それとも表示できないのでしょうか? 作成締め切りが迫っていて焦っています。 お知恵のある方どうかお力添え下さい。 よろしくお願い致します。

  • VBAでFunctionの使い方

    エクセルのVBAでFunctionの使い方がいまいちよくわかりません。 Function msg() Dim h As Integer h = Hour(Time) Select Case h Case Is < 12: msg = "おはようございます。" Case Is < 17: msg = "こんにちは。" Case Else: msg = "こんばんは。" End Select End Function Sub 挨拶() MsgBox msg End Sub とやってみたら一応正しく動くようですが、これであっているのでしょうか? 他の例などを見るとFunction msg()の()内にも何か入れなければならないようなのですが、わかりません。

  • VBAの構文

    Access2002を使用しています。 VBAにて、クエリの結果をメール本文に書き出したいのですが 宜しくお願いします。 【使用するクエリ】 クエリ名:果物クエリ(選択クエリ) フィールド項目:日付、注文者、発送先、電話番号、品名、数量 【現在の内容】 Private Sub コマンド1_Click() On Error GoTo Err_コマンド1_Click Dim stDocName As String Dim strsubject As String Dim strmailto As String Dim strmailto2 As String Dim strtext0 As String Dim strText1 As String Dim strText2 As String Dim strText3 As String Dim strText4 As String Dim strText5 As String Dim strtext6 As String Dim strtext7 As String Dim strtext8 As String Dim strtext9 As String strmailto = Me.電子メール_アドレス strsubject = "商品発送のお知らせ" strText1 = Me.氏名 & " 様" strText2 = "いつもお世話になります、第一青果です。" strText3 = "以下の商品を発送致しましたのでご確認下さいませ。 " strtext0 = "---------------------------------" strText4 = "何でも新鮮!" strText5 = "第一青果" strtext6 = "担当:山田 太郎" strtext7 = "mailto:info@808yaoya.net" strtext8 = "http://808yaoya.net" strtext9 = ★ここからクエリ内の「品名」と「数量」を書き出したい!★ ★以下、現在はレポートをエクセルファイルにして添付するようにしている★ stDocName = ChrW(32013) & ChrW(21697) & ChrW(12524) & ChrW(12509) & ChrW(12540) & ChrW(12488) DoCmd.SendObject acReport, stDocName, , strmailto, , , strsubject, strText1 & vbCrLf & vbCrLf & strText2 & _ vbCrLf & strText3 & vbCrLf & vbCrLf & strtext0 & vbCrLf & strText4 & vbCrLf & strText5 & vbCrLf & strtext6 & vbCrLf & _ strtext7 & vbCrLf & strtext8 & vbCrLf & strtext0 & vbCrLf & strtext9, True Exit_コマンド1_Click: Exit Sub Err_コマンド1_Click: MsgBox Err.Description Resume Exit_コマンド1_Click End Sub

専門家に質問してみよう