• ベストアンサー

エクセルVBAでShapeRangeについて

すみません、教えてください。 以下のマクロは正常に動きます。 Sub TEST() With ActiveSheet For Each s In .Shapes If s.AutoShapeType = msoShape5pointStar Then s.Delete Next .Cells.Interior.ColorIndex = 1 Set AA = .Shapes.AddShape(msoShape5pointStar, 55, 22, 25#, 25#) AA.Fill.Visible = msoTrue AA.Fill.Solid AA.Fill.ForeColor.SchemeColor = 13 AA.Fill.Transparency = 0# AA.line.Weight = 0.75 AA.line.DashStyle = msoLineSolid AA.line.Style = msoLineSingle AA.line.Transparency = 0# AA.line.Visible = msoTrue AA.line.ForeColor.SchemeColor = 64 ' AA.Copy '(1) ' .Paste '(1) ' Set AB = Selection '(1) ' .Range("A1").Select'(1) Set AB = AA.Duplicate '(2) AB.Top = 44 AB.Left = 110 ' AB.ShapeRange.Fill.ForeColor.SchemeColor = 10'(1)の2 AB.Fill.ForeColor.SchemeColor = 10 '(2)の2 End With End Sub ところが、 Set AB = AA.Duplicate '(2)の部分を、コメントアウトしている '(1)の記述に変えると、 AB.Fill.ForeColor.SchemeColor = 10 '(2)の2 の部分も ' AB.ShapeRange.Fill.ForeColor.SchemeColor = 10'(1)の2 に変えないとエラーになります。 ' AA.Copy '(1) ' .Paste '(1) ' Set AB = Selection '(1) も Set AB = AA.Duplicate '(2) も、同じことのように思えるのですが、この違いで、ShapeRangeというのを入れたり消したりしなければならないのはどうしてでしょうか? エクセルは2000です。

質問者が選んだベストアンサー

  • ベストアンサー
  • pauNed
  • ベストアンサー率74% (129/173)
回答No.5

要は、 変数への格納の仕方、 Objectの指定の仕方が違う、 という話です。 Sub try4()   Dim A As Object   Dim B As Object   With ActiveSheet     With .Shapes.AddShape(msoShape5pointStar, 100, 100, 100, 100)       .Duplicate.Select       Set A = Selection 'Duplicateしたもの       .Copy     End With     .Paste     Set B = .Shapes(.Shapes.Count) 'Copyしたもの   End With   MsgBox "A: " & TypeName(A) & vbLf & "B: " & TypeName(B)   Stop      Set A = Nothing   Set B = Nothing End Sub Sub try5()   Dim A As Object      With ActiveSheet     .Shapes.AddShape msoShape5pointStar, 100, 100, 100, 100     Set A = .DrawingObjects(.DrawingObjects.Count)     MsgBox A.ShapeRange.Name   End With   Stop      Set A = Nothing End Sub

merlionXX
質問者

お礼

> 変数への格納の仕方、 > Objectの指定の仕方が違う、 なるほど、同じ物でも Set A = .DrawingObjects(.DrawingObjects.Count) とすれば型はRectangleだし、 Set A = .Shapes(.Shapes.Count) とすれば型はShapeになりますね。 有難うございます。

その他の回答 (5)

回答No.6

今日は暇なのでまた登場。 今回はこれで終わりにしまする。(^^;;; >う~っ、結果としてそうなったShapeの下にShapeRangeが無く、Rectangleの下にはまずShapeRangeがきて、その下にFillがくるという構造になっているということなんでしょうね。わかったようでわからないような・・・・ VBAのプロになるのであればなんですが、 こんな小難しいことは考えなくてもいいのではないのですか? 何回も言ってるように ●選択された図形●を扱う場合は、ShapeRangeコレクションを使う、 と覚えておけばいいと思いますよ。 Selection.ShapeRange.Fill。。。。。。 なお、当方の回答は、あくまでも 質問のタイトルにある、「エクセルVBAでShapeRangeについて」です。   で、今回の質問については当方の回答は終了ということで。  

merlionXX
質問者

お礼

大師さま、何度もお手間を取らせすみませんでした。 ●選択された図形●を扱う場合は、Rectangle型になっているのでShapeRangeコレクションを使う。 選択しなくともRectangle型として変数に入れたオブジェクトもShapeRangeコレクションを使うということですね。 覚えます、有難うございました。

回答No.4

またまた登場、、、(^^;;; >わたしも選択しているか否かのせいではないかと思いました。 >それで .Range("A1").Select'(1) をわざと書き加えたのです。 >これでA1セルが選択されて図形の選択が解除されていますよね? Range("A1").Selectしたら図形選択は当然解除されますが、コードをよく見てください。 1。 AA.Copy 2。 .Paste 3。 Set AB = Selection 4。 .Range("A1").Select 2でコピーされた図形は選択された状態になり、 3でその選択された図形をABへセットしてますから この3で、ShapeRangeコレクションにAddされるわけです その後、4でセル選択して図形選択を解除しても それは画面上で解除されただけで、ShapeRangeには選択された図形として入っていることになりませんか? なりますよね。 4のセル選択は意味がないことになります。 なので、  >選択か否かではなくTypeNameがShapeかRectangleかの違いなのではないでしょうか? これは、先ず、選択したか否かがあり、 結果としてShapeかRectangleがあるわけですから 結論は選択したか否か、ということになるのではありませんか?   そして、 >もっともDuplicateすればShapeのままで、CopyしてPasteしたらRectangleに変わるというのもなぜかわからないのですが・・・・ これについては、なぜか? という問いには誰も答えられないと思われます。 強いていうなら、Copyしたらではなくて、Selectionオブジェクトの仕様としか言いようがないですね。 ということで、今回の問題は、選択したか否か、ということです。 これでもう、ShapeRangeコレクションの使い方は分かりましたね?(^^;;; 以上です。

merlionXX
質問者

お礼

> 結果としてShapeかRectangleがあるわけですから > 結論は選択したか否か、ということになるのではありませんか? ここまではやっとわかりました。 > これでもう、ShapeRangeコレクションの使い方は分かりましたね?(^^;;; う~っ、結果としてそうなったShapeの下にShapeRangeが無く、Rectangleの下にはまずShapeRangeがきて、その下にFillがくるという構造になっているということなんでしょうね。わかったようでわからないような・・・・ φ( ̄_ ̄;) でも、そのように覚えておきます。

  • pauNed
  • ベストアンサー率74% (129/173)
回答No.3

ちょっとごちゃごちゃ書きすぎて、解り難かったようです。ごめんなさい。 『Copyで作成された』から『Typeが違う』のではありません。 Sub try1()だけ実行してください。 Selectせずに変数に格納したら型がShapeであり、 SelectしてSelectionを変数に格納したら型がRectangleになります。 >Stop時、VBEのローカルウィンドウを表示し、変数A,Bに格納されたObjectの型を確認してください。 これは、確認してみられましたか? さらに、A,Bそれぞれを展開してみてください。(左の田をクリック) Objectは階層構造になっています。 Aの直下にFillプロパティがあります。 Bにはありません。 ただ、Bの直下にShapeRangeプロパティがあります。 これは ShapeRange コレクションを返します。 このShapeRangeをさらに展開してください。最後に Item1 があります。 これがAと同じものです。 >AB.ShapeRange.Fill.ForeColor.SchemeColor = 10 は AB.ShapeRange.Item(1).Fill.ForeColor.SchemeColor = 10 と同じ事をしています。 >Selectメソッドで選択したObjectと、Selectionの内容は異なる事があります。 Shapeを選択しても、SelectionはShapeではない、という事です。

merlionXX
質問者

お礼

> Selectせずに変数に格納したら型がShapeであり、 > SelectしてSelectionを変数に格納したら型がRectangleになります。 CopyとDuplucateの違いではなかったのですね。わかりました。 > さらに、A,Bそれぞれを展開してみてください。(左の田をクリック) こういうところがあるとは存じませんでした。 初体験です。 > Objectは階層構造になっています。 > Aの直下にFillプロパティがあります。 > Bにはありません。 なるほど、こういう違いがあるんですねえ。 有難うございました。

回答No.2

エキスパートさん、こんにちは。 寒くなりましたがいかがお過ごしでしょうか。 と、余計なご挨拶は置いといて。。。 質問の件はヘルプをみてもなかなか分かりづらいところがありますが、 簡単に言うと、その図形が選択されてるかどうか、です。 選択された図形はShapeRangeコレクションの中に入るので その図形を扱うときはShapeRangeを使わないといけないということです。 但し、これは、今回のような【書式プロパティ】についてですが。 -------------------------------------------------  AA.Copy '(1)  .Paste '(1)  Set AB = Selection '(1) このABは【選択された状態】ですから、ShapeRangeでないとダメ ---------------------------------------------------------    Set AB = AA.Duplicate このABは、【選択されてない状態】であり、    Set AB = Activesheet.Shapes(2) と同じなので、ShapeRangeは使わないでもよい ------------------------------------------------------ それから、 >AB.ShapeRange.Fill.ForeColor.SchemeColor = 10'(1)の2 >AB.Fill.ForeColor.SchemeColor = 10 '(2)の2 ActiveSheet.Shapes(AB.Name).Fill.ForeColor.SchemeColor = 10 とすれば問題はおこりませんが、コードがちょと綺麗じゃない?! 【結論】 選択された図形の書式プロパティを扱うときは、ShapeRangeコレクションを使う と単純に覚える。   以上です。

merlionXX
質問者

お礼

大師さま、お久しゅうございます。 わたしも選択しているか否かのせいではないかと思いました。 それで .Range("A1").Select'(1) をわざと書き加えたのです。 これでA1セルが選択されて図形の選択が解除されていますよね? ですから、選択か否かではなくTypeNameがShapeかRectangleかの違いなのではないでしょうか?もっともDuplicateすればShapeのままで、CopyしてPasteしたらRectangleに変わるというのもなぜかわからないのですが・・・・。

  • pauNed
  • ベストアンサー率74% (129/173)
回答No.1

こんにちは。 Selectメソッドで選択したObjectと、Selectionの内容は異なる事があります。 Sub try1()   Dim A   Dim B      Set A = ActiveSheet.Shapes.AddShape(msoShape5pointStar, 100, 100, 100, 100)   A.Select   Set B = Selection   MsgBox "A: " & TypeName(A) & vbLf & "B: " & TypeName(B)   Stop      Set A = Nothing   Set B = Nothing End Sub Stop時、VBEのローカルウィンドウを表示し、変数A,Bに格納されたObjectの型を確認してください。 また、Selectionではなくとも、隠しObjectを使う事でも再現します。 (隠しObject...95以前のバージョンとの互換性を保持するためのもの) Sub try2()   Dim A   Dim B      Set A = ActiveSheet.Shapes.AddShape(msoShapeRectangle, 100, 100, 100, 100)   Set B = ActiveSheet.Rectangles.Add(200, 200, 100, 100)   MsgBox "A: " & TypeName(A) & vbLf & "B: " & TypeName(B)   Stop      Set A = Nothing   Set B = Nothing End Sub 変数にVariant型を用いている事も要因のひとつです。 個人的には、きちんと変数宣言し明示して、Objectの型を意識したほうが良いと思います。 ただ、Selectionを用いると、型違いエラーが発生する事もあります。 Sub try3()   Dim A As Object   Dim B As Rectangle   Dim C As Shape      Set A = ActiveSheet.Shapes.AddShape(msoShapeRectangle, 100, 100, 100, 100)   A.Select   Set B = Selection   On Error Resume Next   Set C = Selection 'エラー   Stop   Set C = A   Stop   Set A = Nothing   Set B = Nothing   Set C = Nothing End Sub Selection のような状況依存しないといけない時には..As Object を使う事もあります。 (上記例の Dim B As Rectangle...などは、あまり使わないとは思います)

merlionXX
質問者

お礼

有難うございます。 最初に生成された星型AAはTypeNameがShapeでした。 Duplicateで複製した星型ABは、オリジナルと同じくTypeNameがShapeでしたが、Copyで作成された星型ABはTypeNameがRectangleと、Typeが違うんですね! ここまでは理解できました。 では、ABが"Shape"であれば AB.Fill.ForeColor.SchemeColor = 10 でOKなのに ABが"Rectangle"なら AB.ShapeRange.Fill.ForeColor.SchemeColor = 10 と、"ShapeRange"というのを入れなければならないのはどうしてなのでしょうか? (実はShapeRangeというのが何なのか良くわかってないのです。)

関連するQ&A

専門家に質問してみよう