プロが教えるわが家の防犯対策術!

VBAについての質問です。初心者でいろいろ調べているのですが行き詰まりました。ご指導お願いします。
表を入力して、
系列数 3
要素 入力ごとに増加
各系列毎にフォントを変える
ラベルはまた別のセルの値

という散布図をVBAで作成したいとおもっております。

Dim sc1, sc2, sc3 As Series
Set sc1 = ActiveSheet.ChartObjects(1).Chart.SeriesCollection(1)
Set sc2 = ActiveSheet.ChartObjects(1).Chart.SeriesCollection(2)
Set sc3 = ActiveSheet.ChartObjects(1).Chart.SeriesCollection(3)

と変数を設定して、「あるセルの値が○○だったら系列1(sc1)として取得しグラフに表示する」というコードを書きたいのですが、

Dim last As Integer
last = Range("C2").End(xlDown).Row
Dim 行番号 As Integer
行番号 = 2
Do While Range("C" & 行番号).Value <> ""
Select Case Range("C" & 行番号).Value
Case Is = ○○

のあとがどうにもわかりません。
何か良い方法はございますでしょうか?

質問者からの補足コメント

  • ご回答ありがとうございます。説明不足でした、すみません。

    グラフはすでに存在しているのですか?
    →出来ればエクセルにあるのは表だけ、というところからVBAでグラフから作りたいと考えてます。

    散布図では、Xの値とYの値があります。
    データはC列のみにあるのですか?
    そこからXの値とYの値を抽出するのですか?
    →データは「Xの値のデータ」と「Yの値のデータ」の2列が他にあります。

    さらに系列分けもするのですか?
    →「場所」という系列で各場所にそれぞれX,Yとなる要素があるイメージです。

    はたしてC列にはどんなデータが入力されているのでしょうか?
    →今回は「場所」が入力されていると想定してます

    場所やX,Yが増えても、表のほうに打ち込めばそれに応じて所定のグラフ(今回は散布図)を作ってくれるようなVBAが組みたいと考えておりました。

    参考サイト、ありがとうございますm(_ _)m

    No.1の回答に寄せられた補足コメントです。 補足日時:2015/08/18 18:18
  • C列の場所には3つ地点名が~
    →3地点=3系列です。ランダムに表れる各地点ごとにE列F列のデータを整理したいのです(同種類の地点は同系列として)。

    Xの値、Yの値が2行になっていますがこれはどういうことでしょうか?
    地点名データとの整合性はどうなっていますか?
    →これはマクロを記録する際に手動でやったせいかと思われます。1行でX,Y値を指定できるのであればそうしたいです。

    なるほど参照式を使えば指定できるのですね。Offsetプロパティを使えば、「その要素データが入力されている○列隣のセルの値をラベルにする」とかもできそうですね。
    丁寧にありがとうございます。本当に助かります。

    No.3の回答に寄せられた補足コメントです。 補足日時:2015/08/21 01:19

A 回答 (5件)

>No.4 この回答へのお礼



>前半部で、セル入力に応じて変数を設定し、後半部でそれぞれの変数にセルの値を代入する、という構成なのですね。
前半で
C列の値に応じて3系列のデータセル範囲(名前、Xの値、Yの値)を抽出取得
後半で
散布図を描画

実際には、データ収集部とグラフ描画部を
別々に記述してサブプロシージャ化する方が良いかもしれません。
専門家ではないのでそこら辺の事は不案内です。

>.Name = "=" & stname & "!" & rngn1.Address
>部分でエラー 91で処理が止まってしまいました。
実際のシート名はどうなっていますか?
シート名によってはその前後を「’」で囲む必要があります。
.name = "='" & stname & "'!" & rngn1.address
で試してみてください。

>これは前半部のElseの部分でrngn1を指定していないからでしょうか。
系列名は1度設定すれば固定で大丈夫な筈です。

No.4で提示したコードは
飽くまでも意図したグラフが作成できるかの確認用です。

グラフは最初に一度描画すれば大丈夫な筈です。
逐次入力されるデータを
グラフ用の表に抽出整形するコード(関数でできるならそちらでも可)
グラフを掴まえてデータ範囲を書き換えるコード
にすれば良いのではないでしょうか。
それにはワークシートのイベントプロシージャを使えば良いと思います。
<参考>
イベントプロシージャを活用しよう!
http://home.att.ne.jp/zeta/gen/excel/c04p59.htm
    • good
    • 0

とりあえず下記のようなコードを書いてみました。


これを参考にしてグラフが描けるかどうか試してください。
解った範囲で現状に合わせたつもりです。

繰り返しますが
別場所にグラフ用に整形したデータ表を書き出した方が良いと思います。

Dim stname As String
Dim rng As Range, c As Range
Dim rngn1 As Range, rngn2 As Range, rngn3 As Range
Dim rngx1 As Range, rngx2 As Range, rngx3 As Range
Dim rngy1 As Range, rngy2 As Range, rngy3 As Range
Dim ser As Series
Dim i As Integer

stname = ActiveSheet.name
Set rng = Range("C2:C10")
For Each c In rng
Select Case c.Value
Case "A"
If rngx1 Is Nothing Then
Set rngn1 = c
Set rngx1 = Cells(c.Row, "E")
Set rngy1 = Cells(c.Row, "F")
Else
Set rngx1 = Union(rngx1, Cells(c.Row, "E"))
Set rngy1 = Union(rngy1, Cells(c.Row, "F"))
End If
Case "B"
If rngx2 Is Nothing Then
Set rngn2 = c
Set rngx2 = Cells(c.Row, "E")
Set rngy2 = Cells(c.Row, "F")
Else
Set rngx2 = Union(rngx2, Cells(c.Row, "E"))
Set rngy2 = Union(rngy2, Cells(c.Row, "F"))
End If
Case "C"
If rngx3 Is Nothing Then
Set rngn3 = c
Set rngx3 = Cells(c.Row, "E")
Set rngy3 = Cells(c.Row, "F")
Else
Set rngx3 = Union(rngx3, Cells(c.Row, "E"))
Set rngy3 = Union(rngy3, Cells(c.Row, "F"))
End If
End Select
Next

With Sheets(stname).Shapes.AddChart.Chart
.ChartType = xlXYScatter
For Each ser In .SeriesCollection
ser.Delete
Next
For i = 1 To 3
With .SeriesCollection.NewSeries
If i = 1 Then
.name = "=" & stname & "!" & rngn1.address
.XValues = rngx1
.Values = rngy1
ElseIf i = 2 Then
.name = "=" & stname & "!" & rngn2.address
.XValues = rngx2
.Values = rngy2
ElseIf i = 3 Then
.name = "=" & stname & "!" & rngn3.address
.XValues = rngx3
.Values = rngy3
End If
End With
Next
End With
    • good
    • 0
この回答へのお礼

ありがとうございます。
前半部で、セル入力に応じて変数を設定し、後半部でそれぞれの変数にセルの値を代入する、という構成なのですね。
実行してみたところ
.Name = "=" & stname & "!" & rngn1.Address
部分でエラー 91で処理が止まってしまいました。
これは前半部のElseの部分でrngn1を指定していないからでしょうか。

確かにおっしゃる通り、入力判定までも、VBA任せにするとかえって繁雑になりそうです。グラフ用データ入力シートを作って型どおりに入力していく、という方法で考えてみたいと思います。
どうもありがとうございました。凄く助かりました!

お礼日時:2015/08/25 11:04

>No.2 この回答へのお礼


C列の場所には3つ地点名があるということですか?
3地点つまり3系列ということですね?
で、地点ごとにE列F列のデータを整理するということですか?
地点名はデータはランダムに出現するのですか?
それとも規則に則って出現しますか?

離れたデータを同一系列に纏めることは可能です。
しかし、SERIES式(グラフ用の隠し関数です)でセル番地の記述が煩雑になり
文字数だったか何かの制限に引っかかる可能性があります。
私的には別場所にグラフ用に整形したデータを用意した方が良いと思います。

危惧される問題点は置いといて
コードを見ますと
>.SeriesCollection(2).Name = "=""地点B"""
>.SeriesCollection(2).XValues = "='Sheet1'!$E$4:$E$5"
>.SeriesCollection(2).Values = "='Sheet1'!$F$4:$F$5"
というように
Xの値、Yの値が2行になっていますがこれはどういうことでしょうか?
地点名データとの整合性はどうなっていますか?

>最後のデータラベルでは、Yの値ではなく任意のセル・・・・・
参照式を書けばOKです。
With .SeriesCollection(1)
With .Points(1).DataLabel
.Formula = "=Sheet1!B2" '★1
End With
’あるいは
With .Points(2).DataLabel
.text = "=Sheet1!B3" ’★2
End With
End With
この回答への補足あり
    • good
    • 0

>No.1 補足コメント


データ追加時にグラフを再描画するのは賛成できません。
私なら、該当グラフを掴まえてデータ範囲の書き換えを行うようにします。
それで良ければ考えてみます。

しかしながら現状の情報量では手が付けられません。
実データを使ってグラフ作成作業を行い「マクロの記録」して頂けませんか?
得られたコードを提示して頂ければ大概の事がわかると思います。
    • good
    • 0
この回答へのお礼

補足ありがとうございます。
A列にロット、B列に品種、C列に地点、D列に年度、E列に大きさ、F列に割合のデータが入っている状態です。


Sub 質問()
'
' 質問 Macro

ActiveSheet.Shapes.AddChart.Select
With ActiveChart
.ChartType = xlXYScatter
.SetSourceData Source:=Range("E2:F3")
.SeriesCollection.NewSeries
.SeriesCollection(2).Name = "=""地点B"""
.SeriesCollection(2).XValues = "='Sheet1'!$E$4:$E$5"
.SeriesCollection(2).Values = "='Sheet1'!$F$4:$F$5"
.SeriesCollection(1).Name = "=""地点A"""
.ApplyLayout (1)
End With
ActiveSheet.ChartObjects("グラフ 6").Activate
ActiveChart.ChartTitle.Text = "散布図4"
ActiveChart.Axes(xlValue, xlPrimary).AxisTitle.Text = "割合(%)"
ActiveChart.Axes(xlCategory, xlPrimary).AxisTitle.Text = "大きさ(㎜)"
ActiveChart.SeriesCollection(1).ApplyDataLabels
ActiveChart.SeriesCollection(2).ApplyDataLabels
End Sub

最後のデータラベルでは、Yの値ではなく任意のセル(同じ行の別の項目の値)を表示させたいのですがそのやり方はわかりませんでした。手動で数式バーにてそのセルを選択しても、表示はされるもののVBAには反映されませんでした。

系列の地点が増えても対応できるようなVBAを組みたいと考えております。

お礼日時:2015/08/19 12:05

提示された内容からは


妙な事をやっておられるという印象です。
的が絞れません。

グラフはすでに存在しているのですか?
散布図では、Xの値とYの値があります。
データはC列のみにあるのですか?
そこからXの値とYの値を抽出するのですか?
さらに系列分けもするのですか?
はたしてC列にはどんなデータが入力されているのでしょうか?

取りあえず気になる処を指摘してみます。

>Dim sc1, sc2, sc3 As Series
多分、sc1, sc2, sc3 共にSeries型で宣言されている積りだと思います。
VBAでは変数の型は個々に記述します。
省略した場合は自動的にVariantになります。
提示例では
sc1とsc2はVariant
sc3はSeries
ということになります。

>Dim last As Integer
>last = Range("C2").End(xlDown).Row
最近のExcelでは行数が大幅に増えています。
場合によってはInteger型ではオーバーフローする恐れがあります。

Select Case 文の書き方に焦点を絞るなら
Web検索すれば参考サイトがたくさんヒットします。
<参考>
Select Caseステートメント
http://officetanaka.net/excel/vba/statement/Sele …
この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!