| 
    
     |  | ▼ichinose さん: >▼亜矢 さん:
 >こんにちは。
 >>シートを追加した時に他のシート(同じブック)にあるコマンドボタン(Activexコントロール)3つをコピー(コードも)したいのですが、方法がわかりません。
 >
 >コピー(コードも)  は、ボタンのコピーと共にシートモジュールにある
 >イベントプロシジャーも同じようにコピーするという意味ですよね?
 >
 >これは、Vbprojectを操作すれば、可能ですが、セキュリティを下げなければなりません。このセキュリティを下げる事の危険をあまりわかっていない方もこのプログラムを
 >使う対象になっているなら、こんな仕様は避けなければなりません。
 >
 >簡単な方法は、このコマンドボタンをActiveXコントロールのそれから、
 >Excelコントロールのボタンに代える仕様にすることです。
 >これがカリーニンさんがリンクされたスレッドで私が投稿した事なんですが・・・。
 >他にもコマンドバーを新規に作成し、そこのボタンを配置する方法も仕様によっては、
 >考えられます。
 >
 >ActiveXコントロールのコマンドボタンを使う方法でも出来そうではありますが・・・。
 >
 >簡単な例として新規ブックにて試してください。
 >
 >クラスモジュールを二つ作成してください(クラス名は、Class1とClass2)。
 >
 >Class2のモジュールに
 >
 >'==================================================================
 >Option Explicit
 >Public parent As Object
 >Public callnm As String
 >Public WithEvents btn As MSForms.CommandButton
 >Public sht As Worksheet
 >'==================================================================
 >Private Sub btn_Click()
 >  CallByName parent, callnm, VbMethod, btn, sht
 >End Sub
 >
 >
 >Class1のモジュール
 >
 >'==================================================================
 >Private col As Collection
 >Event click(ByVal btn As MSForms.CommandButton, ByVal sht As Worksheet)
 >'==================================================================
 >Private Sub Class_Initialize()
 >  Set col = New Collection
 >End Sub
 >'==================================================================
 >Private Sub Class_Terminate()
 >  On Error Resume Next
 >  Set col = notihng
 >End Sub
 >'==================================================================
 >Sub entry_btn(ByVal ebtn As MSForms.CommandButton, ByVal sht As Worksheet)
 >  Dim cls As Class2
 >  Set cls = New Class2
 >  Set cls.parent = Me
 >  cls.callnm = "click_ev"
 >  Set cls.btn = ebtn
 >  Set cls.sht = sht
 >  col.Add cls
 >End Sub
 >'==================================================================
 >Sub click_ev(ByVal btn As MSForms.CommandButton, ByVal sht As Worksheet)
 >  RaiseEvent click(btn, sht)
 >End Sub
 >
 >
 >Thisworkbookのモジュールに
 >
 >'==================================================================
 >Option Explicit
 >Private WithEvents cls As Class1
 >'==================================================================
 >Private Sub Workbook_BeforeClose(Cancel As Boolean)
 >  Call term_cls
 >End Sub
 >'==================================================================
 >Private Sub Workbook_NewSheet(ByVal Sh As Object)
 >  Dim ole As OLEObject
 >  Dim r As Range
 >  Dim btn As MSForms.CommandButton
 >  Set ole = Worksheets("sheet1").OLEObjects(1)
 >  ole.Copy
 >  Sh.Select
 >  Sh.Paste
 >  Sh.Range("a1").Select
 >  Set r = Range("b2:c5")
 >  With Sh.OLEObjects(1)
 >    .Left = r.Left
 >    .Top = r.Top
 >    .Width = r.Width
 >    .Height = r.Height
 >  End With
 >  Set btn = Sh.OLEObjects(1).Object
 >  setev_cls btn, Sh
 >End Sub
 >'==================================================================
 >Private Sub Workbook_Open()
 >  Dim sht As Worksheet
 >  Dim ole As OLEObject
 >  Call init_cls
 >  For Each sht In ThisWorkbook.Worksheets
 >    For Each ole In sht.OLEObjects
 >     If TypeName(ole.Object) = "CommandButton" Then
 >       Call setev_cls(ole.Object, sht)
 >     End If
 >    Next
 >  Next
 >End Sub
 >'==================================================================
 >Sub init_cls()
 >  Set cls = New Class1
 >End Sub
 >'==================================================================
 >Sub term_cls()
 >  Set cls = Nothing
 >End Sub
 >'==================================================================
 >Sub setev_cls(ByVal btn As MSForms.CommandButton, ByVal sht As Worksheet)
 >  cls.entry_btn btn, sht
 >End Sub
 >'==================================================================
 >Private Sub cls_click(ByVal btn As MSForms.CommandButton, ByVal sht As Worksheet)
 >  MsgBox sht.Name & "  の  " & btn.Name
 >End Sub
 >
 >
 >最後に標準モジュール(Module1)に
 >
 >'======================================================================
 >Sub mk_btnsamp()
 >  Dim r As Range
 >  Dim btn As MSForms.CommandButton
 >  Set r = Range("b2:c5")
 >  Set btn = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", Link:=False _
 >    , DisplayAsIcon:=False, Left:=r.Left, Top:=r.Top, Width:=r.Width, Height:=r.Height).Object
 >  btn.TakeFocusOnClick = False
 >End Sub
 >
 >
 >コードは以上です。
 >
 >VBEの参照設定にて、「Microsoft Forms 2.0 Object Library」にチェックを
 >入れてください。
 >
 >適当なシートをアクティブにして、mk_btnsampを実行してください。
 >アクティブシートにコマンドボタンが作成されます。このコマンドボタンが
 >コピー元のコマンドボタンです。
 >
 >
 >ここで適当な名前でブックを保存して、一度このブックを閉じてください。
 >再度、ブックを開いてください。
 >作成されているコマンドボタンをクリックしてください。
 >
 >シート名 の コマンドボタン名 というメッセージが表示されるはずです。
 >
 >「挿入」----「ワークシート」とクリックしてください。
 >挿入されたワークシートに事前に作成したコマンドボタンがコピーされてます。
 >クリックすると、シート名 の コマンドボタン名 というメッセージが表示されるはずです。
 >
 >試してみてください。
 >
 >Excel2002では、コマンドボタンのコピー&ペーストでは、モジュールレベルの変数の
 >初期化は行われませんでしたので、提示したコードで正常に動作しました。
 >
 >が、何かの仕様追加で動的にこのコマンドボタンを作成した場合、前述の
 >モジュールレベルの変数の初期化が行われて正常に作動しません。
 >回避方法は、ありますが、更に面倒になります。
 >
 >コマンドバー「フォーム」ボタン(Excelコントロール)での仕様変更を
 >検討してみてください。
 いろいろお手数をお掛けしました。上記のプログラムの見て中々理解できません。
 フォームボタンの仕様に変更することと他の方法を検討することにします。
 ありがとうございました。
 
 |  |