次の方法で共有


Excel VBAのグラフ更新で実行エラーとなるのは何故?

質問

2021年2月10日水曜日 12:23

計測器から多チャンネルの温度データを一定間隔で取得しグラフを更新していくプログラムを作成中です。
しかし、400回程度データ取得すると「実行エラー1004 アプリケーション定義またはオブジェクト定義のエラーです」が表示され止まってしまいます。止まる場所は"SetSourceData Source:="のところです。
ch数を半分にすると取得回数は倍程度になります。止まる回数は同じ場合もありますがそうでない時もあります。さらにエラー後、強制停止させた後でグラフのデータ範囲が手動で変更出来なくなります??エラーが発生する前に停止させた場合はデータ範囲は変更できます。 Excelの不具合?仕様上の制限でしょうか?原因がわかりません。
 
下記コードで現象が確認できます。他のパソコン2台で確認(Win10 Excel2016)しましたが同じ現象となりました。
 
下記プログラム実行する前にデータが入るシート名には「データ」としデータフォーマットはセルB1~BM1に64ch分のチェンネル名(系列名)を入力しておきます。セルA2以降は自動的に1,2,3...という数字が入ります。グラフシート名は「グラフ」とし予めデータ1回分の散布図を直線で作成しておきます。また結果を早く出すために待ち時間を設けていません。
どうかよろしくお願い致します。
 
Sub 不具合再現テスト64ch()
 
Dim mcnt As Long '測定カウント数
Dim ch As Long '測定チャンネル数
Dim MeasData(0, 64) '測定データ;納
 
For mcnt = 1 To 1000 '1000回分で動作の様子を見る(測定希望回数は2万回)
 
    MeasData(0, 0) = mcnt '測定回数を入れる
 
    For ch = 1 To 64 'チャンネル
        MeasData(0, ch) = Int((20 * Rnd) ; 10) '乱数データを適当に入れる
    Next ch
 
    With Worksheets("データ")
      If ActiveSheet.Name = "データ" Then .Cells(1 ; mcnt, 1).Activate 'データシートがアクティブ時にセルを動かす
      .Range("A" & 1 ; mcnt & ":BM" & 1 ; mcnt).Value = MeasData() '1回測定データを一気に貼り付け
 
      Charts("グラフ").SetSourceData Source:=.Range("A1:BM" & 1 ; mcnt), PlotBy _
        :=xlColumns 'グラフを更新 ←ココでエラー
    End With
 
    DoEvents
 
Next mcnt
 
End Sub

すべての返信 (8)

2021年2月13日土曜日 15:18

kazu0706さん、今晩は。

ここらあたりではないかと思いますが。

Excel の仕様と制限 - Excel (microsoft.com)

私の場合、1系列約60ポイントのxy散布の約60系列を表示したグラフシートを3シートばかり作成したブック(.xlsm)の場合、ブックの容量は約3MBばかりですが、手動でも、グラフ作成の際に挙動不審が見られ、作成時に注意が必要な感じ(必ず控えを取っておくなど)です。


2021年2月15日月曜日 13:00

 KokemomoYamamomo様

返信ありがとうございます。

「手動でも、グラフ作成の際に挙動不審が見られ」とはグラフは作成されなかったということでしょうか?

メモリ依存という制限があるということですが、あまりにも少なすぎませんか?

私の場合、手動でも64系列×行数数2000行のデータ選択でグラフを作成しましたがエラーはありませんでした。

なのにVBAで実行するとエラーが発生します。

但し、予め2000回分のデータ範囲を指定(Charts("グラフ").SetSourceData Source:=.Range("A1:BM" & 1 ;2000 ), PlotBy :=xlColumns)しデータを入力とするとエラーは発生しません。

データ範囲の指定方法は予め指定しグラフを作成しなければならないという仕様であるということならば納得できるのですが原因がわからないので正解が知りたいですね。

MS社の方からの回答は得られるのでしょうか?よろしくお願いします。


2021年2月15日月曜日 14:43

kazu0706さん、今晩は。

挙動不審とは、系列名、系列X、系列Yの順にデータ範囲をセットしていくとハングアップしたようになってグラフが描画できないけれども、系列名の次に系列Yをセットして、最後に系列Xをセットするとグラフが描画される、という訳の分からないことがありました。今では、グラフ数もワークシートも削除して少なくしたので、挙動不審は今のところは再現できません。

なお、ご提示いただいたVBAマクロを試してみました。グラフの種類は折れ線グラフとし、最初はまっさらとしたところがkazu0706さんと異なります。1回目は、項目数が341までワークシートにデータが記入されたところでエラーでストップ、2回目は340でストップ、3回目は339まででストップ、4回目は別の3MBほどのワークブックを開いておいて実行しましたら、337まででストップしました。試行回数が重なる度に1ずつ減って、4回目は2減っているのが不思議です。

系列数は64なので制限範囲内ですね。項目数がメモリに応じた項目数という事でしょうか。

パソコンを再起動して、タスクマネージャを起動した状態で改めてやり直しましたら、340でストップしましたが、メモリ使用量は半分以下のレベル(すべてがエクセルではなく、エクセルの使用量は少ない)であることが分かりました。

こうなるとなおさらエラーが出る理由が良く分かりませんが、どうやら最初の小生のご返事は的外れみたいですね。以上、情報提供まで。

そのほかのご質問については、分かりませんので、お答えしかねます。悪しからず。


2021年2月16日火曜日 0:21

2010では342行目でエラー発生しました。

SetSourceDataの前に

Dim cnt As Series: For Each cnt In Charts("グラフ").SeriesCollection: cnt.Delete: Next

を置くと改善しました。

ただ、処理が遅くなるので、エラー発生時にのみ実行するようにした方がベターかも。


2021年2月16日火曜日 0:43

訂正。

SetSourceDataの前に

Dim cnt As Series: For Each cnt In Charts("グラフ").SeriesCollection: cnt.Delete: Next

ではなく、

Charts("グラフ").ChartArea.ClearContents

の方が早いかも。


2021年2月16日火曜日 2:13

kazu0706さん、おはようございます。

グラフ描画の前に「If mcnt Mod 100 = 0 Then」を、直後に「End If」を挿入して100回目ごとにグラフを描画するようにしましたら、1000回まで完遂出来ました。

そこで今度は1000を10000に1桁上げて試してみましたら、次第に動作が重くなり、9000でメモリ不足のメッセージが出て止まりました。タスクマネージャで見ていると、波を打ちながらメモリ使用量が増えていきましたが、まだ未使用量は残っておりました。

次に、データ項目数は1のままでデータは更新してグラフ描画を繰り返すように変更して試してみましたら、340でエラーで止まりました。

どうやら、メモリが残っていても、340回程度グラフ描画が繰り返されるとエラーとなるのではないかと思われます。どうしてなのかは分かりません。

以上、ご参考まで。


2021年2月16日火曜日 4:56

kazu0706さん、minmin312さん、こんにちは。

どうもmcntが340くらいでエラーが起きるので、minmin312さんのご回答の通り、エラーが生じた時点で、エラー処理で「Charts("グラフ").ChartArea.ClearContents」を実行するようにしましたら、途中2回エラー処理が挟まりましたが特に違和感なく、mcnt=1000まで実行できました。毎回「Charts("グラフ").ChartArea.ClearContents」を実行していると偉く時間がかかってしまいますので、エラー処理で実行するというminmin312さんのアイデアが正解ですね。


2021年2月16日火曜日 13:54

KokemomoYamamomo様、minmin312様

こんばんは、試して頂きまして本当に感謝します。色々なエラー回避のアイディアあってとても勉強になります。

自分でもそれぞれを動作確認し測定間隔に間に合う回避策を検;していきたいと思います。原因は??ですが...

目標は2万回分のデータ取得!測定間隔をどこまで縮めるか!少し時間は掛かりますがまた報告させて頂きます。

よろしくお願い致します。