エクセルでグラフを作る際に、まず面倒くさいのはデータの選択ではないでしょうか?
もちろん、CtrlやShiftボタンを使えばそれなりに効率的にデータ範囲を選択できますが、グラフが変なところに表示されたり、色々面倒くさい感じがします。どうせグラフの見た目も整えるのであれば、データ選択もマクロでやってしまった方が早いですよね。
どのようにすれば効率的でしょうか?
今回はその1と似ていますが、少し異なるパターンを扱います。
X軸+Y軸のデータが並んでいる
その1との違いがよく分からないかもしれませんが、下図のようなパターンです。

X軸と離れた箇所にわざわざY軸のデータを並べるか?と思うかもしれませんが、実際によく使うのは、X軸の横にY軸が並んでいるが、その一部をグラフにしたい場合です。全データを並べるとごちゃごちゃしてしまう場合や、一部の失敗測定データを除外する場合など様々なケースで有り得る使い方だと思います。
このような場合も、X軸の一番上のデータをCtlを押しながら選択、Y軸の一番上のデータをドラックして選択することでグラフにしたいデータの要素を指定できます。

つまり、上記のような状態です。この状態でマクロを実行することで、グラフを作成できれば便利ではないでしょうか?実際にコードを作成してみます。
実際のマクロコード
いつも通り、まずはコードを示します。
Sub DataSelect4()
Dim cn As Long
Dim Rng As Variant
Dim Rng_X As Range
Dim Rng_Y As Range
Dim graph As Chart
'選択部分のアドレスを取得
Rng = Split(Selection.Cells.Address(False, False), ",")
'X軸を取得
Set Rng_X = Range(Selection, Selection.End(xlDown))
Range(Rng(1)).Select
cn = Selection.Cells.Columns.Count 'Y軸データの列数を取得
'Y軸の1列目を取得
Range(Left(Rng(1), 2)).Select 'アドレスから1列目の表記を抜き出す
Set Rng_Y = Range(Selection, Selection.End(xlDown))
'1列目のデータを用いてグラフ作成
Set graph = ActiveSheet.Shapes.AddChart.Chart
With graph
.ChartType = xlXYScatterLinesNoMarkers
'ここでX軸、Y軸のデータを指定
.SetSourceData Range(Rng_X.Address(False, False) + ", " + Rng_Y.Address(False, False))
Graphname = .Parent.Name '作ったグラフの名前を取得
End With
'2列目以降のデータをグラフに追加
For n = 1 To cn - 1
Range(Left(Rng(1), 2)).Offset(0, n).Select
Set Rng_Y = Range(Selection, Selection.End(xlDown))
With ActiveSheet.ChartObjects(Graphname).Chart.SeriesCollection.NewSeries
.XValues = Rng_X
.Values = Rng_Y
End With
Next n
End Sub
選択範囲のアドレスを取得する
その2の時と同様に、まず選択している範囲のアドレスを取得することがポイントです。
Rng = Split(Selection.Cells.Address(False, False), ",")
Selection.Cells.Address(False, False)の部分が、選択した範囲のアドレスを返し、この場合には例えば”A2, E2:G2″というような文字列を返します。Splitを用いて”,”で分割してRngに配列として格納しているので、Rng(0)=”A2″、Rng(1)=”E2:G2”みたいになります。
1列目のデータでグラフ作成
次に最初のデータでグラフの土台(グラフオブジェクト)を作ります。これも前回と同じですね。Y軸のアドレスは”E2:G2″のような表記になっているはずなので、E2の部分のみ抜き出すためにLeft関数を使っています。
Range(Left(Rng(1), 2)).Select 'アドレスから1列目の表記を抜き出す
Set Rng_Y = Range(Selection, Selection.End(xlDown))
グラフの作成やグラフオブジェクトの名前をGraphname = .Parent.Nameで取得している点も前回と同じですが、使うデータの指定方法をRange()の中に文字列を直接入れる形式にしています。
.SetSourceData Range(Rng_X.Address(False, False) + ", " + Rng_Y.Address(False, False))
.SetSourceData Range(Rng_X, RngY)としても同じことのように思いますが、そうするとX軸の列とY軸の列の間の列も選択されてしまいました。色々検討して上記のような形になったのですが、もっとよいやり方があるのかもしれません。目的は果たせたので良しとしました。
残りのデータをプロット
最後は簡単です。Y軸は連続して並んでいるわけですから、Left(Rng(1), 2)の右にcn-1個のY軸データが並んでいるはずです。For文とoffsetを用いてデータ範囲を取得しています。
'2列目以降のデータをグラフに追加
For n = 1 To cn - 1
Range(Left(Rng(1), 2)).Offset(0, n).Select
Set Rng_Y = Range(Selection, Selection.End(xlDown))
With ActiveSheet.ChartObjects(Graphname).Chart.SeriesCollection.NewSeries
.XValues = Rng_X
.Values = Rng_Y
End With
Next n
まとめ
今回は、解析を進めていくと欲しくなってくるデータ選択手法を紹介しました。どんなデータ選択方法があると便利か、それをどう実現するかを考えると面白くなってくると思います。



コメント