環境は、
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
---------------------------
追記:
エラーになるのは、
.Axes(xlCategory, xlSecondary).HasTitle = False
の箇所です。
いくつか検索したのですが、
質問している人はいてもなかなか答えがみつかりませんでした。
どうぞよろしくお願いいたします。
まず、マクロ自体が動作するかどうかを、Excelだけで確認してください。
マクロは動作するけれど、VBに移植した時に失敗するのであれば、
移植したコードに問題がある可能性があります。
確認のため、VB側を「Option Explicitあり、参照設定無し」の状態に
しておき(定数等は個別にConstで定義する)、それで動作するかどうかを
確認してください。この時点でコンパイルエラーになるようであれば、
移植したコードに問題がある事になります。
レスありがとうございます。
VBAを起動することなく、
マクロの記録で作成したものをマクロ実行するとエラーになるのです。
つまりマクロ自体が動作していません。
> 定数等は個別にConstで定義する
xlSecondaryを2にしてみましたが、変化がありませんでした。
> Option Explicitありにする
変化がありませんでした。
> 参照設定無しにする
ツール→参照設定 でチェックを外すということでしょうか?
Visual Basic For Applications
Microsoft Exel9.0 Object Library
のみ「使用中のコントロールまたは参照を削除することはできません」
となりチェックを外せなかったのですが、
その他のチェックは全て外してみて、変化がありませんでした。
私がしたいことは、
・Y軸の異なる2つのデータを折れ線グラフで1つの表にまとめたい
ということなので、もし他の方法があれば
お願いいたします。
http://www2.gol.com/users/digitaku/01graph4.gif
のようなものです。
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
修正案ありがとうございます。
上記のDrawGraph2()を実行したところ
以前と同様に
.Axes(xlCategory, xlSecondary).HasTitle = False
のところで
「実行時エラー '1004'
'Axes'メソッドは失敗しました:'_Chart'オブジェクト」
となってしまいました。
何かあらかじめ参照設定とかで追加しておくものとかが、
あるのでしょうか?
DrawGraph()、DrawGraph2() どちらも
Range("A1:B18").Select
を関数の先頭に挿入することで解決いたしました。
ありがとうございます。
ところで、
これを挿入して解決するということはどういうことなのでしょうか?
例えば沢山ある列から適当な2つを選んでグラフを表示するとかいった場合、
どこをSelectすればいいのかなどを考えるとき困りそうなので。。。
A列とC列にデータがある場合
"A1:B18"
を
"A1:A18,C1:C18"
に変えればできました。
どうもありがとうございます。
本質的にはよくわからないのですが、
解決です。
申し訳ありません。
追加で質問させてください。
全く同じソースをアドインで作成しているソースにコピーしたら、
また、同じエラーが起きるようになってしまいました。
何故でしょうか?
ご教授願います。
> 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メソッドに相当する効果があります。
> 全く同じソースをアドインで作成しているソースにコピーしたら、
> また、同じエラーが起きるようになってしまいました。
「現在選択されているオブジェクト」は、逐次変化しますので、
どのオブジェクトを処理しているのかは、明確に指定した方が安全です。
(アドイン等で使うときは、なおさらです)
例えば、チャートが選択されていないときは、
ActiveChart
は無効(Nothing状態)となりますし、逆にチャートが選択されている時は、
Range("A1:B18")
などは無効となります。
ブック上に埋め込まれたマクロの時は、ある程度曖昧な表現でも
動作してくれますが、VB等から制御する場合は、マクロの自動記録で
作成されるような曖昧なコードだと、どのオブジェクトが選択されて
いるかによって、動作が異なってしまう(エラーになる)可能性が
高くなるので、注意が必要です。
# なお、相変わらず xlSecondary の行で失敗しているのであれば、
# エラーになった時に、それが「2軸系のグラフ」になっているかを
# 確認してみてください。
アドインの方でエラーが起きる件です。
アドインとそうでないものには、
参照設定に違いがありました。
アドインではない方は
Microsoft Forms 2.0 Object Library
にチェックがなく、
逆にアドインの方は、チェックがついています。
アドインではない方でこのチェックをつけるとエラーになりました。
しかし、このチェックを外そうとすると
「使用中のコントロールまたは参照を削除することができません。」
となりチェックが外せなくなってしまいました。
これが、原因なのでしょうか?
詳細を記述します。
アドインの方でもそうでない方もソースは全く同じです。
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
> 逆にアドインの方は、チェックがついています。
> アドインではない方でこのチェックをつけるとエラーになりました。
すいません、。
勘違いでした。
アドインではない方に
Microsoft Forms 2.0 Object Library
のチェックをつけても動きました。
> 逆にアドインの方は、チェックがついています。
> アドインではない方でこのチェックをつけるとエラーになりました。
すいません、。
勘違いでした。
アドインではない方に
Microsoft Forms 2.0 Object Library
のチェックをつけても動きました。
Option Explicit を有効にしていますか?
> アドインの方でもそうでない方もソースは全く同じです。
それはまずいでしょう。
Excel製のアドイン(*.xla)なのか、VB製のアドイン(*.dll)なのかは
わかりませんが、VBにもExcel VBAにも、「Sheet1」という固有オブジェクトは
ありませんので、アドインがコンパイルエラーになるような気がします。
(Option Explicitが無い時は、実行時にエラーになると思います)
VBEオブジェクトもしくは、Excel.Applicationオブジェクトから、
処理対象のワークブックを取得し(Workbooksコレクション等)、
そのWorksheetsコレクション(またはSheetsコレクション)経由で
対象のワークシートを指定するようにしてみてください。
ありがとうございます。
下記のようにしてみましたが、変化なく、エラーでした。
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
を削除してみたら動きました。
魔界の仮面弁士様ありがとうございました。
ちなみに
> Option Explicit を有効にしていますか?
有効にしています。が、
>「Sheet1」という固有オブジェクトは
> ありませんので、アドインがコンパイルエラーになるような気がします。
> (Option Explicitが無い時は、実行時にエラーになると思います)
コンパイルエラーにはなっていませんでした。
> Excel製のアドイン(*.xla)なのか、VB製のアドイン(*.dll)なのかは
> わかりませんが、VBにもExcel VBAにも、
Excel製のアドインで作成しています。
> ThisWorkbook.Activate
これだと、「アドインブック」をアクティブにしてしまう事になりますよね。
> Excel製のアドインで作成しています。
そうしますと、一番最初の発言に書かれている『VB6.0』というのは、
一体どの部分で利用されているのでしょうか?
> コンパイルエラーにはなっていませんでした。
という事は、そのアドイン(*.xla)ファイル上に、
「Sheet1という名前のワークシート」が存在しているので、
エラーになっていないのだと思われます。
その場合、
> Set myChartObject = Sheet1.ChartObjects.Add(160, 80, 320, 200)
だと、『処理対象のワークブック上のSheet1』ではなく、
『アドインブック上に存在するSheet1』が処理されますよね。
> > Excel製のアドインで作成しています。
> そうしますと、一番最初の発言に書かれている『VB6.0』というのは、
> 一体どの部分で利用されているのでしょうか?
エクセルでVBAを開いて、ヘルプのバージョン情報を見て書きました。
あぁ! なるほど、そっちの意味でしたか。了解です。
この場合の「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
申し訳ないです。
了解いたしました。
ツイート | ![]() |