
Sub うまくいく()
Dim rng As Range, shp As Object
For Each shp In ActiveSheet.Shapes
With shp
Set rng = Range(.TopLeftCell, .BottomRightCell)
Debug.Print rng.Address
End With
Next shp
End Sub
----------------------------------------------------------------
Sub うまくいかない()
Dim rng As Range, shp As Object
Set shp = Selection.ShapeRange
With shp
Set rng = Range(.TopLeftCell, .BottomRightCell)
Debug.Print rng.Address
End With
End Sub
----------------------------------------------------------------
事前にオブジェクトを選択してからの
Set shp = Selection.ShapeRange
を
Set shp = ActiveSheet.Shapes.Range(Array("picture 2"))
などと直接指定してもいずれも
Set rng = Range(.TopLeftCell, .BottomRightCell)
のところで
実行時エラー '438':
オブジェクトは、このプロパティまたはメソッドをサポートしていません。
となってしまいます。
うまくいくのといかないのとの違いが判りません。どなたかお願いいたします。
No.4ベストアンサー
- 回答日時:
何度もすみません。
「うまくいくほう」をF8キーでステップ実行して
「For Each shp In ActiveSheet.Shapes」の実行直後に
ローカルウィンドウで「shp」の中身(変数内に格納されたもの)を見ると、
「Object/Shape」と表示されます。
「うまくいくほう」も同じくF8キーでステップ実行して
「Set shp = Selection.ShapeRange」の実行直後に
ローカルウィンドウで「shp」の中身(変数内に格納されたもの)を見ると、
「Object/ShapeRange」と表示されます。
両者を比較すると、同じ名前・型の変数なのに・・・、
★うまくいくほうは:「Object/Shape」、
つまり、「Shapeオブジェクト」のデータが格納され、
★うまくいかないほうは:「Object/ShapeRange」、
つまり、「ShapeRangeオブジェクト」のデータが格納され
・・・ています。
そして、ヘルプにて
「Shapeオブジェクト」のオブジェクトメンバーを調べてみると、「TopLeftCell」プロパティがちゃんと存在します。「オブジェクトの左上端にあるセルを表す Range オブジェクトを返します。値の取得のみ可能です。」とあり、「うまくいくほう」の動きとも合致します。
が、「ShapeRangeオブジェクト」のほうには、ヘルプのオブジェクトメンバーを調べてみても「TopLeftCell」プロパティは存在しません。
オブジェクトブラウザで「TopLeftCell」で完全一致で検索しても、ヒットするのは・・・
・ChartObject
・OLEObject
・Shape
・・・の三つだけです。
なので、「ShapeRangeオブジェクト」は確実に、「TopLeftCell」プロパティを保持・内包していません。
うまくいかないほうのコードではWithが無ければ、
Set rng = Range(shp.TopLeftCell, shp.BottomRightCell)
という意味になると思いますが、
すこしまとめますと・・・
うまくいくほうでは「変数shp」の中身は「Shapeオブジェクト」。
うまくいかないほうでは「変数shp」の中身は「ShapeRangeオブジェクト」。
そしてヘルプやオブジェクトブラウザによると、
「Shapeオブジェクト」は、「TopLeftCell」プロパティを保持・内包していますが
「ShapeRangeオブジェクト」は「TopLeftCell」プロパティを保持・内包していません。(ついでに、BottomRightCellも保持・内包していません。)
つまり、「ShapeRangeオブジェクト」は「TopLeftCell」プロパティも「BottomRightCell」プロパティも保持・内包していないのにもかかわらず、「変数shp」に代入(Set)してしまったので、そのため、
「shp.TopLeftCell」と書くことで「ShapeRangeオブジェクト.TopLeftCell」と書いたことになってしまい、
また、「shp.BottomRightCell」と書くことで「ShapeRangeオブジェクト.BottomRightCell」と書いたことになってしまったので、
変数「rng 」に代入する直前の段階で、
「いま、変数shpにはShapeRangeオブジェクトが代入されちゃってますが、ShapeRangeオブジェクトには、もともとTopLeftCellもBottomRightCellも内包されていませんよ?」=すなわち、「オブジェクトはこのプロパティ、またはメソッドをサポート(保持・内包)していません」とエラーが出てしまったのではないかと思います。
丁寧にありがとうございます。
この回答のおかげでNo.1さんのおっしゃる意味がわかりました。
大変助かりました。重ねてお礼申し上げます。
No.5
- 回答日時:
すみません。
訂正です。「うまくいくほう」も同じくF8キーでステップ実行して
「Set shp = Selection.ShapeRange」の実行直後に
は
「うまくいかないほう」も同じくF8キーでステップ実行して
「Set shp = Selection.ShapeRange」の実行直後に
でした。すみませんでした。
No.3
- 回答日時:
「うまくいく」のほうの動きから察しますと、
「うまくいかない」のほうの、
事前にオブジェクトを選択してからの
Set shp = Selection.ShapeRange
を
Set shp = Selection
にするってことではダメなんでしょうか?・・・
単体のシェイプを選んで ×××・・・、みたいな・・・
そういうことがしたいのではなかったでしょうか?
意味が違ってたらすみません。
ローカルウィドウやウォッチ式ウィンドウなどで、オブジェクト変数や式の中身を色々と調べると色々とわかるのではないでしょうか?
ヘルプを読むと、「ShapeRange」オブジェクトは「図形範囲」「使用例:名前またはインデックス番号で指定した図形セットを取得する」ということのようですので、単一の図形も扱えるっぽいですが、どちらかというと複数の図形をいっぺんに扱う的なときに使うっぽい感じに読めました。
でも「うまくいかない」ほうのコードを見ると、、「単一のシェイプを選択して何かしたい」っぽいので、わざわざ、「ShapeRange」オブジェクトを意識しなくてもよいのではないかと思いました。
基本、「Selection」だけで、「1つのシェイプを選択した」というような意味になるので。
セルをクリックしても図形をクリックしても「Selection」と書くだけでよいのだから、それだけで良い(「ShapeRange」の記述は要らない)のではなかしら?と思いました。
意味が違ってたらすみません。
わかりやすい回答ありがとうございました。
shaperangeにTopLeftCellプロパティがないことを見落としていました。
助かりました。
No.2
- 回答日時:
>Excel vba Range型変数格納
Shape をRange 型に格納するというのは無理というか、
シート上のRange と、Shape は、セルAddress とは繋がってますが、フェーズ(階層)が違いますから、シート上のRange に、Shape は上に乗っているだけなのです。
その違いをプログラム的にどう説明するというのは、無理なのですが、何を目的にするかによって答えられると思います。
>Sub うまくいく()
>Dim rng As Range, shp As Object
>
>For Each shp In ActiveSheet.Shapes
>With shp
>Set rng = Range(.TopLeftCell, .BottomRightCell)
>Debug.Print rng.Address
>End With
>Next shp
>End Sub
うまくいっているのではなくて、エラーが出ていないだけで、図形を格納しているわけではありません。以下の「オブジェクトで格納する方法」を参照してください
'-----------------------------
Dim ShapeNames() 'プロシージャ外変数
Dim Rngs As New Collection 'プロシージャ外変数
'サブルーチンにする限りは、あまり意味はありません。
'***********
Sub GetShapeNames()
'名前で格納する方法
Dim shp As Shape
Dim i As Long
'配列変数を使う意味は得にありません、後で、Split関数で切り分けても可能です。
ReDim ShapeNames(ActiveSheet.Shapes.Count - 1) '再定義
For Each shp In ActiveSheet.Shapes
Debug.Print shp.Name
ShapeNames(i) = shp.Name
i = i + 1
Next
Call SelectShapes
End Sub
'*
Sub SelectShapes()
ActiveSheet.Shapes.Range(ShapeNames).Select '全部選択
End Sub
'-----------------------------
Sub GetShapeNames2()
'オブジェクトで格納する方法(取り出しは番号)
Dim shp As Shape
Dim i As Long
For Each shp In ActiveSheet.Shapes
With shp
i = i + 1
Rngs.Add Range(.TopLeftCell, .BottomRightCell)
End With
Next
Call SelectShapes2(2) '2番目を選択
End Sub
'*
Sub SelectShapes2(ByVal num As Long)
Dim shp As Shape
For Each shp In ActiveSheet.Shapes
If Not Intersect(Rngs(num), shp.TopLeftCell) Is Nothing Then
shp.Select
End If
Next
End Sub
ご返答ありがとうございました。
ShapeをRange型に格納したかったわけではありませんでした。
vba周辺の習熟不足につき当方の質問のしかたが的確でなかったかと思います。
お手数おかけしました。
No.1
- 回答日時:
こんにちは
属性値(TopLeftCellなど)を利用するのですから、対象となるのは単体のShapeオブジェクトでないとうまくいかないはずです。
一方で、ShapeRangeは文字通りshapesのRangeですから、仮に実質的な内容が一つであったとしても、包含オブジェクトであることは変わりません。
単体のShapeを取得するために
Selection.ShapeRange.Item(1)
とか
Selection.ShapeRange(1)
を参照するようにすれば、動作するのではないかと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Excel(エクセル) VBA 1 2023/04/27 13:37
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
- PowerPoint(パワーポイント) ExcelのVBAコードについて教えてください。 3 2022/05/25 14:32
- Excel(エクセル) 【マクロ】スクショ印刷がうまく動かない件 5 2022/12/06 17:37
- Visual Basic(VBA) 【VBAエラー】Nextに対するForがありません 対策について 5 2022/11/21 21:26
- Visual Basic(VBA) 【VBA】Excelの特定範囲のセルを画像で保存したい 2 2023/01/25 13:06
- Visual Basic(VBA) Excel vbaについての質問 3 2023/04/18 16:14
- Visual Basic(VBA) findメソッドの変数について 6 2023/06/23 08:01
- Visual Basic(VBA) VBAで教えて頂きたいのですが? 1 2022/04/29 02:36
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
worksheetFunctionクラスのVloo...
-
「Columns("A:C")」の列文字を...
-
エクセルのVBAの標準モジュール...
-
VBAで Set wb = Sheets(1).Cop...
-
Excelでフィルタをかけると警告...
-
sheetsメソッドの失敗
-
VBAでWebページにセルの値を入力
-
VBAで既に開いている別アプリケ...
-
オブジェクトが見つかりません
-
VBからPDFファイル自動生成...
-
エクセルマクロの行選択
-
vb.netアプリケーションで発生...
-
findメソッドの変数について
-
Excel VBAでWordの複数ファイル...
-
ASPからSELECT文を複数発行する...
-
エクセル/保護したシート上の埋...
-
実行時エラー 3265「要求された...
-
エクセルマクロエラー「'Cells'...
-
エクセルVBAでcode128のバー...
-
Excel2007 VBA ラジオボタン Ca...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
worksheetFunctionクラスのVloo...
-
「Columns("A:C")」の列文字を...
-
エクセルのVBAの標準モジュール...
-
Excelでフィルタをかけると警告...
-
実行時エラー 3265「要求された...
-
VBAで既に開いている別アプリケ...
-
テキストボックス中の文字列の...
-
ExcelVBAでのNZ関数について
-
[VBA]CDOメッセージ送信エラー
-
EXCEL VBA オートシェイプナン...
-
VBAで Set wb = Sheets(1).Cop...
-
エクセルマクロエラー「'Cells'...
-
AccessVBAで「dim dbs as datab...
-
Excel VBAでWordの複数ファイル...
-
オブジェクトが見つかりません
-
CreateObjectとGetObjectの違い
-
エクセルVBAで配列内に空白デー...
-
オブジェクト変数またはWITHブ...
-
エクセルVBAでcode128のバー...
-
VBScriptからDLL参照設定したい
おすすめ情報