Avevo postato alcune domande all’OP della discussione #53131, ma non ho ricevuto alcuna risposta.
Allora ho deciso di pubblicare sul BLOG questo mio lavoro, che non so se possa essere utile ai fini pratici,pero puo servire (a mio modesto avviso)come studio,il progetto in esame l’ho chiamato ” Come inserire dei controlli RUNTIME in una USERFORM”.
Scenario:
In un file EXCEL, nel foglio1 a partire della cella “A1″inserisco dei dati che possono essere , numeri , strighe, ecc., cosi per tutta la colonna,fino ad arrivare alla cella”Ax”. Ho creato anche una USERFORM ed ho inserito un pulsante, vorrei fare in modo che, all’evento CLICK sul pulsante, nella USERFORM vengano creati tanti PULSANTI quanti sono le celle riempite della colonna “A”, con la “CAPTION” del valore delle celle,inoltre vorrei associare ad ogni Pulsante una MACRO diversa per ogni Pulsante.
Per effettuare cio’ ci vengono in aiuto le “CLASSI”, in VBA “Moduli di Classe”.
Per cominciare creiamo una USERFOM che conterra’ i nostri Oggetti che andremo a creare RUNTIME, una volta aperto il nostro editorVba, dal menu Inserisci,click su Modulo di classe, nella finestra delle proprieta’ rinominiamo il “Name” in “clsCommandButton” e inseriamo queste righe di codice:
Option Explicit
Public WithEvents cmd As MSForms.CommandButton
Public frm As UserForm
Private Sub cmd_Click()
MsgBox “Ciao. Il mio nome è: ” _
& cmd.Name _
& vbNewLine _
& “La mia caption è: ” _
& cmd.Caption
MONDELLO (cmd.Name)
End Sub
cosa fa questo codice:
Dichiaro una variabile “cmd” che è un “COMMANDBUTTON” e gli dico che qualsiasi Evento che faccio su questa variabile fai qualcosa(nel nostro caso l’evento è il CLICk).
Subito dopo c’è la Sub cmd_Click che mi lancia una MSGBOX(ne potremmo fare a meno), e dopo chiama una ROUTINE “MONDELLO” passandoci un parametro(cmd.Name).
Dopo aver inserito un Modulo di Classe, inseriamo un Modulo ed andiamo a digitare il codice seguente:
Option Explicit
Dim myCmd As clsCommandButton
Dim cmd As MSForms.CommandButton
Sub MONDELLO(dato)
Select Case dato
Case “A”
A
Case “B”
B
Case “C”
C
Case “D”
D
End Select
End Sub
Sub A()
MsgBox “Macro A”
End Sub
Sub B()
MsgBox “Macro B”
End Sub
Sub C()
MsgBox “Macro C”
End Sub
Sub D()
MsgBox “Macro D”
End Sub
In cima al codice dichiariamo del variabile “myCmd e cmd “, dopo abbiamo la ” Sub MONDELLO” a cui passimo un argomento “dato”, che a secondo del suo valore effettua un “Select Case dato”.
Passando al pulsante della nostra Userform, abbiniamo il seguente codice:
Option Explicit
Dim colCommandButton As Collection
Dim myCmd As clsCommandButton
Private Sub master_Click()
Dim riga As Integer
Dim msg As String, style As String, title As String
riga = 0
Do
riga = Val(InputBox(“Quanti Pulsanti vuoi per ogni riga? MAX 5”, “Richiesta righe”))
If riga < 6 Then
Exit Do
End If
msg = “Devi inserire un valore UGUALE o INFERIORE a 5”
style = vbCritical
title = “Albatros54”
MsgBox msg, style, title
Loop While riga > 5
If riga = 0 Then
Unload UserForm2
Exit Sub
End If
Call addTxtBox1(riga)
End Sub
‘ Questa Routine non fa altro che chiedermi quanti pulsanti debbo inserire per ogni riga(MAX 5)
Private Sub addTxtBox1(iTextBoxPerRiga)
Dim Wbs As Object
Dim mTxtBox As Object
Dim mCounter As Long
Dim mLeft As Long, mWidth As Long, mHeight As Long
Dim mDist As Long, mIncr As Long
Dim ur As Long, k As Long, r As Long
Dim dTop As Long
Dim lblcap As String
Set Wbs = Worksheets(“Foglio1”)
ur = Wbs.Range(“A” & Rows.Count).End(xlUp).Row
r = 1
mLeft = 10
mHeight = 18
mWidth = 80
mIncr = 0
k = 0
mDist = 8 ‘ incrementa/decrementa distanza verticale botton
dTop = 8
For mCounter = 1 To ur
lblcap = Wbs.Cells(r, 1)
Set mTxtBox = UserForm2.Controls.Add(“Forms.CommandButton.1”, “Test” & mCounter, True)
With mTxtBox
.Height = mHeight
.Width = mWidth
.Left = mLeft + mIncr
.Top = dTop
.Caption = lblcap
.Name = lblcap
k = r Mod iTextBoxPerRiga ‘3
End With
If k = 0 Then
mIncr = 0
Else
mIncr = (mWidth + 15) * (mCounter Mod iTextBoxPerRiga)
End If
r = r + 1
If mCounter Mod iTextBoxPerRiga = 0 Then
dTop = dTop + mHeight + mDist
End If
Next mCounter
‘calcola dimensioni uForm
Dim h, w
Dim nome As String
Dim C As Control
h = 0: w = 0
For Each C In UserForm2.Controls
nome = C.Name
If C.Visible Then
If C.Top + C.Height > h Then h = C.Top + C.Height
If C.Left + C.Width > w Then w = C.Left + C.Width
End If
Next C
If h > 0 And w > 0 Then
With UserForm2
.Width = w + 40
.Height = h + 40
End With
End If
Dim ctl As MSForms.Control
Set colCommandButton = New Collection
For Each ctl In Me.Controls
Set myCmd = New clsCommandButton
Set myCmd.cmd = ctl
Set myCmd.frm = Me
colCommandButton.Add myCmd
Next
master.Visible = False
End Sub
‘ Questa Routine non fa altro ,ricevuto il parametro,di calcolare i pulsanti da inserire nella Userform,di assegnare alla proprieta’ “NAME” di ogni pulsante il valore trovato nella colonna “A” del foglio1, e crea una Collection “colCommandButton” che passera’ il valore del pulsante alla Classe “clsCommandButton”.
In allegato il file dove ho lavorato.
