Excel2024からActiveXコントロールが使用できなくなりました。
理由が「セキュリティの脆弱性」であるため、
Excel365も追従する可能性が高いです。
新規に挿入することはもちろんできなくなりますが、
既存のコントロールも選択や押下ができなくなり、
そこに設置したマクロ(イベント)も実行できなくなります。
この問題に対応するための、
アクティブシートの全ActiveXボタンを一括でフォームボタンに置き換えるマクロ
を紹介します。
↑こんな感じで、同じ位置/同じ大きさ/同じマクロをセットした、
「元_ボタン名」というフォームボタンを生成します。
実行型の便利マクロですので、
Excel起動時に裏で開かれる「個人用マクロブック」などに搭載して使ってください。
と言いつつこのマクロはある程度作業が終われば不要になるものなので、
普通のブックに書いておき、使い終わったら押し入れにしまうくらいがちょうどいいかもしれません。
ソースコード
Sub アクティブシートのActiveXコントロールボタンをフォームコントロールボタンに置き換える() Dim 対象シート As Worksheet: Set 対象シート = ActiveSheet ' ActiveXコントロールのうちCommandButtonだけを処理 Dim OLEオブジェクト As OLEObject For Each OLEオブジェクト In 対象シート.OLEObjects If TypeName(OLEオブジェクト.Object) = "CommandButton" Then ' 位置・サイズ・キャプション(テキスト)・マクロ名を取得 Dim ボタンtop As Double, ボタンleft As Double Dim ボタンwidth As Double, ボタンheight As Double Dim ボタンテキスト As String, ボタン名 As String, マクロ名 As String With OLEオブジェクト ボタンtop = .Top ボタンleft = .Left ボタンwidth = .Width ボタンheight = .Height ボタンテキスト = .Object.Caption ボタン名 = .Name マクロ名 = 対象シート.CodeName & "." & .Name & "_Click" End With ' 同じ位置に同じ大きさでフォームコントロールのボタンを挿入 Dim フォームボタン As Button Set フォームボタン = 対象シート.Buttons.Add( _ Top:=ボタンtop, Left:=ボタンleft, _ Width:=ボタンwidth, Height:=ボタンheight) ' ActiveXボタンの設定を追加したフォームボタンに反映 With フォームボタン .Name = "元_" & ボタン名 .Caption = ボタンテキスト .OnAction = マクロ名 End With ' ActiveXボタンを削除 OLEオブジェクト.Delete End If Next ' ActiveXコントロールのうちCommandButtonだけを処理 MsgBox "すべてのActiveXボタンの置き換えを完了しました。" End Sub
解説
↓以下の処理を愚直に実行している割とストレートなコードです。
- シート内のActiveXコントロール(OLEオブジェクト)をFor Eachループ
- 位置や大きさ、名称、設定マクロ名などを記憶
- それらを反映させたフォームボタンを挿入
- 完了後にActiveXのボタンを削除
一つ一つの処理は複雑なことはしていませんので、
コメントと変数名を読めば処理の流れはつかめると思います。
仕様上の注意点として、両ボタンにセットするマクロは通常
- ActiveXボタン:ボタン名称に「_Click」を付けたイベントプロシージャ
- フォームボタン:任意のマクロを手作業で設置(どこに書いてもOK)
という違いがあります。
今回はActiveXにセットされたマクロをフォームボタンに付け替えるのですが、
「シートモジュール上のPrivateプロシージャは、
シートオブジェクト名.プロシージャ名 でボタンに設置可能」
という小技を使って設定しています。
Privateプロシージャは通常マクロの一覧には表示されず、
故にボタンにセットすることは出来なそうに感じるのですが、
↑このように「シートオブジェクト名.マクロ名」を手入力することで、
リストにないPrivateプロシージャでもボタンに登録することが可能になります。
この技はもちろん「OnAction」への設定でも使用できますので、
今回のコードでもこの仕様を活用しています。
なお、この設定にはシート名ではなくシートオブジェクト名を使う必要があり、
Worksheet.CodeNameで取得していることに留意してください。
シートオブジェクト名についてはこちらの記事をどうぞ
最後に注意として、
ActiveXにおいてボタン名とマクロ名が必ず一致しているとは限りません。
加えてActiveXコントロールの設定イベントも正確に取得することはできませんので、
このマクロで置き換えたボタン達は必ず動作確認をお願いします。