April 13, 2014

Excel TopLeftCell プロパティをSelection.ShapeRangeに対して適用するには

以下の記事で示したように、Selectionに対して、TopLeftCellを求められませんでした。
found, known and done.: Excel VBAのTopLeftCellプロパティが分からない
http://foundknownanddone.blogspot.jp/2014/04/excel-vba-topleftcell-runtime-error-selection-does-not-support-this-property.html
もう少し調べて理解した範囲でなぜなのか、どうすればよいのかを以下に解説します。


ShapeRangeとShapeは違う

TopLeftCellはShapeオブジェクトのメンバーですが、ShapeRangeオ ブジェクトのメンバーではありません。そして、For each target In Selection.ShapeRangeとした場合、targetに代入されるのは、Shapeオブジェクトではなく、ShapeRangeオブジェク トです。そのため、以下のコード1ではエラーとなります。
Sub testTopLeftCell()
    For Each target In Selection.ShapeRange
        MsgBox target.TopLeftCell.Address
    Next
End Sub

コード2ではShapeオブジェクトのTopLeftCellプロパティを参照しているのでエラーとなりません。
Sub testTopLeftCell2()
    For Each target In Selection.ShapeRange
        MsgBox ActiveSheet.Shapes(target.Name).TopLeftCell.Address
    Next
End Sub

同じプロパティもある

ではShapeRangeとShapeがまったく違うオブジェクトかというと、そういうことはなくて、コード3で実験すると、3回同じ結果が返されます(1つの図形を選んで実行した場合)。
Sub testShapeRange()
    For Each target In Selection.ShapeRange
        MsgBox "target: " + target.Name + "," + TypeName(target)
        MsgBox "Selection.ShapeRange(1): " + _
            Selection.ShapeRange(1).Name + ", " + _
            TypeName(Selection.ShapeRange(1))
        MsgBox "ActiveSheet.Shapes(target.Name): " + _
            ActiveSheet.Shapes(target.Name).Name + "," + _
            TypeName(ActiveSheet.Shapes(target.Name))
    Next
End Sub

これは、NameプロパティやTypeName関数は、ShapeRangeオブジェクトにもShapeオブジェクトにも同じ値を返す仕様だからです。

ではShapeRangeオブジェクトは何なのか

ShapeとShapeRangeは独立したオブジェクトとして考えるのではなく、ShapeRangeオブジェクトは選択されたShapeオブジェクトに対するインターフェイスのようなものと理解するのが妥当だと考えられます。

参照している実体は同じShapeオブジェクトなので、NameやTypeNameは同じ値を返すのですが、すべてのプロパティが共通しているわけではない、ということになります。

No comments :

Post a Comment