【ExcelVBA】シェイプやコントロールのインデックス番号を元に選択状態にするには

この記事では、シェイプやコントロールのインデックス番号を元に選択状態にする方法についてご説明します。

今回の記事は、「【ExcelVBA】シート上のシェイプやコントロール全ての名前や種類を取得するには」を改良した内容になっています。

【動画】シート上のシェイプやコントロール全ての名前や種類を取得する実際の動き

本題に入る前に、まずは次の動画をご覧ください。


まずはシェイプやコントロールのインデックス番号を取得します。

ただし、インデックス番号の値はそもそもシェイプやコントロール自体には用意されていないので、シェイプやコントロールの名前や種類を取得する際のカウンタの値を代替でインデックス番号として取得します。

今回のサンプルでは、インデックス番号をシートに出力後、A列の名前のセルを選択したタイミングでシェイプまたはコントロールが配置されているセルを選択してそのシェイプまたはコントロールを選択状態にしています。

マクロ作成の流れ

【①ユーザー定義関数】シート上のシェイプやコントロール全ての名前や種類を取得する

STEP.1
ShapeオブジェクトのNameプロパティでシェイプやコントロールの名前を取得する
ShapeオブジェクトのNameプロパティでシェイプやコントロールの名前を取得します。
STEP.2
ShapeオブジェクトのAutoShapeTypeプロパティでシェイプやコントロールの種類を取得する
ShapeオブジェクトのAutoShapeTypeプロパティでシェイプやコントロールの種類を取得します。
STEP.3
index番号を取得する(カウンタの値で代替)
index番号を取得します。
ただし、インデックス番号の値はそもそもシェイプやコントロール自体には用意されていないので、カウンタの値で代替します。
STEP.4
シェイプやコントロールの数だけSTEP.1からSTEP.3まで繰り返す
シェイプやコントロールの数だけSTEP.1からSTEP.3まで繰り返します。

【②Worksheet_SelectionChangeイベントプロシージャ:今回のサンプルでは「Worksheet_SelectionChangeイベントプロシージャ」を使用】シェイプやコントロールのインデックス番号を元に選択状態にする

STEP.1
選択されたセルがA列でかつ、その選択されたセルと同じ行のC列のセルに文字列「idx-」が含まれているかを判定する
選択されたセルがA列でかつ、その選択されたセルと同じ行のC列のセルに文字列「idx-」が含まれているかを判定します。
この条件に合致すればSTEP.2に遷移します。
この条件に合致しなければ何もしません。
STEP.2
C列のセルの値から文字列「idx-」を取り除いた値(インデックス番号)を取得する
C列のセルの値から文字列「idx-」を取り除いた値(インデックス番号)を取得します。
STEP.3
シェイプまたはコントロールが配置されているセルを選択する
シェイプまたはコントロールが配置されているセルを選択します。
シェイプまたはコントロールがどこに配置されたか分かるように画面表示させます。
STEP.4
シェイプまたはコントロールを選択状態にする
シェイプまたはコントロールを選択状態にします。

コードの例

①Excelマクロのユーザー定義関数のコード(例)

Option Explicit
Const indexStr As String = "idx-"

Sub test()

    Dim obj As Object       'シェイプ・コントロール用変数
    Dim cnt As Integer      'カウンタ
    
    'カウンタを初期化する
    cnt = 2
    
    With Worksheets("work")
    
        'シェイプ・コントロールの名前・種類・インデックス番号を出力するセルをクリアする
        .Range(.Cells(2, 1), .Cells(100, 3)) = ""
    
        'シート「work」上のシェイプ・コントロールの数分だけループ
        For Each obj In .Shapes
        
            'シェイプ・コントロールに付けられた名前を取得する
            .Range("A" & cnt).Value = obj.Name
            
            'シェイプ・コントロールの種類を取得する(数値で取得)
            .Range("B" & cnt).Value = obj.AutoShapeType
            
            'index番号を取得する(カウンタの値で代替)
            .Range("C" & cnt).Value = indexStr & cnt - 1
                        
            cnt = cnt + 1
        
        Next obj

    End With

End Sub

注目すべきコード①

最初に見て頂きたいのは2行目です。

Const indexStr As String = "idx-"

以上のコードは、文字列「idx-」を定数に設定するコードです。

インデックス番号は数値なので念のため、わざわざ文字列「idx-」にインデックス番号を結合させるためこの定数を用意しています。
(1や2などの値がすでにC列のセルに値が入っていた場合に、マクロがインデックス番号だと認識してしまい困るのでわざわざ他のセルには存在しないような一意の値に設定するためこの定数を用意)

注目すべきコード②

次に見て頂きたいのは20行目です。

    With Worksheets("work")
    
        'シート「work」上のシェイプ・コントロールの数分だけループ
        For Each obj In .Shapes

以上のコードは、シェイプやコントロールの数だけループ処理を行うコードです。

例えば、シェイプやコントロールが10個あれば、10回ループを繰り返します。

注目すべきコード③

次に見て頂きたいのは20行目です。

            'シェイプ・コントロールに付けられた名前を取得する
            .Range("A" & cnt).Value = obj.Name
            
            'シェイプ・コントロールの種類を取得する(数値で取得)
            .Range("B" & cnt).Value = obj.AutoShapeType
            
            'index番号を取得する(カウンタの値で代替)
            .Range("C" & cnt).Value = indexStr & cnt - 1

以上のコードは、ShapeオブジェクトのNameプロパティとAutoShapeTypeプロパティでシェイプやコントロールの名前と種類を取得、さらにはインデックス番号をセルに出力しているコードです。

21行目と24行目のNameプロパティとAutoShapeTypeについては、今回の記事の本題から外れるので、こちらの記事の内容をご覧ください。

最後に27行目のインデックス番号ですが、インデックス番号の値はそもそもシェイプやコントロール自体には用意されていないので、シェイプやコントロールの名前や種類を取得する際のカウンタの値を代替でインデックス番号としてセルに出力しています。

なお、カウンタ「cnt」の前に、文字列「idx-」が格納された定数indexStrを結合させています。

インデックス番号は数値なので念のため、わざわざ文字列「idx-」にインデックス番号を結合させるようにしています。

このインデックス番号を参照して使いたいタイミングでこの定数indexStrを削除してインデックス番号だけを使うようにしています。

【参考】定数indexStrを削除してインデックス番号だけを抜き出す処理
            indexVal = CInt(Replace(Worksheets("work").Range("C" & Target.Row), indexStr, ""))

②ExcelマクロのWorksheet_SelectionChangeイベントプロシージャのコード(例)

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    Dim indexVal As Integer     'インデクス番号の値

    With Worksheets("work")

        If Target.Column = 1 And _
           InStr(.Range("C" & Target.Row), indexStr) = 1 Then
            
            '選択されたセルがA列でかつ、その選択されたセルと同じ行のC列のセルに文字列「idx-」が含まれている場合
            
            'C列のセルの値から文字列「idx-」を取り除いた値(インデックス番号)を取得する
            indexVal = CInt(Replace(Worksheets("work").Range("C" & Target.Row), indexStr, ""))

            'シェイプまたはコントロールが配置されているセルを選択する
            '→シェイプまたはコントロールがどこに配置されたか分かるように画面表示させる
            .Range(Worksheets("work").Shapes(indexVal).TopLeftCell.Address).Select

            'シェイプまたはコントロールを選択状態にする
            .Shapes(indexVal).Select

        End If

    End With

End Sub

注目すべきコード①

最初に見て頂きたいのは2行目です。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

今回のサンプルでは、「別のセルが選択された」タイミングを処理開始のトリガーにするためWorksheet_SelectionChangeイベントプロシージャを使用しています。

どのイベントをトリガーにするか?

Worksheet_SelectionChangeイベントプロシージャの他にも、どのタイミングでイベントを発生させるか選択肢はあるとは思いますが、お手軽さを考えて今回のサンプルではWorksheet_SelectionChangeイベントプロシージャを使うことにしました。
ただし、Worksheet_SelectionChangeを使いたくない場合は、お使いの環境に合わせてどのイベントをトリガーにするかは決めて頂ければと思います。

注目すべきコード②

次に見て頂きたいのは7行目と8行目です。

        If Target.Column = 1 And _
           InStr(.Range("C" & Target.Row), indexStr) = 1 Then

以上のコードは、選択されたセルがA列でかつ、その選択されたセルと同じ行のC列のセルに文字列「idx-」が含まれているかどうかを判定するコードです。

今回のサンプルでは、A列のシェイプやコントロールの名前が入力されているセルが選択された場合にシェイプやコントロールを選択状態にしたいので、この条件を満たしているかを判定します。

なお、A列をクリックしただけではなく、同じ行のC列のセルに文字列「idx-」が含まれインデックス番号が入力されていなければ処理は何もせず終了します。

注目すべきコード③

次に見て頂きたいのは13行目です。

            'C列のセルの値から文字列「idx-」を取り除いた値(インデックス番号)を取得する
            indexVal = CInt(Replace(Worksheets("work").Range("C" & Target.Row), indexStr, ""))

以上のコードは、インデックス番号を取り出すコードです。

C列のセルの値にはインデックス番号の頭に文字列「idx-」が結合されているので(例:idx-1)、「idx-」をRepalce関数を使って取り除いた値(インデックス番号)を取得し変数「indexVal」に格納しています。

注目すべきコード④

次に見て頂きたいのは17行目から20行目です。

            'シェイプまたはコントロールが配置されているセルを選択する
            '→シェイプまたはコントロールがどこに配置されたか分かるように画面表示させる
            .Range(Worksheets("work").Shapes(indexVal).TopLeftCell.Address).Select

            'シェイプまたはコントロールを選択状態にする
            .Shapes(indexVal).Select

以上のコードは、シェイプまたはコントロールが配置されているセルを選択し、シェイプまたはコントロールを選択状態にするコードです。

今回のサンプルでは、インデックス番号をシートに出力後、A列の名前のセルを選択したタイミングでシェイプまたはコントロールが配置されているセルを選択してそのシェイプまたはコントロールを選択状態にしています。

ちなみに、なぜシェイプまたはコントロールが配置されているセルをわざわざ選択しているのかというと、シェイプまたはコントロールを選択状態にしただけではそのシェイプまたはコントロールが配置されている位置まで移動して画面を表示してくれないからです。
(ただシェイプまたはコントロールが選択されているだけで、表示されている画面はそのままで切り替わらない)

動作確認

【①ユーザー定義関数】実行前

今回用意したExcelファイルは以下の通りシェイプとコントロールが配置されています。

【①ユーザー定義関数】実行後

マクロを実行すると、配置されたシェイプとコントロールの名前と種類、インデックス番号がセルに出力されました。

【②Worksheet_SelectionChangeイベントプロシージャ】実行前

選択状態にしたいシェイプまたはコントロールの名前が入力されたセル(A列のセル)をクリックします。

【②Worksheet_SelectionChangeイベントプロシージャ】実行後

選択状態にしたいシェイプまたはコントロールが選択状態になりました。

最後に

本記事では、シェイプやコントロールのインデックス番号を元に選択状態にする方法についてご説明しました。

どんなシェイプやコントロールが配置されているか把握するだけではなく、直感的にどこにそのシェイプやコントロールがあるのかを確認したい時はこの記事が参考にしてみてくださいね。

Excelのスキル向上やExcelの基礎知識をしっかりと学びたいなら

Excelのスキルを習得したい、Excelの基礎知識をもっと理解したい、そう考えているなら「無期限サポート付きExcel講座【すごい改善】」がおすすめです。

Excelのスキルの基礎を身につけるなら【すごい改善】で無期限サポート付きがあるので、これで「Excelのスキルや基礎」を学ぶのにおすすめですよ。

→ 受講後、何度でも無期限でメールで質問できるアフターサポートがついているExcelマスター講座はこちら