【お題】NEW演歌

すみません、教えてください。
以下のマクロは正常に動きます。

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です。

A 回答 (6件)

要は、


変数への格納の仕方、
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
    • good
    • 0
この回答へのお礼

> 変数への格納の仕方、
> Objectの指定の仕方が違う、

なるほど、同じ物でも
Set A = .DrawingObjects(.DrawingObjects.Count) とすれば型はRectangleだし、
Set A = .Shapes(.Shapes.Count) とすれば型はShapeになりますね。
有難うございます。

お礼日時:2007/12/06 13:58

今日は暇なのでまた登場。


今回はこれで終わりにしまする。(^^;;;

>う~っ、結果としてそうなったShapeの下にShapeRangeが無く、Rectangleの下にはまずShapeRangeがきて、その下にFillがくるという構造になっているということなんでしょうね。わかったようでわからないような・・・・

VBAのプロになるのであればなんですが、
こんな小難しいことは考えなくてもいいのではないのですか?
何回も言ってるように

●選択された図形●を扱う場合は、ShapeRangeコレクションを使う、
と覚えておけばいいと思いますよ。

Selection.ShapeRange.Fill。。。。。。

なお、当方の回答は、あくまでも
質問のタイトルにある、「エクセルVBAでShapeRangeについて」です。
 
で、今回の質問については当方の回答は終了ということで。
 
    • good
    • 0
この回答へのお礼

大師さま、何度もお手間を取らせすみませんでした。

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

お礼日時:2007/12/06 14:11

またまた登場、、、(^^;;;



>わたしも選択しているか否かのせいではないかと思いました。
>それで .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コレクションの使い方は分かりましたね?(^^;;;

以上です。
    • good
    • 0
この回答へのお礼

> 結果としてShapeかRectangleがあるわけですから
> 結論は選択したか否か、ということになるのではありませんか?

ここまではやっとわかりました。

> これでもう、ShapeRangeコレクションの使い方は分かりましたね?(^^;;;

う~っ、結果としてそうなったShapeの下にShapeRangeが無く、Rectangleの下にはまずShapeRangeがきて、その下にFillがくるという構造になっているということなんでしょうね。わかったようでわからないような・・・・
φ( ̄_ ̄;)

でも、そのように覚えておきます。

お礼日時:2007/12/05 16:29

ちょっとごちゃごちゃ書きすぎて、解り難かったようです。

ごめんなさい。
『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ではない、という事です。
    • good
    • 0
この回答へのお礼

> Selectせずに変数に格納したら型がShapeであり、
> SelectしてSelectionを変数に格納したら型がRectangleになります。

CopyとDuplucateの違いではなかったのですね。わかりました。

> さらに、A,Bそれぞれを展開してみてください。(左の田をクリック)

こういうところがあるとは存じませんでした。
初体験です。

> Objectは階層構造になっています。
> Aの直下にFillプロパティがあります。
> Bにはありません。

なるほど、こういう違いがあるんですねえ。
有難うございました。

お礼日時:2007/12/05 16:23

エキスパートさん、こんにちは。


寒くなりましたがいかがお過ごしでしょうか。
と、余計なご挨拶は置いといて。。。

質問の件はヘルプをみてもなかなか分かりづらいところがありますが、
簡単に言うと、その図形が選択されてるかどうか、です。

選択された図形は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コレクションを使う
と単純に覚える。
 
以上です。
    • good
    • 0
この回答へのお礼

大師さま、お久しゅうございます。
わたしも選択しているか否かのせいではないかと思いました。
それで .Range("A1").Select'(1) をわざと書き加えたのです。
これでA1セルが選択されて図形の選択が解除されていますよね?

ですから、選択か否かではなくTypeNameがShapeかRectangleかの違いなのではないでしょうか?もっともDuplicateすればShapeのままで、CopyしてPasteしたらRectangleに変わるというのもなぜかわからないのですが・・・・。

お礼日時:2007/12/05 11:29

こんにちは。


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...などは、あまり使わないとは思います)
    • good
    • 0
この回答へのお礼

有難うございます。
最初に生成された星型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というのが何なのか良くわかってないのです。)

お礼日時:2007/12/05 10:29

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

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報