i've got dynamically generated userform consisting of labels, checkboxes and text boxes. is it possible to have a contents of a textbox selected when clicked?
this is method i'm using to create textbox:
Set NewTextBox = MainFrame.Controls.Add("Forms.TextBox.1")
With NewTextBox
.Name = "QtyTB" & row
.Value = Cells(cellrow - 1 + row, 11)
.Height = 18
.Left = 210
.Top = 18
.Width = 36
.Enabled = True
.BackColor = RGB(255, 255, 0)
End With
if i was to create textbox manually i could write on_click sub for specific text box. but as i said, code generates everything from scratch.
so if there is a property, or some other way to get it done, i would be gratefull.
Yes, this can be done by creating a class module with event handling
The following code will need a bit of adaption as there isn't much code to go on in the question...
In a class module called TextBoxEventHandler
Private WithEvents FormTextBox As MSForms.TextBox
Public Property Set TextBox(ByVal oTextBox As MSForms.TextBox)
Set FormTextBox = oTextBox
End Property
Private Sub FormTextBox_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If Button = 1 Then
With FormTextBox
.SelStart = 0
.SelLength = Len(.Text)
End With
End If
End Sub
Then in the UserForm code
Private CollectionOfEventHandlers As Collection
Private Sub UserForm_Initialize()
Dim i As Long
Dim NewTextBox As MSForms.TextBox
For i = 0 To 4
Set NewTextBox = Me.Controls.Add("Forms.TextBox.1")
With NewTextBox
.Name = "QtyTB" & i ' Row
.Value = "Text " & i ' Cells(cellrow - 1 + Row, 11)
.Height = 18
.Left = 21
.Top = 18 + i * 25
.Width = 36
.Enabled = True
.BackColor = RGB(255, 255, 0)
End With
Next i
Call InitialiseHandlers
End Sub
Private Function InitialiseHandlers()
Set CollectionOfEventHandlers = New Collection
Dim FormControl As Control
For Each FormControl In Me.Controls
If TypeName(FormControl) = "TextBox" Then
Dim EventHandler As TextboxEventHandler
Set EventHandler = New TextboxEventHandler
Set EventHandler.TextBox = FormControl
CollectionOfEventHandlers.Add EventHandler
End If
Next FormControl
End Function
Related
I am trying to get rid of the horizontal scroll bar in my listbox--which appears when a user clicks in certain cells and is then consequently "deleted" each time the user clicks out of that cell (so I can't change it manually, I must change it with code)--but the .ColumnWidths property does not seem to function.
It seems the ColumnWidths is default set at 74--this based on the fact that if I set my Width at 74 or greater there is no horizontal scroll bar.
If when clicking a cell, I go into design mode, open properties, I can manually set the ColumnWidths to 35. That is not a solution since my listbox is created and deleted depending on the user's active cell. Nonetheless this confirmed that it is something about how my code is written.
Option Explicit
Private WithEvents Lbx As MSForms.ListBox
Private oTarget As Range
Private ListBoxName As String
Private Const Cell_A1 As String = "B1:B20" 'change addr as required.
Private Sub Lbx_Change()
Dim k As Long
oTarget.ClearContents
For k = 0 To Lbx.ListCount - 1
If Lbx.Selected(k) Then
If Len(oTarget) = 0 Then
oTarget = Lbx.List(k)
Else
oTarget = _
Trim(oTarget & vbNewLine & Lbx.List(k))
End If
End If
Next
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim oListBox As OLEObject
On Error Resume Next
Me.OLEObjects(1).Delete
Range(Cell_A1).Interior.ColorIndex = 0
If Target.Column = 2 And (Target.Row >= 1 And Target.Row <= 20) Then
'UCase(Target.Address(0, 0)) = UCase(Cell_A1)
Application.DisplayFormulaBar = False
Set oListBox = _
Me.OLEObjects.Add(ClassType:="Forms.ListBox.1")
With oListBox
Names.Add "ListBoxName", .Name
.Left = Target.Offset(0,1).Left
.Top = Target.Offset(0, 0).Top
.ColumnCount = 1
.ColumnWidths = "35"
.Width = 54
.Height = Me.StandardHeight * 16
.Object.ListStyle = fmListStylePlain
.ListFillRange = "A1:A20"
.Placement = xlFreeFloating
.Object.MultiSelect = fmMultiSelectMulti
.Object.SpecialEffect = fmSpecialEffectFlat
.Object.BorderStyle = fmBorderStyleSingle
With Application
.OnTime Now + _
TimeSerial(0, 0, 0.01), Me.CodeName & ".Hooklistbox"
.CommandBars.FindControl(ID:=1605).Execute
End With
End With
Else
Application.DisplayFormulaBar = True
Names("ListBoxName").Delete
Range(Cell_A1).Interior.ColorIndex = 0
End If
End Sub
Private Sub Hooklistbox()
Application.CommandBars.FindControl(ID:=1605).Reset
Set oTarget = ActiveCell
ActiveCell.Interior.Color = vbGreen
'display the listbox and hook it.
With Me.OLEObjects(Evaluate("ListBoxName"))
.Visible = True
Set Lbx = .Object
End With
End Sub
Type
.Object.
Before .ColumnCount and .ColumnWidths
And get rid of the on error resume next, which brought you to this "hidden" error in the first place
Use a on error goto 0 afterwards when it's not needed anymore
++
instead of:
On Error Resume Next
Me.OLEObjects(1).Delete
you could use:
If Me.OLEObjects.Count > 0 Then Me.OLEObjects(1).Delete
and delete this line (because Names will be overwritten, so no need to delete:
Names("ListBoxName").Delete
I'm using a form to generate 3 groups of textboxes at run time. I'm trying to achieve this: when the user click a textbox of the group "txtboxe", a FileDialog opens so the user can choose the file. When the file is picked, i wwant to get the filepath.
The problem is, usually, i would use a sub like - textboxe_Click - but i need this to work inside a existing module, and the name of each textbox is generate at run time.
So... Any ideas? I tried to use multiple times something with 'Controls' commands, but without any sucess. I manage to pick the data from each textbox, but not to control a click or change on a textbox group.
I'm providing the code below.
Dim i As Long
Dim o As Long
Dim number As Long
number = InputBox("How many docs?", "Number of docs")
Dim txtB1 As Control
Dim txtB2 As Control
For i = 1 To number
Set txtB1 = Controls.Add("Forms.Textbox.1")
With txtB1
.Name = "txtbox" & i
.Height = 16
.Width = 30
.Left = 60
.Top = 20 + (i * 40)
.Value = i
.Locked = True
.BackColor = &H80000000
End With
Set txtB2 = Controls.Add("Forms.Textbox.1")
With txtB2
.Name = "txtboxw" & i
.Height = 18
.Width = 234
.Left = 162
.Top = 20 + (i * 40)
Debug.Print .Name
End With
Set txtB3 = Controls.Add("Forms.Textbox.1")
With txtB3
.Name = "txtboxe" & i
.Height = 18
.Width = 264
.Left = 420
.Top = 20 + (i * 40)
Debug.Print .Name
End With
Next i
End Sub
Private Sub CommandButton3_Click()
Dim p As Long
For p = 1 To number
cells(p + 1, 1) = Controls("txtbox" & p).Value
cells(p + 1, 2) = Controls("txtboxw" & p).Value
cells(p + 1, 3) = Controls("txtboxe" & p).Value
Next p
End Sub ````
Registering event handlers with dynamically created controls is tricky.
But you can do it using a Class Module and WithEvent variable.
First, add the following code as a Class Module ControlEvent.
Option Explicit
Private WithEvents targetCtrl As MSForms.TextBox
Public Sub SetCtrl(new_ctrl As MSForms.TextBox)
Set targetCtrl = new_ctrl
End Sub
' You can add arbitrary event handlers for TextBox as ``targetCtrl_(Event handler name)``
Private Sub targetCtrl_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
With Application.FileDialog(msoFileDialogFilePicker)
If .Show() Then
' You can access the control with the targetCtrl class variable
targetCtrl.Value = .SelectedItems(1)
End If
End With
End Sub
Then, modify your code in the UserForm to the following.
I added an array ctrls to store the ControlEvent class instances and set the created controls to the WithEvents class variables with SetCtrl method.
Private ctrls As Variant ' Added
Sub CommandButton2_Click()
Dim i As Long
Dim o As Long
Dim number As Long
number = InputBox("How many docs?", "Number of docs")
Dim txtB1 As Control
Dim txtB2 As Control
Dim txtB3 As Control
ReDim ctrls(0 To number - 1)
For i = 1 To number
Set txtB1 = Controls.Add("Forms.Textbox.1")
With txtB1
.Name = "txtbox" & i
.Height = 16
.Width = 30
.Left = 60
.Top = 20 + (i * 40)
.Value = i
.Locked = True
.BackColor = &H80000000
End With
Set txtB2 = Controls.Add("Forms.Textbox.1")
With txtB2
.Name = "txtboxw" & i
.Height = 18
.Width = 234
.Left = 162
.Top = 20 + (i * 40)
Debug.Print .Name
End With
Set txtB3 = Controls.Add("Forms.Textbox.1")
With txtB3
.Name = "txtboxe" & i
.Height = 18
.Width = 264
.Left = 420
.Top = 20 + (i * 40)
Debug.Print .Name
End With
Set ctrls(i - 1) = New ControlEvent ' Added
ctrls(i - 1).SetCtrl txtB3 ' Added
Next i
End Sub
I created many buttons dynamically (creating schedule) and want all of them do the same thing during Click event (OnClick property).
Of course, I can create max number of buttons on the form beforehand and set them invisible, and so forth, while adding "call SomeEvent" on their Click event considering that there can be over a thousand buttons. This would be very tedious.
Therefore, simplified:
I created new class btnClass`
Public WithEvents ButtonEvent As MsForms.CommandButton
Private Sub ButtonEvent_Click()
MsgBox "hey"
End Sub
Then, in my UserForm, where I dynamically create buttons I added this (I also have Collection, to remove buttons later), in its simplified form:
Dim btnColl As Collection
Dim Buttons As New btnClass
Set btnColl = New Collection
Set Buttons = New btnClass
For i = 0 To btnCount
Set theButton = Controls.Add("Forms.CommandButton.1", "btn" & i, True)
With theButton
.Height = 17
.Caption = "btn" & i
End With
Set Buttons.ButtonEvent = theButton
btnColl.Add theButton, theButton.Name
Next i
But nothing happens when I click dynamically created buttons. What am I missing?
---UPDATED
---#FaneDuru Provided solution which worked for me
ReDim Buttons(0 To btnCount, 0 To dtDiff)
For labelcounter = 0 To dtDiff 'add date labels
Set theLabel = Controls.Add("Forms.Label.1", "lblDay" & labelcounter, True)
With theLabel
.Caption = VBA.Format(DateAdd("d", labelcounter, bDate), "d-mm-yy")
.Left = 15 + 44 * labelcounter
.BackColor = vbBlack
.Font.Bold = True
.ForeColor = vbWhite
.Height = 13
.Width = 40
.Top = 85
End With
For i = 0 To btnCount 'add time buttons
pTime = DateAdd("n", i * dur, begTime)
Set theButton = Controls.Add("Forms.CommandButton.1", "btn" & CDate(theLabel.Caption & " " & TimeValue(pTime)), True)
With theButton
.Height = 17
.Caption = VBA.Format(TimeValue(pTime), "hh:mm")
'.Caption = CDate(theLabel.Caption & " " & TimeValue(pTime))
.Left = 15 + 44 * labelcounter
.BackColor = vbGreen
.Width = 40
.Top = 100 + 18 * i
End With
Set Buttons(i, labelcounter).ButtonEvent = theButton
btnColl.Add theButton, theButton.Name
Next i
Next labelcounter
In this way, only for the last created button an event is allocated. You must declare an array of classes... I also played a little with the Left property of the newly created buttons, only to have the possibility to test their click event. Try the next approach, please:
Option Explicit
Private btnColl As New Collection
Dim Buttons() As New btnClass
Private Sub btCreate_Click()
Dim btnCount As Long, theButton As CommandButton, i As Long
btnCount = 3
ReDim Buttons(0 To btnCount)
For i = 0 To btnCount
Set theButton = Me.Controls.aDD("Forms.CommandButton.1", "btn" & i, True)
With theButton
.height = 17
.Caption = "btn" & i
.left = 50 * i
End With
btnColl.aDD theButton, theButton.Name
Set Buttons(i).ButtonEvent = theButton
Next i
End Sub
Private Sub btdelete_Click() 'buttons deletion...
Dim i As Long
For i = 1 To btnColl.count
Me.Controls.Remove (btnColl(i).Name)
Next
End Sub
I want to create dynamic buttons and then implement the click method, but any help on the internet does not work here. I hope someone can help me here.
It is not possible to create all buttons. Unfortunately, there is no possibility to write in other languages because we can only use Excel and may.
This is about the infoBtn1_Click.
My Script
Option Explicit
Dim WithEvents infoBtn As MSForms.CommandButton
Dim WithEvents infoBtn1 As MSForms.CommandButton
Dim WithEvents frameCard As MSForms.frame
Dim WithEvents cardTitel As MSForms.Label
Dim WithEvents ausLabel As MSForms.Label
Dim WithEvents ausbilderLabel As MSForms.Label
Dim WithEvents amLabel As MSForms.Label
Dim WithEvents datumLabel As MSForms.Label
Dim WithEvents infoLabel As MSForms.Label
Dim add As Integer
Dim topPos As Integer
Dim ctl As Control
Dim n As Integer
Dim VorhabenArray() As Variant
Dim Free(1 To 5) As Long
Dim sh As Worksheet
Dim v As Range
Dim arr(0 To 40) As Integer
Dim i As Integer
Dim ausbildungNr As String
Dim speicher As String
Private Sub CommandButton1_Click()
If ComboBox1.Value = "" Then
MsgBox "Bitte tragen Sie eine Ausbildung ein."
Exit Sub
End If
ausbildungSuche.ausbildungCB.Value = ComboBox1.Value
Unload Me
Call ausbildungSuche.suchenBtn_Click
End Sub
Private Sub infoBtn1_Click()
MsgBox "test"
End Sub
Private Sub UserForm_Activate()
On Error GoTo fehler
ComboBox1.List = Sheets("Meta").Range("A1:A8").Value
speicher = ausbildungSuche.ausbildungCB.Value
Select Case speicher
Case "MilFit":
ausbildungNr = "1"
Case "Circuit training":
ausbildungNr = "2"
Case "Volleyball":
ausbildungNr = "3"
Case "Fußball":
ausbildungNr = "4"
Case "Sportliche Ertuechtigung":
ausbildungNr = "5"
Case "BFT":
ausbildungNr = "6"
Case "DSA":
ausbildungNr = "7"
Case "Schwimmen":
ausbildungNr = "8"
Case Else
MsgBox "Fehler"
End Select
Set sh = ThisWorkbook.Worksheets(ausbildungNr)
i = 0
topPos = 12
For Each v In sh.Range("M2:M100")
If Not v = "0" Then
Set frameCard = Controls.add("Forms.Frame.1", "frame" & i)
With frameCard
.Left = 144
.Top = topPos
.Width = 258
.Height = 72
.Caption = ""
.Zoom = 100
.SpecialEffect = 3
.BorderColor = &H80000012
End With
Set cardTitel = frameCard.Controls.add("Forms.Label.1", "cardTitel" & i, True)
With cardTitel
.Left = 8
.Top = 6
.Width = 126
.Height = 18
.ForeColor = &H8000000D
.Caption = v.Cells(, -10)
.FontBold = True
.FontSize = 12
End With
Set infoBtn = frameCard.Controls.add("Forms.CommandButton.1", "infoBtn" & i, True)
With infoBtn
.Left = 144
.Top = 36
.Width = 102
.Height = 24
.ForeColor = &HFFFFFF
.BackColor = &H8000000D
.Caption = v & " Plätze frei"
End With
Debug.Print "infoBtn" & i
Set ausLabel = frameCard.Controls.add("Forms.Label.1", "ausLabel", Visible)
With ausLabel
.Left = 12
.Top = 30
.Width = 42
.Height = 12
.Caption = "Ausbilder"
End With
Set ausbilderLabel = frameCard.Controls.add("Forms.Label.1", "ausbilderLabel", Visible)
With ausbilderLabel
.Left = 54
.Top = 30
.Width = 72
.Height = 12
.FontBold = True
.Caption = v.Cells(, -9)
End With
Set amLabel = frameCard.Controls.add("Forms.Label.1", "amLabel", Visible)
With amLabel
.Left = 12
.Top = 48
.Width = 24
.Height = 12
.Caption = "Am"
End With
Set datumLabel = frameCard.Controls.add("Forms.Label.1", "datumLabel", Visible)
With datumLabel
.Left = 54
.Top = 48
.Width = 72
.Height = 12
.FontBold = True
.Caption = v.Cells(, -8)
End With
Set infoLabel = frameCard.Controls.add("Forms.Label.1", "infoLabel", Visible)
With infoLabel
.Left = 222
.Top = 6
.Width = 24
.Height = 12
.FontBold = True
.Caption = "Info"
End With
topPos = frameCard.Top + frameCard.Height + 10
i = i + 1
End If
Next
ausbildungsfilter.Caption = ausbildungSuche.ausbildungCB.Value
Exit Sub
fehler: MsgBox "Das hat leider nicht geklappt."
Unload Me
End Sub
You need a class module beside the user form. Here is a sample of the mechanic how dynamic events works:
Place this code in the module of an empty user form:
Option Explicit
Dim comSampleBtn1 As clsClickEventsComBut
Dim comSampleBtn2 As clsClickEventsComBut
Private Sub UserForm_Initialize()
Dim comButTemp As MSForms.CommandButton
Dim commandButtonIndex As Byte
commandButtonIndex = 1
'Place sample button 1 and generate click event
Set comButTemp = Me.Controls.Add("Forms.commandbutton.1", "CommandButton" & commandButtonIndex, True)
commandButtonIndex = commandButtonIndex + 1
With comButTemp
'Place button
.Left = 50
.Top = 50
.Height = 20
.Width = 100
.Caption = "Sample Button 1"
.ControlTipText = "Click me"
End With
Set comSampleBtn1 = New clsClickEventsComBut
Set comSampleBtn1.ComButSample = comButTemp
Set comButTemp = Nothing
'Place sample button 2 and generate click event
Set comButTemp = Me.Controls.Add("Forms.commandbutton.1", "CommandButton" & commandButtonIndex, True)
commandButtonIndex = commandButtonIndex + 1
With comButTemp
'Place button
.Left = 50
.Top = 75
.Height = 20
.Width = 100
.Caption = "Sample Button 2"
.ControlTipText = "Click me too"
End With
Set comSampleBtn2 = New clsClickEventsComBut
Set comSampleBtn2.ComButSample = comButTemp
Set comButTemp = Nothing
End Sub
Now you need a class module with the name clsClickEventsComBut
Copy the following code to this module:
Option Explicit
Public WithEvents ComButSample As MSForms.CommandButton
Private Sub ComButSample_Click()
MsgBox "You clicked the sample button: " & UserForm1.ActiveControl.Name & Chr(13) & "With the caption: " & UserForm1.ActiveControl.Caption
End Sub
If you now click one of the two buttons, the message box will be show. This works with all controls.
Edit: New text for the message box with reference to the clicked button.
You have to assign this to the OnClick property of the button (usually on the OnLoad event or something similar):
infoBtn1.OnClick = "[Event Procedure]"
This assumes you have your Private Sub InfoBtn1_Click procedure declared like you have on your example code.
And note that it is this exact "[Event Procedure]" string that should be assigned to the OnClick.
I have a code here that will generate pages depends on what value is on the textbox.
'Button accepting how many number of pages
Private Sub CommandButton1_Click()
RowChar = 70
MultiPage1.Pages.Clear
For i = 0 To TextBox1.Value - 1
MultiPage1.Pages.Add
MultiPage1.Pages(i).Caption = "Variable" & i + 1
Call LabelPerPage
Set txtbx = UserForm1.MultiPage1.Pages(i).Controls.Add("Forms.TextBox.1", "NameBox")
With txtbx
.Top = 20
.Left = 100
End With
Set txtbx = UserForm1.MultiPage1.Pages(i).Controls.Add("Forms.TextBox.1", "MinBox")
With txtbx
.Top = 50
.Left = 100
End With
Set txtbx = UserForm1.MultiPage1.Pages(i).Controls.Add("Forms.TextBox.1", "LsbBox")
With txtbx
.Top = 20
.Left = 300
End With
Set txtbx = UserForm1.MultiPage1.Pages(i).Controls.Add("Forms.TextBox.1", "Mataas")
With txtbx
.Top = 50
.Left = 300
End With
If i = 0 Then
FormulaString = "= C15"
Else
FormulaString = FormulaString & " " & Chr(RowChar) & "15"
RowChar = RowChar + 3
End If
Next i
TextBox2.Value = FormulaString
End Sub
Problem: I want to disable commandbutton2(button for computation of MINbox and MAxbox) if all the textboxes inside each pages are empty. Do you have any IDEA how can I do that? Thank you.
Though best way and easiest way is to validate on click in CommandButton2_Click as answered by #Excelosaurus, i just offering slightly modified way of TextBox change event trapping by #Mathieu Guindon's answer in the post Implementing a change event to check for changes to textbox values and enabling the “apply” button. The full credit of this technique of encapsulating a WithEvents MSForms control goes to #Mathieu Guindon
in the Userform1 code module may be modified as below
Public handlers As VBA.Collection ' added
Private Sub CommandButton1_Click()
RowChar = 70
MultiPage1.Pages.Clear
For i = 0 To TextBox1.Value - 1
MultiPage1.Pages.Add
MultiPage1.Pages(i).Caption = "Variable" & i + 1
'Call LabelPerPage
Set txtbx = UserForm1.MultiPage1.Pages(i).Controls.Add("Forms.TextBox.1", "NameBox")
With txtbx
.Top = 20
.Left = 100
End With
Set txtbx = UserForm1.MultiPage1.Pages(i).Controls.Add("Forms.TextBox.1", "MinBox")
With txtbx
.Top = 50
.Left = 100
End With
Set txtbx = UserForm1.MultiPage1.Pages(i).Controls.Add("Forms.TextBox.1", "LsbBox")
With txtbx
.Top = 20
.Left = 300
End With
Set txtbx = UserForm1.MultiPage1.Pages(i).Controls.Add("Forms.TextBox.1", "Mataas")
With txtbx
.Top = 50
.Left = 300
End With
If i = 0 Then
FormulaString = "= C15"
Else
FormulaString = FormulaString & " " & Chr(RowChar) & "15"
RowChar = RowChar + 3
End If
Next i
TextBox2.Value = FormulaString
CommandButton2.Enabled = False ' added
makeEvents ' added
End Sub
Sub makeEvents() ' added
Set handlers = New VBA.Collection
Dim cnt As MSForms.Control
For i = 0 To UserForm1.MultiPage1.Pages.Count - 1
For Each cnt In UserForm1.MultiPage1.Pages(i).Controls
If TypeOf cnt Is MSForms.TextBox Then
Dim textBoxHandler As DynamicTextBox
Set textBoxHandler = New DynamicTextBox
textBoxHandler.Initialize cnt
handlers.Add textBoxHandler
'Debug.Print cnt.Name & i & "Inited"
End If
Next cnt
Next i
End Sub
Then Add a new class module to your project, call it DynamicTextBox
Option Explicit
Private WithEvents encapsulated As MSForms.TextBox
Public Sub Initialize(ByVal ctrl As MSForms.TextBox)
Set encapsulated = ctrl
End Sub
Private Sub encapsulated_Change()
Dim TextEmpty As Boolean
Dim cnt As Control
Dim i As Integer
For i = 0 To UserForm1.MultiPage1.Pages.Count - 1
For Each cnt In UserForm1.MultiPage1.Pages(i).Controls
If TypeOf cnt Is MSForms.TextBox Then
'Debug.Print cnt.Name & i & "checked"
If cnt.Value = "" Then
TextEmpty = True
Exit For
End If
End If
Next cnt
If TextEmpty = True Then
Exit For
End If
Next i
If TextEmpty Then
UserForm1.CommandButton2.Enabled = False
Else
UserForm1.CommandButton2.Enabled = True
End If
End Sub
Tried and found working
The easier way is to validate on click: in CommandButton2_Click, scan your dynamically created textboxes, and either proceed or notify the user about any validation error.
A more complicated way is to create a class that will monitor the events of a TextBox. You will create one instance of this class per TextBox you want to monitor, keeping those instances in e.g. an array. See How to add events to Controls created at runtime in Excel with VBA.
You can loop through each worksheet in your workbook, and for each worksheet - loop through all the OLEObjects. You will check the typename of the .Object, and perform your final tests there.
I would create a function that you can easily call to perform this check and return a Boolean True/False.
Function allTextboxEmpty() As Boolean
Dim oleObj As OLEObject, ws As Worksheet
allTextboxEmpty = True
For Each ws In ThisWorkbook.Worksheets
For Each oleObj In ws.OLEObjects
If TypeName(oleObj.Object) = "TextBox" Then
If oleObj.Object.Value <> vbNullString Then
allTextboxEmpty = False
Exit Function
End If
End If
Next oleObj
Next ws
End Function
If the above function returns True, then you know that all of your textboxes in the workbook are empty. You can use this function as shown in the below example:
If allTextboxEmpty Then
Worksheets("Sheet1").CommandButton2.Enabled = False
Else
Worksheets("Sheet1").CommandButton2.Enabled = True
End If