Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10全般 : Excel 2016)
画面上に一度も読み込んでいないグラフの操作について
投稿日時: 23/07/26 13:58:56
投稿者: ひろと

標題のようなグラフのグラフ名称を「グラフ1」、そのグラフのあるシートのコード名を「wsグラフ」、現在表示させているシートが「wsグラフ」以外の場合に、

wsグラフ.ChartObjects("グラフ1").Chart.PlotArea.Top=10
とすると、以下のエラーが出ます。これを回避する方法はありますでしょうか?
出来ればシートをセレクトするという方法は避けたいです。
 
実行時エラー'-2147467259 (80004005)':
'Top'メソッドは失敗しました:'PlotArea'オブジェクト

回答
投稿日時: 23/07/26 15:54:44
投稿者: simple

試してみましたが、再現しませんね。(当方、Win10,Excel2019)
そもそもTopはメソッドではなく、プロパティですよね。
と言っても詮無いですか。
 
それと、シートがアクティブならエラーにはならないのですか?
それもあまり想定しにくいのですが。
一部分のコードだけでなく、Sub から End Subまでを示されたらどうでしょうか。
(事象が再現する、できるだけ小さいものを)

回答
投稿日時: 23/07/26 16:11:57
投稿者: sk

引用:
画面上に一度も読み込んでいないグラフ

「既に作成済みであるグラフ」の話をされているのか、
ChartObjects オブジェクトの Add メソッドや
Shapes オブジェクトの AddChart / AddChart2 メソッドによって
「新規作成しようとしているグラフ」の話をされているのか、
どちらなのでしょうか。

投稿日時: 23/07/26 16:49:01
投稿者: ひろと

simpleさん、skさん
コメントありがとうございます。
 
本件、「既に作成済みであるグラフ」の内容です。
また、コードは抜粋すると以下の通りです。

Sub グラフ大きさ調整()
Dim エリア
 ReDim エリア(1)
 エリア(1) = Array("", 10, 210, 18, 500)
For Each グラフ In wsグラフ.ChartObjects
 With グラフ
  .Height = 324
  .Width = 556
  With .Chart
   With .PlotArea
    .Top = エリア(1)(1)
    .Height = エリア(1)(2)
    .Left = エリア(1)(3)
    .Width = エリア(1)(4)
   End With
  End With
 End With
Next グラフ
End Sub
この11行目
.Top = エリア(1)(1)
でエラーが出ます。エリア(1)(1)を210に書き換えてもエラーは出ます。
その手前の
  .Height = 324
  .Width = 556
はエラーは出ません。
 
wsグラフシートがアクティブなだけではエラーが出て、一度グラフを描画済みの状態(グレーアウト+アイコンではない状態)にすればエラーは出なくなります。逆に、一度描画してしまっていれば、wsグラフシートが非アクティブでもエラーは出ません。
最初の投稿で、『現在表示させているシートが「wsグラフ」以外の場合に、』と記載したのは説明を省略しておりました。
 

回答
投稿日時: 23/07/26 17:05:33
投稿者: simple

引用:
wsグラフシートがアクティブなだけではエラーが出て、
一度グラフを描画済みの状態(グレーアウト+アイコンではない状態)にすれば
エラーは出なくなります。
ということは
描画する前にそのマクロを実行するということですか?
なぜ、そのようなトリッキーなことに挑戦されるのですか?

投稿日時: 23/07/26 17:37:33
投稿者: ひろと

simpleさん
 
描画前にマクロを実行します。
主な理由は、以下の通りです
・データ入力及びマクロ実行ボタン設置シートとグラフ設置シートが別であること
・グラフは4枚ありますが、各グラフ8,000行弱×20系列弱あり、描画するときにPC動作が重くなること
・使っているのは会社PCですが、能力が貧相であること(ただし業務遂行のためにグラフは省けない)

回答
投稿日時: 23/07/26 17:49:48
投稿者: sk

引用:
本件、「既に作成済みであるグラフ」の内容です。

引用:
wsグラフシートがアクティブなだけではエラーが出て、一度グラフを
描画済みの状態(グレーアウト+アイコンではない状態)にすれば
エラーは出なくなります。逆に、一度描画してしまっていれば、
wsグラフシートが非アクティブでもエラーは出ません。

(「新規作成しようとしているグラフ」ならばともかく)
「既に作成済みであるグラフ」が一度も描画されていないという状況が
いまいちピンとこないのですが、そもそもそれらのグラフは
どのようにして作られたもので、どのタイミングで
そのマクロを実行なさろうとされているのでしょうか。
 
例えば「非アクティブなワークシート上に(複数個の)グラフオブジェクトを
新規作成する
マクロ」が別にあり、そのマクロが実行された後、
そのワークシートが(グラフオブジェクトが挿入されてから)
一度もアクティブになったことがない状況下において

それらのグラフオブジェクトのサイズとプロットエリアのサイズを
統一するマクロを実行しようとしている、といったことなのでしょうか。
 
その場合は、確かに「一度も描画されていない」ので
件の実行時エラーが発生することになりますが。
 
引用:
For Each グラフ In wsグラフ.ChartObjects
 With グラフ
  .Height = 324
  .Width = 556

For Each グラフ In wsグラフ.ChartObjects
 With グラフ
  .Select
  .Height = 324
  .Width = 556

回答
投稿日時: 23/07/26 17:57:40
投稿者: simple

事情はなんとなく分かりました。
 
それで提示されたコードは、描画前(データとのひも付きをする前)ということですか?
・shapeのHeightなどは何が設定されているのか、
・そのときのデフォルトのchatAreaのTop等のパラメータは何が設定されているのか、
等が提示されたコードでは判明しません。
そもそも描画前であることすら分かりません。
そのあたりはいかがですか?

投稿日時: 23/07/26 18:21:20
投稿者: ひろと

skさん、simpleさん
 
このエクセルは、数百あるロットをほぼ同じような見た目でまとめようとしているもので、グラフは既に作成済みのエクセルに組込まれています(エクセル1.xlsmでグラフ作成、コピーしてエクセル2.xlsmを作成、開いて編集←エクセル2.xlsmは開く前からグラフ作成済み)。
 
まとめ作業が進むにつれて適時入る、フォントサイズの変更や軸名称の修正、表示系列の増減の指示に対応するために、ご推察の通り、統一するマクロを実行しようとしています。このマクロでは加えて別途生データcsvの取込(取込区間は特定の値が条件を満たす範囲)も実施しています。
 
マクロ実行前のデフォルトの各パラメータは、エクセル作成日時(指示の入った程度)によってまちまちで、例えばエクセル100.xlsm(先週作成)とエクセル150.xlsm(昨日作成)とエクセル200.xlsm(今日作成)では異なった値です。
 
グラフのx値y値自体は、offsetとcountaを使って定義した名前(y軸1、y軸2等)を指定しているため、常に紐付が完了している状態です(いちいち重いので編集中は計算手動にしておりますが)。
描画せずに紐づいている状態という表現が正しいでしょうか…

回答
投稿日時: 23/07/27 11:33:27
投稿者: Suzu

引用:
グラフは既に作成済みのエクセルに組込まれています(エクセル1.xlsmでグラフ作成、コピーしてエクセル2.xlsmを作成、開いて編集←エクセル2.xlsmは開く前からグラフ作成済み)。

 
一度、表示を行い ファイルを保存し
ファイル開き直したあとに、Chartが含まれる Sheet をアクティブにしないと 同様になりますね・・
 
スタイルの変更なら、
  .ClearToMatchStyle
 .ChartStyle = 348
 
の様に、「ClearToMatchStyle」 を行うとエラーにはなりませんでした。
 
が、残念ながら、スタイルをカスタムして保存する事はできない。
 
 
 
であれば、グラフを「修正」ではなく、
変更内容を含め、グラフをテンプレートとして保存し、
 
Chart.ApplyChartTemplate メソッド (Excel)
https://learn.microsoft.com/ja-jp/office/vba/api/excel.chart.applycharttemplate
 
を使えば良いかと。
 
 
Excel VBAでグラフ作成を自動化するならグラフテンプレート機能が便利
https://www.stjun.com/entry/exceltemperate
 
にもある様に、VBAに 拘ると 逆に楽できませんよ。

回答
投稿日時: 23/07/27 13:08:57
投稿者: sk

引用:
データ入力及びマクロ実行ボタン設置シートと
グラフ設置シートが別である

引用:
グラフは4枚ありますが、各グラフ8,000行弱×20系列弱あり

・4 つのグラフが挿入されたワークシート(以下[グラフシート])と、
 それらのデータソースの大元となる表があるワークシート(以下[データシート])と、
 任意のパラメータ値を入力し、マクロを実行させるためのインターフェースとなる
 ワークシート(以下[パラメータシート])、そしてこれらのワークシートを
 参照、操作するプロシージャが記述されたモジュールがあらかじめ
 作成されているマクロ有効ブックがある。
 
引用:
グラフのx値y値自体は、offsetとcountaを使って定義した名前
(y軸1、y軸2等)を指定しているため、常に紐付が完了している

・[グラフシート]内の各グラフのデータソースは、そのブック内で
 定義された名前付きセル範囲である。
 
・それぞれの名前付きセル範囲の参照先として、[パラメータシート]上のセルを
 参照する COUNTA 関数や OFFSET 関数を用いて[データシート]上の表の範囲を
 部分的に参照する数式が設定されている。
 つまりその数式が返す結果により、グラフのデータソースとして
 実際に参照されるセル範囲は動的に変化する。
 
引用:
このマクロでは加えて別途生データcsvの取込(取込区間は
特定の値が条件を満たす範囲)も実施しています。

・このマクロ有効ブックとは別に、一定の間隔(日ごと、週ごと、月ごと)に
 作成される CSV ファイルが存在する。
 (この CSV ファイルのレイアウトが常に一定であるか否かは不明)
 
・上記の CSV ファイルをインポートし、[データシート]上に展開する
 プロシージャ(以下[インポートマクロ])がマクロ有効ブックの
 モジュールに作成されている。
 したがって、[データシート]上の表の内容は[インポートマクロ]が
 実行されるごとに異なる。
 
引用:
マクロ実行前のデフォルトの各パラメータは、
エクセル作成日時(指示の入った程度)によってまちまちで、
例えばエクセル100.xlsm(先週作成)とエクセル150.xlsm(昨日作成)と
エクセル200.xlsm(今日作成)では異なった値です。

引用:
エクセル1.xlsmでグラフ作成、コピーしてエクセル2.xlsmを作成、開いて編集

・ユーザーが実際に使用しているのは、上記のマクロ有効ブックを
 テンプレートとして複製されたブック(レプリカ)である。
 したがって、[データシート]と[パラメータシート]上のデータ、
 および[グラフシート]上の 4 つのグラフにプロットされる範囲は
 それぞれのレプリカごとに異なる。
 また、[データシート]上の一部のセルの値や[グラフシート]上の
 グラフの書式が、ユーザーの手によって改変されている可能性がある。
 
引用:
数百あるロットをほぼ同じような見た目でまとめようとしている

引用:
まとめ作業が進むにつれて適時入る、フォントサイズの変更や
軸名称の修正、表示系列の増減の指示に対応するために、ご推察の通り、
統一するマクロを実行しようとしています。

・ユーザーによって編集された複数個のレプリカ(のコピー)を
 1 つのフォルダ上に保存し、フォルダ内のブックを 1 つずつ開いて
 それぞれの[グラフシート]上のグラフの書式を統一するマクロを
 実行しようとしてる。
 
概ねこんな感じのことをなさろうとしているのだと仮定します。
 
引用:
With .PlotArea
 .Top = エリア(1)(1)

引用:
wsグラフシートがアクティブなだけではエラーが出て、一度
グラフを描画済みの状態(グレーアウト+アイコンではない状態)にすれば
エラーは出なくなります。逆に、一度描画してしまっていれば、
wsグラフシートが非アクティブでもエラーは出ません。

ブックを開かれてから一度もグラフをプロットされていない状態では、
そのプロットエリアの位置やサイズなどの描画に関する情報
( Left / Top / Width / Height )が読み込まれておらず
「未定義」に近い扱いになっているためか、もしくは
Excel によって開始されたグラフのプロット処理と
衝突してしまっているため(恐らく後者)ではないかと推察します。
 
例えばブックを開いた時点で[グラフシート]が非アクティブだったとして、
そのままマクロを実行すれば件の実行時エラーが発生しますが、
同じマクロをもう一度実行すれば実行時エラーが発生することなく
マクロの実行が完了するはず。
 
また、PlotArea の Top / Left / Width / Height プロパティの設定を
後回しにして、先に ChartTitle の設定を行なってやると
実行時エラーが発生しないこともこちらでは確認できました。
 
-------------------------------------------------------------
 
 With グラフ
  .Height = 324
  .Width = 556
  With .Chart
   .ChartTitle.Top = .ChartTitle.Top
   With .PlotArea
    .Top = エリア(1)(1)
 
-------------------------------------------------------------

投稿日時: 23/08/03 15:34:51
投稿者: ひろと

Suzuさん、skさん
 
コメントありがとうございます。
 
.ChartTitle.Top = .ChartTitle.Top
をかますことでエラーが出なくなる理由は私には分からないのですが、この方法でやってみようと思います。
 
大変ありがとうございました。