I need to list the captions of a large number of old ActiveX command buttons on a worksheet.
How do I refer to the collection?
PseudoCode:
For each btn in Activesheet.CommandButtons
Debug.Print btn.Caption
Next btn
Dim s As Worksheet
Set s = ActiveSheet
Dim o As OLEObject
For Each o In s.OLEObjects
If TypeName(o.Object) = "CommandButton" Then
Debug.Print o.Object.Caption
End If
Next
Updated the code that i found from MrExcel website:
Dim BtnActX As Integer
Dim MyShapes As OLEObjects
Dim Btn As OLEObject
'OLE Programmatic Identifiers for Commandbuttons = Forms.CommandButton.1
Set MyShapes = ActiveSheet.OLEObjects
For Each Btn In MyShapes
If Btn.progID = "Forms.CommandButton.1" Then
BtnActX = BtnActX + 1
abc = Btn.Object.Caption
MsgBox "command button text is: " & abc
End If
Next
How about looping through the OLEObjects in your worksheet, you can use their progID and see it it equals "Forms.CommandButton.1".
Note: please don't use ActiveSheet, instead use fully qualified objects, like Worksheets("Sheet1").
Option Explicit
Sub FindCommandButtonsInOLEObjects()
Dim Sht As Worksheet
Dim Obj As OLEObject
Set Sht = ThisWorkbook.Sheets("Sheet1") '<-- modify "Sheet1" to your sheet's name
' loop thourgh all OLE objects in "Sheet1"
For Each Obj In Sht.OLEObjects
If Obj.progID Like "Forms.CommandButton.1" Then ' <-- check if current object is type Comman Button
Debug.Print Obj.Object.Caption
End If
Next Obj
End Sub
Related
I have looked through numerous posts on looping through UserForm Controls but cant seem to adjust the code i have found for my needs and need some help.
Scenario I am trying to figure out:
I have 44 text boxes on a userform whose names all start with "ch" example "chTextBox1"
When the userform activates I need to loop through all of the text boxes that start with "ch" and change the background color of those textboxes to a color based on the interior color of a cell
Below is the code that I have been messing around with and I either end up in an infinite loop or I get
Error 424
Private Sub UserForm_Activate()
Dim wb As Workbook
Dim wsRR As Worksheet
Dim bColor As Range
Dim c As Control
Dim y As String
Set wb = Application.ThisWorkbook
Set wsRR = wb.Sheets("RiskRating")
Set bColor = wsRR.Range("C3")
For Each c In JHKey.Controls
If TypeName(c) = "TextBox" Then
y = Left(c, 2)
End If
If y = "ch" Then
c.BackColor = bColor.Interior.Color
End If
Next c
End Sub
Try placing the If statement testing for "ch" within the If statement testing for "TextBox". Also, you should specify the Name property for the control when checking for its name, otherwise it defaults to its Value property. Also, as an aside, I would suggest replacing JHKey with the keyword Me, which refers to the userform itself regardless of its name.
Private Sub UserForm_Activate()
Dim wb As Workbook
Dim wsRR As Worksheet
Dim bColor As Range
Dim c As Control
Dim y As String
Set wb = Application.ThisWorkbook
Set wsRR = wb.Sheets("RiskRating")
Set bColor = wsRR.Range("C3")
For Each c In Me.Controls
If TypeName(c) = "TextBox" Then
y = Left(c.Name, 2)
If y = "ch" Then
c.BackColor = bColor.Interior.Color
End If
End If
Next c
End Sub
Going crazy here. I use this definition of worksheet all the time. Copied every string to avoid typing errors. Still, the code below produces "Nothing" when I try to set FR worksheet. Pls help!
Sub FindReplace()
Dim FRep As Worksheet
Dim c As Range
Dim cText As TextBox
Dim i As Integer
Set FRep = ThisWorkbook.Worksheets("FindReplace")
For i = 1 To 23
cText = FRep.Cells(i, 3).Text
FRep.Cells(i, 2).NumberFormat = "#"
FRep.Cells(i, 2).Value = cText
Next i
The code as is seems correct. Make sure that "FindReplace" worksheet is in ThisWorkbook.
Also, you can try to get "FindReplace" worksheet by CodeName instead of by the name of the sheet. The advantage is that if the user changes the name of the worksheet, the CodeName will remain the same and you won't need to update your code to the new worksheet name.
Public Function GetWsFromCodeName(codeName As String, wb As Workbook) As Worksheet
Dim ws As Worksheet
For Each ws In wb.Worksheets
If ws.CodeName = codeName Then
Set GetWsFromCodeName = ws
Exit For
End If
Next ws
End Function
Add this function in your code:
Sub FindReplace()
Dim FRep As Worksheet
Set FRep = GetWsFromCodeName("YourCodeName", ThisWorkbook)
I'm trying to select an item in a ComboBox in a UserForm. I found the .Selected(index)=True code almost everywhere but for me it sais:
Compile error: Method or data member not found.
My code:
Private Sub UserForm_Initialize()
Dim worksheetList As New ArrayList
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
worksheetList.Add ws.Name
Next ws
sourceWorksheets.List = worksheetList.toArray
destinationWorksheets.List = worksheetList.toArray
sourceWorksheets.Selected(1) = True 'Error here
End Sub
Am I doing something wrong? I couldn't really find any other function which would set the "default" item.
As #Rory keeps saying - use ListIndex to select an item in the list control.
This piece of code will add each sheet name to the list control and then select the first item:
Private Sub UserForm_Initialize()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
Me.worksheetList.AddItem ws.Name
Next ws
Me.worksheetList.ListIndex = 0
End Sub
I think the OP was trying to use the code similar to below, but this still needs the ListIndex=0.
Private Sub UserForm_Initialize()
Dim ws As Worksheet
With CreateObject("System.Collections.ArrayList")
For Each ws In ThisWorkbook.Worksheets
.Add ws.Name
Next ws
Me.worksheetList.List = .ToArray
End With
Me.worksheetList.ListIndex = 0
End Sub
Edit: The code assumes the list control is called worksheetList.
Edit 2: A slightly different version. It reverses the items in the list when you click the form.
It's still Me.worksheetList.ListIndex = 0 to select the item in the list control though.
Option Explicit
Public MyArrayList As Variant
Private Sub UserForm_Initialize()
Dim ws As Worksheet
Set MyArrayList = CreateObject("System.Collections.ArrayList")
With MyArrayList
For Each ws In ThisWorkbook.Worksheets
.Add ws.Name
Next ws
.Sort
Me.worksheetList.List = .ToArray
End With
Me.worksheetList.ListIndex = 0
''This will only work in a listbox, not a combobox.
''Select items in row numbers that are even (ListIndex 0,2,4, etc)
''MultiSelect must be 1 - fmMultiSelectMulti or 2 - fmMultiSelectExtended
' Dim x As Long
' For x = 0 To Me.worksheetlist.ListCount - 1
' If x Mod 2 = 0 Then
' Me.worksheetlist.Selected(x) = True
' End If
' Next x
End Sub
Private Sub UserForm_Click()
With MyArrayList
.Reverse
Me.worksheetList.List = .ToArray
End With
Me.worksheetList.ListIndex = 0
End Sub
To check whether particular element (indicated by index) is selected you should do workaround like this:
ComboBox1.Value = ComboBox1.List(i)
where i is given index. It has to be done like that, because there is no propertry like SelectedIndex in VBA ComboBox.
Keep in mind, that indexing starts with 0 !
I have a user form and on a click of a button it is supposed to access or open a user form. But every time code gets to that part,
Run-time error '424':
Object required
pops up. Here is my code:
If CheckSheet(TextBoxValue) = True Then
Sheets(TextBoxValue).Select
UserForm.Show
Else
Set Worksheet = ThisWorkbook.Sheets.Add(After:=Sheets(Sheets.Count))
Worksheet.Name = TextBoxValue
Dim label As Control
For Each label In UserForm.Controls
If TypeName(label) = "Label" Then
With ActiveSheet
i = i + 1
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
.Cells(lastRow, i).Value = label.Caption
End With
End If
Next
UserForm.Show
End If
Every time it gets to the part with UserForm.Show and For Each label In UserForm.Controls
I checked the spelling of the form multiple times already and it is very much the same.
You may have had something like this in mind:-
Sub TestCode()
Dim Ws As Worksheet ' "Worksheet" is a reserved word
Dim MyForm As UserForm1 ' "UserForm" is a reserved word
Dim MyLabel As Control ' "Label" is a reserved word
Dim C As Long ' better name for a column than "i"
Set MyForm = New UserForm1
If GetSheet(Ws) Then
For Each MyLabel In MyForm.Controls
If TypeName(MyLabel) = "Label" Then
With Ws ' true, Ws is the ActiveSheet but
' always use the same name for the same sheet
C = C + 1
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
.Cells(LastRow, C).Value = MyLabel.Caption
End With
End If
Next
End If
MyForm.Show
End Sub
Private Function GetSheet(Ws As Worksheet) As Boolean
' return True if Ws didn't exist
Dim Ws As Worksheet
On Error Resume Next
Set Ws = Worksheets(TextBoxValue)
If Err Then ' Err = doesn't exist
Set Ws = ThisWorkbook.Sheets.Add(After:=Sheets(Sheets.Count))
Ws.Name = TextBoxValue
GetSheet = True
End If
End Function
Private Function TextBoxValue() As String
TextBoxValue = "MySheetName"
End Function
In order to test if a word is a "reserved" word, select it in your VB Editor and press F1. If MS Office uses it, don't argue.
I am trying to add a button to an Excel workbook so that it shows up in every sheet. A great answer to my original question gave me a macro to create the buttons on each sheet:
Sub AddButtons()
Dim ws As Excel.Worksheet
Dim btn As Button
For Each ws In ThisWorkbook.Worksheets
Set btn = ws.Buttons.Add(X, Y, W, H)
[set btn properties]
Next ws
End Sub
I am now having trouble with setting the button properties so that the button prints the sheet when pressed. Again here is my print macro:
Dim WS_Count As Integer
Dim i As Integer
' Set WS_Count equal to the number of worksheets in the active workbook.
WS_Count = ActiveWorkbook.Worksheets.Count
'allows user to set printer they want to use
Application.Dialogs(xlDialogPrinterSetup).Show
' Begin the loop.
For i = 5 To WS_Count
Worksheets(i).Activate
With ActiveWorkbook.Worksheets(i).PageSetup
.PrintArea = "A1:O48"
.Orientation = xlLandscape
.Zoom = False
.FitToPagesTall = 1
.FitToPagesWide = 1
End With
ActiveWorkbook.Worksheets(i).PrintOut
There have been some good suggestions about how to go about incorporating this macro into the button properties (passing variables and creating a new print sub) however I am pretty new to VBA and have been unsuccessful in getting this to work. Ideally I would have a button macro that creates the button and every time it is pressed calls the print macro for each sheet.
One last thing, I am trying to change the button code so that it only adds buttons to sheet 5 onwards. It would be great if anyone knew how to do that as well?
Any advice is helpful and greatly appreciated!
Try this:
Sub AddButtons()
Dim ws As Excel.Worksheet
Dim btn As Button
For Each ws In ThisWorkbook.Worksheets
Set btn = ws.Buttons.Add(X, Y, W, H)
btn.OnAction = "MySub" ' MySub is executed when btn is clicked
' Substitute the name of your printing subroutine
btn.Caption = "Print"
'set additional btn properties as needed
Next ws
End Sub
X and Y determine the location, W and H determine the button size.
This will add a button (Form Control) and assign an existing macro to it.
Sub test()
Dim cb As Shape
Set cb = Sheet1.Shapes.AddFormControl(xlButtonControl, 10, 10, 100, 25)
cb.OnAction = "PrintMacro"
End Sub
Private Sub PrintMacro()
MsgBox "Test" ' for testing pursposes
' you actually put your print code here
End Sub
Now to add buttons from Sheet 5 onwards only, you can try:
Producing a list of all your sheet names (if there's only a few of them)
Dim shname
For Each shname In Array("Sheet 5", "Sheet 6", "Sheet 7")
test Sheets(shname) ' note that you'll have to use below test sub
Next
Do it the other way around. Make a list of what to exclude and test every sheet if it is on the list or not.
Dim sh As Worksheet
Dim xcludesheet: xcludesheet = Array("Sheet1", "Sheet2", "Sheet3", "Sheet4")
For Each sh In Worksheets
If IsError(Application.Match(sh.Name, xcludesheet, 0)) Then
test Sheets(sh.Name)
End If
Next
Your test sub to be used in above samples.
Sub test(ws As Worksheet)
Dim cb As Shape
Set cb = ws.Shapes.AddFormControl(xlButtonControl, 10, 10, 100, 25)
cb.OnAction = "PrintMacro"
End Sub