VBAで2 軸上の折れ線グラフを作成するには?

解決


はち  2004-03-09 01:29:21  No: 82461

環境は、
Win2000  エクセル2000  VB6.0
です。

概要:
2 軸上の折れ線グラフをVBAで作成したい。
マクロの記録で作成したものを流用しようとしたら実行できなかった。

詳細:
下記の表データをエクセルでに記入し、
2 軸上の折れ線グラフを作成しました。
それをマクロに記録したものが下記のマクロ(DrawGraph())です。

これをそのまま実行すると
「実行時エラー '1004'
  'Axes'メソッドは失敗しました:'_Chart'オブジェクト」
と表示され、実行できません。
作成したマクロは一切いじっていません。
何故でしょうか?
どなたかご教授願います。

マクロ:
---------------------------
Sub DrawGraph()
    Charts.Add
    ActiveChart.ApplyCustomType ChartType:=xlBuiltIn, TypeName:="2 軸上の折れ線"
    ActiveChart.SetSourceData Source:=Sheets("Sheet1").Range("A1:B18"), PlotBy _
        :=xlColumns
    ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet1"
    With ActiveChart
        .HasTitle = False
        .Axes(xlCategory, xlPrimary).HasTitle = False
        .Axes(xlValue, xlPrimary).HasTitle = False
        .Axes(xlCategory, xlSecondary).HasTitle = False
        .Axes(xlValue, xlSecondary).HasTitle = False
    End With
End Sub
---------------------------

表のデータ:
---------------------------
AAA BBB
999  17
600  27
386  34
330  39
315  45
310  50
305  55
300  60
300  65
300  70
300  75
300  80
300  85
300  91
260  95
200  98
100 100
---------------------------


はち  2004-03-09 01:31:27  No: 82462

追記:

エラーになるのは、
.Axes(xlCategory, xlSecondary).HasTitle = False
の箇所です。

いくつか検索したのですが、
質問している人はいてもなかなか答えがみつかりませんでした。
どうぞよろしくお願いいたします。


魔界の仮面弁士  2004-03-09 01:54:39  No: 82463

まず、マクロ自体が動作するかどうかを、Excelだけで確認してください。

マクロは動作するけれど、VBに移植した時に失敗するのであれば、
移植したコードに問題がある可能性があります。

確認のため、VB側を「Option Explicitあり、参照設定無し」の状態に
しておき(定数等は個別にConstで定義する)、それで動作するかどうかを
確認してください。この時点でコンパイルエラーになるようであれば、
移植したコードに問題がある事になります。


はち  2004-03-09 01:58:29  No: 82464

レスありがとうございます。

VBAを起動することなく、
マクロの記録で作成したものをマクロ実行するとエラーになるのです。
つまりマクロ自体が動作していません。


はち  2004-03-09 03:04:34  No: 82465

> 定数等は個別にConstで定義する
xlSecondaryを2にしてみましたが、変化がありませんでした。
> Option Explicitありにする
変化がありませんでした。
> 参照設定無しにする
ツール→参照設定  でチェックを外すということでしょうか?
  Visual Basic For Applications
  Microsoft Exel9.0 Object Library
のみ「使用中のコントロールまたは参照を削除することはできません」
となりチェックを外せなかったのですが、
その他のチェックは全て外してみて、変化がありませんでした。


はち  2004-03-09 03:11:12  No: 82466

私がしたいことは、
・Y軸の異なる2つのデータを折れ線グラフで1つの表にまとめたい
ということなので、もし他の方法があれば
お願いいたします。

http://www2.gol.com/users/digitaku/01graph4.gif
のようなものです。


魔界の仮面弁士  2004-03-09 04:59:16  No: 82467

VB6は関係なく、マクロ自体に問題がある、という事ですね。

この場合は、マクロの最初に、
    Range("A1:B18").Select
を挿入しておいてください。これで、マクロ実行も通ると思います。

ただ、マクロで自動記録される内容は、変数が使えない分、
Active系/Select系に頼ったコードになるため、曖昧(そして冗長的)に
なりがちなので、後から、コードに手を加えた方が良いでしょう。

[Active系に頼らない修正案]

Public Sub DrawGraph2()
    Dim myChartObject As Excel.ChartObject

    Set myChartObject = Sheet1.ChartObjects.Add(200, 100, 400, 250)
    myChartObject.Name = "NewChart01"   '初期値のままでもOK

    With myChartObject.Chart
        'チャートを設定する前には、あらかじめデータをセットしておく必要があります。
        .SetSourceData Sheet1.Range("A1:B18"), xlColumns

        .ApplyCustomType xlBuiltIn, "2 軸上の折れ線"
        .HasTitle = False
        
        .Axes(xlCategory, xlPrimary).HasTitle = False
        .Axes(xlValue, xlPrimary).HasTitle = False
        .Axes(xlCategory, xlSecondary).HasTitle = False
        .Axes(xlValue, xlSecondary).HasTitle = False
    End With
    Set myChartObject = Nothing
End Sub


はち  2004-03-09 19:01:10  No: 82468

修正案ありがとうございます。

上記のDrawGraph2()を実行したところ
以前と同様に
  .Axes(xlCategory, xlSecondary).HasTitle = False
のところで
「実行時エラー '1004'
  'Axes'メソッドは失敗しました:'_Chart'オブジェクト」
となってしまいました。

何かあらかじめ参照設定とかで追加しておくものとかが、
あるのでしょうか?


はち  2004-03-09 19:32:33  No: 82469

DrawGraph()、DrawGraph2()  どちらも
  Range("A1:B18").Select
を関数の先頭に挿入することで解決いたしました。
ありがとうございます。

ところで、
これを挿入して解決するということはどういうことなのでしょうか?
例えば沢山ある列から適当な2つを選んでグラフを表示するとかいった場合、
どこをSelectすればいいのかなどを考えるとき困りそうなので。。。


はち  2004-03-09 19:50:06  No: 82470

A列とC列にデータがある場合
  "A1:B18"

  "A1:A18,C1:C18"
に変えればできました。

どうもありがとうございます。
本質的にはよくわからないのですが、
解決です。


はち  2004-03-09 20:01:46  No: 82471

申し訳ありません。
追加で質問させてください。

全く同じソースをアドインで作成しているソースにコピーしたら、
また、同じエラーが起きるようになってしまいました。
何故でしょうか?
ご教授願います。


魔界の仮面弁士  2004-03-09 20:03:30  No: 82472

> Range("A1:B18").Select
これを使う場合は、どのシート上の範囲かを明示するために、
    ThisWorkbook.Activate
    Sheet1.Activate
    Sheet1.Range("A1:B18").Select
などと書いた方が安全かもしれませんね。

# 個人的には、フォーカスの移動を逐一行うと、その分、処理が遅くなるので
# Active/Select系メソッドは、極力、利用しないようにしています。

>  'Axes'メソッドは失敗しました:'_Chart'オブジェクト」
> となってしまいました。

ふぅむ。環境の差異でしょうか。

こちらの環境(Excel 2000)では、DrawGraph2 のように、
SetSourceData → ApplyCustomType の順で設定すれば、
エラーにならなかったのですけれどね…。
(Sheet2がアクティブな状態であっても、Sheet1上にチャートが作成されました)

なお、『.Axes(…, xlSecondary)』が失敗するのは、そのチャートが
2軸のグラフになっていない事を意味しています。1軸のみのグラフの場合、
xlPrimary軸 は存在しますが、xlSecondary軸が存在しないためです。

> これを挿入して解決するということはどういうことなのでしょうか?
1行ずつ「ステップ実行」するとわかりやすいかと思いますが、単に、

    Charts.Add

と書いた場合、空白のグラフシートが作成される事になります。しかし、

    Range("A1:B18").Select
    Charts.Add

とした場合、「A1:B18 のデータを使った棒グラフのシート」が生成されます。
つまり、SetSourceDataメソッドに相当する効果があります。


魔界の仮面弁士  2004-03-09 20:23:20  No: 82473

> 全く同じソースをアドインで作成しているソースにコピーしたら、
> また、同じエラーが起きるようになってしまいました。

「現在選択されているオブジェクト」は、逐次変化しますので、
どのオブジェクトを処理しているのかは、明確に指定した方が安全です。
(アドイン等で使うときは、なおさらです)

例えば、チャートが選択されていないときは、
  ActiveChart
は無効(Nothing状態)となりますし、逆にチャートが選択されている時は、
  Range("A1:B18")
などは無効となります。

ブック上に埋め込まれたマクロの時は、ある程度曖昧な表現でも
動作してくれますが、VB等から制御する場合は、マクロの自動記録で
作成されるような曖昧なコードだと、どのオブジェクトが選択されて
いるかによって、動作が異なってしまう(エラーになる)可能性が
高くなるので、注意が必要です。

# なお、相変わらず xlSecondary の行で失敗しているのであれば、
# エラーになった時に、それが「2軸系のグラフ」になっているかを
# 確認してみてください。


はち  2004-03-09 20:28:13  No: 82474

アドインの方でエラーが起きる件です。

アドインとそうでないものには、
参照設定に違いがありました。

アドインではない方は
  Microsoft Forms 2.0 Object Library
にチェックがなく、
逆にアドインの方は、チェックがついています。
アドインではない方でこのチェックをつけるとエラーになりました。

しかし、このチェックを外そうとすると
「使用中のコントロールまたは参照を削除することができません。」
となりチェックが外せなくなってしまいました。

これが、原因なのでしょうか?


はち  2004-03-09 20:40:41  No: 82475

詳細を記述します。

アドインの方でもそうでない方もソースは全く同じです。
Step実行したときに
  Set myChartObject = Sheet1.ChartObjects.Add(160, 80, 320, 200)
  ↑ここで空のグラフシートが作成されません。
それゆえに
  .SetSourceData Sheet1.Range(sRange), xlColumns
でも何も起こらずに
その後、エラーになっているのだと思います。

Public Sub DrawGraph2()
    Dim myChartObject As Excel.ChartObject
    Dim sRange As String
    sRange = "A1:A18,C1:C18"
    Range(sRange).Select
    
    Set myChartObject = Sheet1.ChartObjects.Add(160, 80, 320, 200)
    myChartObject.Name = "NewChart01"   '初期値のままでもOK

    With myChartObject.Chart
        'チャートを設定する前には、あらかじめデータをセットしておく必要があります。
        .SetSourceData Sheet1.Range(sRange), xlColumns
        .ApplyCustomType xlBuiltIn, "2 軸上の折れ線"
        .HasTitle = False
        
        .Axes(xlCategory, xlPrimary).HasTitle = False
        .Axes(xlValue, xlPrimary).HasTitle = False
        .Axes(xlCategory, xlSecondary).HasTitle = False
        .Axes(xlValue, xlSecondary).HasTitle = False
    End With
    Set myChartObject = Nothing
End Sub


はち  2004-03-09 20:48:12  No: 82476

> 逆にアドインの方は、チェックがついています。
> アドインではない方でこのチェックをつけるとエラーになりました。
すいません、。
勘違いでした。
アドインではない方に
  Microsoft Forms 2.0 Object Library
のチェックをつけても動きました。


はち  2004-03-09 20:48:15  No: 82477

> 逆にアドインの方は、チェックがついています。
> アドインではない方でこのチェックをつけるとエラーになりました。
すいません、。
勘違いでした。
アドインではない方に
  Microsoft Forms 2.0 Object Library
のチェックをつけても動きました。


魔界の仮面弁士  2004-03-09 21:09:27  No: 82478

Option Explicit を有効にしていますか?

> アドインの方でもそうでない方もソースは全く同じです。
それはまずいでしょう。

Excel製のアドイン(*.xla)なのか、VB製のアドイン(*.dll)なのかは
わかりませんが、VBにもExcel VBAにも、「Sheet1」という固有オブジェクトは
ありませんので、アドインがコンパイルエラーになるような気がします。
(Option Explicitが無い時は、実行時にエラーになると思います)

VBEオブジェクトもしくは、Excel.Applicationオブジェクトから、
処理対象のワークブックを取得し(Workbooksコレクション等)、
そのWorksheetsコレクション(またはSheetsコレクション)経由で
対象のワークシートを指定するようにしてみてください。


はち  2004-03-09 21:12:45  No: 82479

ありがとうございます。

下記のようにしてみましたが、変化なく、エラーでした。

Public Sub DrawGraph2()
    Dim myChartObject As Excel.ChartObject
    Dim sRange As String
    sRange = "A1:A18,C1:C18"
    
    ThisWorkbook.Activate
    ActiveSheet.Range(sRange).Select
    
    Set myChartObject = ActiveSheet.ChartObjects.Add(160, 80, 320, 200)
    myChartObject.Name = "NewChart01"   '初期値のままでもOK

    With myChartObject.Chart
        'チャートを設定する前には、あらかじめデータをセットしておく必要があります。
        .SetSourceData ActiveSheet.Range(sRange), xlColumns

        .ApplyCustomType xlBuiltIn, "2 軸上の折れ線"
        .HasTitle = False
        
        .Axes(xlCategory, xlPrimary).HasTitle = False
        .Axes(xlValue, xlPrimary).HasTitle = False
        .Axes(xlCategory, xlSecondary).HasTitle = False
        .Axes(xlValue, xlSecondary).HasTitle = False
    End With
    Set myChartObject = Nothing
End Sub

しかし、
    ThisWorkbook.Activate
    ActiveSheet.Range(sRange).Select
を削除してみたら動きました。

魔界の仮面弁士様ありがとうございました。


はち  2004-03-09 21:14:55  No: 82480

ちなみに
> Option Explicit を有効にしていますか?
有効にしています。が、
>「Sheet1」という固有オブジェクトは
> ありませんので、アドインがコンパイルエラーになるような気がします。
> (Option Explicitが無い時は、実行時にエラーになると思います)
コンパイルエラーにはなっていませんでした。

> Excel製のアドイン(*.xla)なのか、VB製のアドイン(*.dll)なのかは
> わかりませんが、VBにもExcel VBAにも、
Excel製のアドインで作成しています。


魔界の仮面弁士  2004-03-09 21:27:01  No: 82481

>    ThisWorkbook.Activate
これだと、「アドインブック」をアクティブにしてしまう事になりますよね。

> Excel製のアドインで作成しています。
そうしますと、一番最初の発言に書かれている『VB6.0』というのは、
一体どの部分で利用されているのでしょうか?

> コンパイルエラーにはなっていませんでした。
という事は、そのアドイン(*.xla)ファイル上に、
「Sheet1という名前のワークシート」が存在しているので、
エラーになっていないのだと思われます。

その場合、
>   Set myChartObject = Sheet1.ChartObjects.Add(160, 80, 320, 200)
だと、『処理対象のワークブック上のSheet1』ではなく、
『アドインブック上に存在するSheet1』が処理されますよね。


はち  2004-03-09 22:04:26  No: 82482

> > Excel製のアドインで作成しています。
> そうしますと、一番最初の発言に書かれている『VB6.0』というのは、
> 一体どの部分で利用されているのでしょうか?
エクセルでVBAを開いて、ヘルプのバージョン情報を見て書きました。


魔界の仮面弁士  2004-03-09 22:42:26  No: 82483

あぁ! なるほど、そっちの意味でしたか。了解です。

この場合の「Visual Basic 6.0」というのは、
製品名の事ではなく、言語名の事だったのですね。
(あのバージョンダイアログの表記は、実に紛らわしいですね…)

ExcelなどのVBAに関する質問に関しては、「VB6」などは記述せず、
単に「VBA」とだけ説明される事を、強くお奨めします。
もし、バージョンも明記するのであれば、言語バージョンではなく、製品名
(Excel 2002、Excel 2003など)を書いた方が、誤解されにくいと思います。

VBAではなく、VB6、VB6.0などと書いた場合は、一般的には、
「製品名としてのVisual Basic 6.0シリーズ」の事を意味しますので、
全く別の物として受け取られてしまう可能性が高いです。

# 実際過去にも、Excel VBAを "VB6" と表記して質問したために、
# 回答者と質問者の間で、すれ違いが起こった事がありますので…。
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200401/04010111.txt


はち  2004-03-10 00:52:08  No: 82484

申し訳ないです。
了解いたしました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加