まえがき
文字数制限にひっかかってしまったため、一部のコードを消去しました。
消去したコードにつきましては、編集履歴 の方からご確認いただけます。
前提・実現したいこと
先日、VBA(Excel)で、アクティブなChart の名前を取得するべく、
Chart オブジェクト の MouseDownイベント を用いたプラグラム を組みました。
しかし、そのイベントが連続的に実行された場合、
以下のエラーメッセージが発生してしまいます。
このエラーを回避するコードは組めたのですが、
結局、エラーが発生する原因は分かりませんでした。
今後、同様のエラーを発生させないためにも、
このエラーの原因を突き止めたいです。
エラーメッセージ(Microsoft Excel)
MicrosoftExcel
1この操作を完了するにはメモリが不足しています。 2扱うデータ量を減らすか、他のアプリケーションを終了してください。 3使用できるメモリを増やすには、以下を検討してください。 4- 64ビット版の Microsoft Excel を使う。 5- デバイスのメモリを増設する。
エラーメッセージ(イベント ビューアー)
障害が発生しているアプリケーション名: EXCEL.EXE、バージョン: 16.0.4966.1000 障害が発生しているモジュール名: oart.dll、バージョン: 16.0.4900.1000 例外コード: 0xc0000005
該当のソースコード
ここには エラー発生の原因となるコードを載せます。
全体のコードは【ソースコード(全体)】に載せてあります。
VBA
1 2' TestChart 3Public WithEvents TargetChart As Chart 4 5Private Sub TargetChart_MouseDown(ByVal Button As Long, ByVal Shift As Long _ 6 , ByVal x As Long, ByVal y As Long) 7 8 Debug.Print sheet_.ChartObjects(ActiveChart.Parent.Index).Name ' エラー発生 9 10End Sub
【ソースコード(全体)】
VBAModule
1 2Public sheet_ As Worksheet 3Private class_ As New TestChart 4 5Sub Set_Data() 6 7 Set sheet_ = ThisWorkbook.Sheets("Main") 8 Set class_.TargetChart = sheet_.ChartObjects("Chart 1").Chart 9 10End Sub
VBAClass
1 2' TestChart 3Public WithEvents TargetChart As Chart 4 5Private Sub TargetChart_MouseDown(ByVal Button As Long, ByVal Shift As Long _ 6 , ByVal x As Long, ByVal y As Long) 7 8 Debug.Print sheet_.ChartObjects(ActiveChart.Parent.Index).Name ' エラー発生 9 10End Sub
VBAThisWorkbook
1 2Private Sub Workbook_Open() 3 Call Set_Data 4End Sub
エラー発生の経緯
(シート上には、空のChart(種類:2-D 集合縦棒, 名前:グラフ 1)が一つ 存在しています)
上記ソースコードのイベントが実行された場合、
私は 次のように出力されると予測しました。
immediate
1Chart 1 ' 予測した結果
実際には、次のように出力されました。
immediate
1Chart 1 ' 実際の結果
予想した通りの結果となったため、デバッグ作業に移りました。
デバッグとして、Chart を連続的にクリックし、MouseDown イベントを発生させ続けたところ、
上記のエラーが発生してしまったのです。
タスク マネージャー
タスク マネージャー の 【アクティブなプロセスで使用されている物理メモリ】
- エラー発生前:68 %
- エラー発生後:69 %
32bitアプリのメモリ上限は2GB…であってますよね?
vbaが2GBフルで使用できるわけではないかと思いますが(Excel本体の機能の分があるため)、
それにしても Excelに割り当てられているメモリが少なすぎるように感じます。
【このプロセスで使用されているため別のプロセスでは使用できない物理メモリの量(中断された UWP プロセスを除く)】の推移
(EXCEL.EXE)
・【' エラー発生 の コード】:増える。
クリック回数 | 物理メモリの量 |
---|---|
0 | 38,112 K |
1 | 39,264 K |
2 | 39,640 K |
3 | 39,860 K |
4 | 40,932 K |
5(エラー発生) | 41,088 K |
・【' 問題なし の コード】:増えない。
・イベントを無効にした状態(コメントアウト)で検証:増えない。
解決方法
上記コードを次のように変更したところ、
エラーは発生しなくなりました。
before
1Debug.Print sheet_.ChartObjects(ActiveChart.Parent.Index).Name ' エラー発生
after
1Debug.Print ActiveChart.Parent.Name ' 問題なし
しかし、エラー発生の原因は分からないままだったため、
原因の追究をすることにしました。
試したこと(1)
【sheet_.ChartObjects(ActiveChart.Parent.Index).Name ' エラー発生】
↓
【ActiveChart.Parent.Name ' 問題なし】
という結果から、**【.(ピリオド)】**の個数に注目しました。
こちらを参考にして、次のコードを組んでみました。
VBA
1編集履歴をご参照ください。
結果は変わらず、同じエラーが発生しました。
次に、【sheet_.ChartObjects(ActiveChart.Parent.Index).Name】
に原因があるのかを調べるため、次のコードを実行してみました。
VBA
1編集履歴をご参照ください。
結果は問題なし。
【sheet_.ChartObjects(ActiveChart.Parent.Index).Name】
でもエラーが発生しないということは、【MouseDown イベント】に問題がある と考え、
そちらに注目し、原因の追究をすることにしました。
(【試したこと(2)】に続きます)
試したこと(2)
まずは、【MouseDown イベント】以外のイベントだとどうなるのか、
検証してみました。
ただし、【空のActiveChart】という前提 に合わないイベントは、
検証するイベントから除いています。
結果は次の通りです。
イベント | Debug.Print sheet_.ChartObjects(ActiveChart.Parent.Index).Name | Debug.Print ActiveChart.Parent.Name |
---|---|---|
MouseDown | エラー発生 | 問題なし |
BeforeDoubleClick | エラー発生 | 問題なし |
Activate | 問題なし | 問題なし |
MouseMove | 問題なし | 問題なし |
Resize | 問題なし | 問題なし |
検証の結果、【MouseDown イベント】だけではなく、
【BeforeDoubleClick イベント】でも同じエラーが発生する ことを確認できました。
そこで、次は【BeforeDoubleClick イベント】から、次のコードを検証してみました。
VBA
1編集履歴をご参照ください。
結果は、【MouseDown イベント】と同様のエラーが発生しました。
(【試したこと(3)】に続きます)
試したこと(3)
Chart クリック → 適当なセルをクリック
というのを繰り返した結果、エラーが発生しませんでした。
これに注目し、イベント間に何かしらの処理を挟んでみる ことにしました。
次は、検証用のコードとなります。
VBA
1編集履歴をご参照ください。
上記コードを実行し、Chart クリック → sheet_.Range("F2").Select
というのを繰り返した結果、エラーが発生しませんでした。
検証を深めるため、上記コードを次のように変更してみました。
VBA
1編集履歴をご参照ください。
上記コードを実行し、Chart クリック → sheet_.Range("F2") = boolean_
というのを繰り返した結果、エラーが発生しました。
(【試したこと(4)】に続きます)
試したこと(4)
次に、Chart 1 クリック → Chart 2 クリック
というのを繰り返した結果、エラーが発生しませんでした。
VBA
1編集履歴をご参照ください。
これに注目し、次のコードを検証してみました。
VBA
1編集履歴をご参照ください。
上記コードを実行し、
Chart 1 クリック → sheet_.ChartObjects("Chart 2").Chart.ChartArea.Select
というのを繰り返した結果、エラーが発生しませんでした。
(Chart 一つに使用できるメモリの量が決められていて、そのメモリが、
【セル や 他のChart の Select】が行われるまで解放されない…ということでしょうか?)
(【試したこと(5)】に続きます)
試したこと(5)
その他、次のことを試してみましたが、
結果は変わらず、同じエラーが発生するだけでした。
- 【ハードウェアグラフィックスアクセラレータを無効にする】を選択する
- 違う種類のChart(円・折れ線)を使用する
- book の修復
- アドイン の無効化
- Debug.Print sheet_.ChartObjects(ActiveChart.Parent.Index).Name
を、Sub プロシージャ に移し、イベントから、そのプロシージャを呼び出すようにする
- ステップイン実行【イベント処理終了時(End Sub 到達後、[F8 キー]押下)、エラー発生】
(これにより、処理の終了前に次の処理が開始される → 処理が追いつかなくなってエラー
…という可能性もない、と考えてよさそうです。正直、一番ありえそうな原因だったのですが…)
同様の症状について探していたところ、次の質問が見つかりました。
Excel vba でメモリが不足しています。っと表示されて処理が完了できない。
エラーメッセージ はドンピシャだったのですが…
私は、【カメラ 機能】も【リンクされた図】も【数式】も【名前の定義】も
使用(追加)していません。
(そもそも、Excelファイル新規作成 → 空のChartを挿入 → 上記ソースコード を記入
…しか行っていないファイルのため、肥大化とかはしていない…はずです。
念のため、上の手順で同じファイルを作成してみましたが、何も変わりませんでした)
また、次の環境で試してみたところ、エラーは発生しませんでした。
Windows 7 Home Premium
メモリ:8.00 GB
Excel 2010 64bit(14.0.7237.5000)
追記:試したこと(6)
sazi 様 からのご指摘を受け、次のコードの検証を行いました。
VBA
1 2Public sheet_ As Worksheet 3Public flag_ As Boolean 4Private class_ As New TestChart 5Private class2_ As New TestChart _ 6 7Sub Set_Data() 8 9 Set sheet_ = ThisWorkbook.Sheets("Main") 10 Set class_.TargetChart = sheet_.ChartObjects("グラフ 3").Chart 11 Set class2_.TargetChart = sheet_.ChartObjects("グラフ 1").Chart 12 flag_ = False 13 14End Sub
VBA
1 2Private Sub TargetChart_BeforeDoubleClick(ByVal ElementID As Long, ByVal Arg1 As Long, 3ByVal Arg2 As Long, Cancel As Boolean) 4 5 DoEvents 6 7 If flag_ = False Then 8 9 flag_ = True 10 11 Debug.Print sheet_.ChartObjects(ActiveChart.Parent.Index).Name ' エラー発生 12 13 flag_ = False 14 15 DoEvents 16 17 End If 18 19End Sub
検証の結果、エラーが発生しました。
ステップイン実行 でもエラーが発生していることもあり、
イベント処理中に他のイベントが邪魔をしている、のではなく、
イベント終了時の処理 のどこかに**【エラー発生の原因】**が
ひそんでいるのではないか、と疑っております。
(【試したこと(5)】のステップイン実行でも、
End Sub 到達後の[F8 キー]押下により、エラーが発生しています)
(【追記:試したこと(7)】に続きます)
追記:試したこと(7)
クリックに間をおくとどうなるか、検証してみました。
・【 1 分 間隔 で Chart を クリック 】
クリック回数 | 物理メモリの量 |
---|---|
0 | 37,316 K |
1 | 35,972 K |
2 | 35,524 K |
3 | 35,516 K |
4(エラー発生) | 34,348 K |
・【 2 分 間隔 で Chart を クリック 】
クリック回数 | 物理メモリの量 |
---|---|
0 | 32,672 K |
1 | 35,240 K |
2 | 34,320 K |
3 | 34,292 K |
4 | 34,364 K |
5 | 35,308 K |
6(エラー発生) | 33,344 K |
クリック間に時間をおいても、エラーは発生しました。
また、メモリの方もよくわからない結果になってしまいました。
メモリ不足のエラーの割に、メモリはあまり関係なかったりするのでしょうか?
最後に
まとめると次のようになります。
同じ Chart を 連続的にクリックして、
【MouseDown イベント】や【BeforeDoubleClick イベント】で
特定のコードを実行し続けた場合、エラーが発生する。
【同じ Chart 】というのが、エラーが発生する原因のポイントではないか、と疑っているのですが…
情けない話ですが、私ではこれ以上どう検証していけばいいのか、皆目見当もつきません。
(検証にかけた時間の割に 分かったことが少なすぎて、泣きそうです)
エラー発生の原因について、情報いただけますと幸いです。
よろしくお願いします。
できないこと
わけあって、次の事項を行うことはできません。
・インストール
・管理者権限の必要な設定の閲覧・変更
・レジストリキーの値の変更
・Office アプリケーションの修復
・保護ビューの設定 の 変更(現在、3つの項目すべてに チェックがついている状態 です)
補足情報
Windows 10 Pro
メモリ:4.00 GB
Excel 2016 32bit(16.0.4966.1000)
ファイルサイズ 22 KB
Sheet1(Main)
空のChart(種類:2-D 集合縦棒, 名前:グラフ 1)
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/01 11:17
2020/05/12 11:45
2020/05/12 13:00
2020/05/12 13:54
2020/05/12 14:13 編集
2020/05/12 14:29