私はインターネット上でそうする多くのリソースを見つけました ほとんど 私がやりたいことですが、完全ではありません。名前付きの範囲「daylist」があります。 dayListの各日について、その日のマクロを実行するボタンをユーザーフォームに作成したいと思います。私は ボタンを動的に追加する ができますが、daycell.textを名前付き範囲からボタン、イベントハンドラー、マクロに渡す方法がわかりません:Sこれが私がしなければならないコードですユーザーフォームを作成します。
Sub addLabel()
ReadingsLauncher.Show vbModeless
Dim theLabel As Object
Dim labelCounter As Long
Dim daycell As Range
Dim btn As CommandButton
Dim btnCaption As String
For Each daycell In Range("daylist")
btnCaption = daycell.Text
Set theLabel = ReadingsLauncher.Controls.Add("Forms.Label.1", btnCaption, True)
With theLabel
.Caption = btnCaption
.Left = 10
.Width = 50
.Top = 20 * labelCounter
End With
Set btn = ReadingsLauncher.Controls.Add("Forms.CommandButton.1", "runButton", True)
With btn
.Caption = "Run Macro for " & btnCaption
.Left = 80
.Width = 80
.Top = 20 * labelCounter
' .OnAction = "btnPressed"
End With
labelCounter = labelCounter + 1
Next daycell
End Sub
上記の問題を回避するために、私は現在、実行したい日(Day1など)を入力するようにユーザーに促し、これをマクロに渡すと機能します。
Sub B45runJoinTransactionAndFMMS()
loadDayNumber = InputBox("Please type the day you would like to load:", Title:="Enter Day", Default:="Day1")
Call JoinTransactionAndFMMS(loadDayNumber)
End Sub
Sub JoinTransactionAndFMMS(loadDayNumber As String)
xDayNumber = loadDayNumber
Sheets(xDayNumber).Activate
-Do stuff
End Sub
したがって、runButtonごとに、daycell.textを表示し、同じテキストをパラメーターとして使用するマクロを実行して、作業を行うワークシートを選択する必要があります。
どんな助けでも素晴らしいでしょう。マクロを処理するためにvbaコードを動的に書き込む応答を見たことがありますが、パラメーターを渡すことでもう少しエレガントに実行できる必要があると思います。方法はわかりません。よろしくお願いします!
私はあなたがあなたのために働くそして以下よりはるかに簡単な解決策を今受け入れたことを知っています、しかしあなたが興味を持っているなら、これはあなたの質問に対するより直接的な答えでしょう。
ボタンのクリックを処理するクラスを作成する必要があるため、ボタンがクリックされるたびにクラス内のイベントが使用されます。これを1回実行するだけで、ボタンごとに新しいインスタンスを作成できます。これらのクラスがスコープ外になって失われるのを防ぐには、クラスレベルの宣言に格納する必要があります。以下では、コードを少し移動しました。
クラスモジュール内(私はそれをcButtonHandlerと呼んでいます)
Public WithEvents btn As MSForms.CommandButton
Private Sub btn_Click()
MsgBox btn.Caption
End Sub
ほとんどのイベントをコントロールに使用できるため、イベントありが使用されます。以下のように、ボタン生成コードをユーザーフォームに移動しました。
Dim collBtns As Collection
Private Sub UserForm_Initialize()
Dim theLabel As Object
Dim labelCounter As Long
Dim daycell As Range
Dim btn As CommandButton
Dim btnCaption As String
'Create a variable of our events class
Dim btnH As cButtonHandler
'Create a new collection to hold the classes
Set collBtns = New Collection
For Each daycell In Range("daylist")
btnCaption = daycell.Text
Set theLabel = ReadingsLauncher.Controls.Add("Forms.Label.1", btnCaption, True)
With theLabel
.Caption = btnCaption
.Left = 10
.Width = 50
.Top = 20 * labelCounter
End With
Set btn = ReadingsLauncher.Controls.Add("Forms.CommandButton.1", "runButton", True)
With btn
.Caption = "Run Macro for " & btnCaption
.Left = 80
.Width = 80
.Top = 20 * labelCounter
'Create a new instance of our events class
Set btnH = New cButtonHandler
'Set the button we have created as the button in the class
Set btnH.btn = btn
'Add the class to the collection so it is not lost
'when this procedure finishes
collBtns.Add btnH
End With
labelCounter = labelCounter + 1
Next daycell
End Sub
次に、別のルーチンからuseformを呼び出すことができます。
Sub addLabel()
ReadingsLauncher.Show vbModeless
End Sub
VBAのクラスは、多くのVBAブックで特に十分にカバーされていません(通常、理解するにはVB6ブックを読む必要があります)が、クラスとその仕組みを理解すると、非常に便利になります:)
お役に立てれば
編集-追加のクエリに対処する
コレクション内のオブジェクトを参照するには、これはキーまたはインデックスを介して行われます。キーを使用するには、アイテムをコレクションに追加するときにキーを追加する必要があります。
collBtns.Add btnH
になります
collBtns.Add btnH, btnCaption
このため、キーは一意である必要があります。その後、次のように参照できます。
'We refer to objects in a collection via the collection's key
'Or by it's place in the collection
'So either:
MsgBox collBtns("Monday").btn.Caption
'or:
MsgBox collBtns(1).btn.Caption
'We can then access it's properties and methods
'N.B you won't get any intellisense
collBtns("Monday").btn.Enabled = False
必要に応じて、クラスにプロパティ/メソッドを追加することもできます。たとえば、次のようになります。
Public WithEvents btn As MSForms.CommandButton
Private Sub btn_Click()
MsgBox btn.Caption
End Sub
Public Property Let Enabled(value As Boolean)
btn.Enabled = value
End Property
その後、アクセスされます:
collBtns("Monday").Enabled = False
これは役に立ちますか?さらに読むために、私はあなたにチップピアソンのサイトを紹介します、彼はほとんどのトピックについて素晴らしいものを持っています http://www.cpearson.com/Excel/Events.aspx
VBAはVB6に基づいているため、本格的なOO言語ではありません。たとえば、通常の意味での継承はサポートされておらず、インターフェイスの継承のみがサポートされていることを覚えておいてください。
お役に立てれば :)
ワークシートのクリックをキャッチする例。これをワークシートモジュールに入れます。
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' e.g., range(A1:E1) is clicked
If Not Application.Intersect(Target, Range("A1:E1")) Is Nothing Then
MsgBox "You clicked " & Target.Address
End If
End Sub