|
▼初投稿 さん:
ぼくも佳さん同様、簡単な表を作って
ご提示のコードのまえに
Dim c As Long
Dim s As Long
Dim t As Long
With ActiveSheet
s = .Cells(1, .Columns.Count).End(xlToLeft).Column
t = .Cells(.Rows.Count, 1).End(xlUp).Row
End With
を挿入して、実行してみましたが
見かけ上問題なくグラフは作成されました。
> コードの5行目の部分がうまくいきません。
>Unionの上位オブジェクトがおかしいのではないかと思っていますが、
>直しても書き方が悪いのかうまくいかずお手上げです。
ということですけど、どんな不具合でしょうか?
コードを拝見させていただいて
すごく気になるのは
(1) 問題の5行目で
> Union(Range(Cells(2, 1), Cells(t, 1)), Range(Cells(2, c), Cells(t, c)))
と、Rangeや Cells の親シートの指定がないこと
(2) グラフの枠(ChartObject)を作成してそれを Select している
ことです。
そして、 (1),(2)は関連しあってます。
さきほど
> グラフの枠(ChartObject)
という表現を使いましたが、
> ActiveSheet.ChartObjects.Add(100, 50 + (c - 2) * 220, 400, 200).Select
で、ChartObject を Selectすると、ChartObject自体はアクティブにならず、
ChartObjectの下位にある Chart がアクティブになるのです。
これって紛らわしいですけど、実際のことなのです。
それが証拠に、
> ActiveChart.ChartType = xlXYScatter
って アクティブなグラフ(ActiveChart)を表現しています。
ChartObjectを選択したら Chartがアクティブになっているのです。
そのことと Range Cells の親を省略していることがどう関係してくるのか
というと、
Range Cells の前のシートを省略していて(かつ、このコードが標準モジュール)
に書いてあるばあい、「ActiveSheetが自動で補われる」というしくみが
あります。
そのため
(今回は問題なく実行できているようですけど、)
グラフがアクティブになっているときには、
ActiveSheet は ActiveChart がその実態となるので、Range("A1") と
シートを省略すると ActiveChart.Range("A1") と解釈され、Application
または Object定義のエラー となることがよくあります。
この問題を解決するには
(a)グラフをつくるとき、いちいちそれをSelectしない。(ActiveChartを
使ったコードを書かない)
(b)グラフを作成するまえに グラフの元データ範囲を Range型の変数に収めて
おいて、グラフの SetSourceData の引数には この変数のほうを使って範囲
を渡す。
などの配慮が必要です。
Sub exam1() '--- ChartObject.Select ActiveChart を用いない例
Dim i As Long
Dim s As Long
Dim t As Long
Dim Cht As Chart
'列はs、行はt
With ActiveSheet
s = .Cells(1, .Columns.Count).End(xlToLeft).Column
t = .Cells(.Rows.Count, 1).End(xlUp).Row
For i = 2 To s
Set Cht = .ChartObjects.Add( _
100, 50 + (i - 2) * 220, 400, 200).Chart
Cht.ChartType = xlXYScatter
Cht.SetSourceData _
Source:=Union(.Range(.Cells(2, 1), .Cells(t, 1)), _
.Range(.Cells(2, i), .Cells(t, i)))
Next i
End With
End Sub
Sub exam2() '--- 元データ範囲を変数に格納して利用する例
Dim i As Long
Dim r As Range
Dim rngX As Range
With ActiveSheet
Set r = .Range("A1").CurrentRegion
Set r = Intersect(r, r.Offset(1)) '1行目を除外
Set rngX = r.Columns(1)
For i = 2 To r.Columns.Count
With .ChartObjects.Add( _
100, 50 + (i - 2) * 220, 400, 200).Chart
.ChartType = xlXYScatter
.SetSourceData Union(rngX, r.Columns(i))
End With
Next i
End With
End Sub
Sub exam2() は
A B C D E F
1 □□□□□□
2 □□□□□□
3 □□□□□□
4 □□□□□□
5 □□□□□□
6 □□□□□□
という表があるとき、
>Set r = .Range("A1").CurrentRegion
で上記表範囲[A1:F6] をセットしてすぐ
> Set r = Intersect(r, r.Offset(1))
で1行目を除外した範囲を 変数rに再セットしています(↓ ■印)。
A B C D E F
1 □ □□□□□
2 ■ ■■■■■
3 ■ ■■■■■
4 ■ ■■■■■
5 ■ ■■■■■
6 ■ ■■■■■
↓ 2 3 4 5 6 →r.Columns(2) 〜 r.Columns(6)
rngX
元データ範囲 Union(rngX, r.Columns(i)
|
|