I have a worksheet that has two rows of option buttons. Option buttons 1 - 11 are on row 7 and option buttons 12 - 22 are on row 9 of the sheet. My code loops through and centers each option button in its appropriate cell by calling the centerOfCell function.
When I run my program Worksheets("Orders") gets passed into the CenterOptionButton procedure, and all of the option buttons get centered EXCEPT for option button 1. I cannot figure out why this happens.
Sub CenterOptionButton(wks As Worksheet)
Dim i As Byte
With wks
Select Case .Name
Case "RDC", "SKU"
optionCount = 8
Case "Orders"
optionCount = 11
Case Else
End Select
For i = 1 To optionCount
.OLEObjects("OptionButton" & i).Left = centerOfCell(.Cells(7, i + 1))
.OLEObjects("OptionButton" & i + optionCount).Left = centerOfCell(.Cells(9, i + 1))
Next i
End With
End Sub
If I then run the below procedure all by itself substituting out wks with Worksheets("Orders"), everything works perfectly. Any idea on what the issue could be?
Sub test()
Dim i As Byte
With Worksheets("Orders")
Select Case .Name
Case "RDC", "SKU"
optionCount = 8
Case "Orders"
optionCount = 11
Case Else
End Select
For i = 1 To optionCount
.OLEObjects("OptionButton" & i).Left = centerOfCell(.Cells(7, i + 1))
.OLEObjects("OptionButton" & i + optionCount).Left = centerOfCell(.Cells(9, i + 1))
Next i
End With
End Sub
Try to copy the other option button and replace the first option button. The issue might get resolved. As for why it is happening I would not know. Excel has been know to through up unknown errors. I would normally recreate the file or object and the issue is usually solved.
Related
I have a Data Entry Userform that works but now I want to replicate it I need 36 fields in total (144 items not including buttons)
for an example
Field 1 will consist of a TextBox and 3 labels. (Data Entry, Title, Bottom Border and FieldRequired label.
What I want to do is to generate the above with names like Txt1,Txt2,Txt3.... Title1, Title2, Title3, Bdr1,Bdr2,Bdr3, Fr1,Fr2,Fr3 and for some I need to create Listbox1,Listbox2 and Listbox3 inside of frames 1 2 and 3 but this I can do manually.
I want to separate them so 4 fields across and 9 fields down.
Is there an easy solution to doing this or just doing it manually?
I can sort of do this using the below and then just doing this 4 times and adding 80 to the left
I would then need do to the same for the other fields and apply the events to them and fonts/font sizes etc but I cant figure out how to use events against them.
Sub addLabel()
frmUserAdd.Show vbModeless
Dim lblid As Object
Dim lblc As Long
For lblc = 1 To 9
Set lblid = frmUserAdd.Controls.Add("Forms.Label.1", "Alert" & lblc, True)
With lblid
.Caption = "*Field Required" & lblc
.Left = 10
.Width = 60
.Top = 30 * lblc
End With
Next
end sub
Please, test the next scenario:
Insert a class module, name it "clsTbox" and copy the next code inside it:
Option Explicit
Public WithEvents newTBox As MSForms.TextBox
Private Sub newTBox_Change()
If Len(newTBox.Text) > 3 Then 'it do something for 4 entered digits:
Select Case CLng(Right(newTBox.name, 1))
Case 1, 3
MsgBox newTBox.name & " changed (" & newTBox.Text & ")"
Case 2, 4
MsgBox newTBox.name & " changed its text"
Case Else
MsgBox newTBox.name & " Different text..."
End Select
End If
End Sub
Insert a Userform and copy the next code in its code module:
Option Explicit
Private TBox() As New clsTBox
Private Sub UserForm_Initialize()
Dim i As Long, txtBox01 As MSForms.TextBox, leftX As Double, tWidth As Double, k As Long
Const txtBName As String = "Txt"
leftX = 20: tWidth = 50
ReDim TBox(10) 'use here the maximum number of text boxes you intend creating
For i = 1 To 5
Set txtBox01 = Me.Controls.Add("Forms.TextBox.1", txtBName & i)
With txtBox01
.top = 10
.left = leftX: leftX = leftX + tWidth
.width = tWidth
.Text = "something" & i
End With
Set TBox(k).newTBox = txtBox01: k = k + 1
Next i
ReDim Preserve TBox(k - 1) 'keep only the loaded array elements
End Sub
Now, show the form and play with text in the 5 newly created text boxes.
You can show one of its instances in the next way:
a) Name it "frmTxtBEvents"
b) Use the next Sub:
Sub ShowTheForm()
Dim frm As New frmTxtBEvents
frm.Show vbModeless
End Sub
When enter 4 characters, according to the last text box name digit their Change event will show specific message boxes...
If something not clear enough, do not hesitate to ask for clarifications.
But it is late in my country and (today) I will be available for no more than half an hour.
I have inserted the following three buttons into my Excel spreadsheet:
I am using a German Excel version: Schaltfläche = Button
As you can see the buttons are counted by 1,2,3 and each additional button will get the next higher count number.
Now, I run the following VBA to delete all buttons:
Sub Delete_Buttons()
Sheet1.Select
Sheet1.Buttons.Delete
End Sub
After I run this VBA I insert the buttons again:
As you can see the buttons are counted starting from 3.
How can I reset the count of the buttons and make the count starting from 1 again?
or you could use a sub that "orders" the buttons text by their Left property
this example uses a SortedList object
Sub Rename_Buttons()
With CreateObject("System.Collections.SortedList")
Dim btn As Button
For Each btn In Sheet1.Buttons
.Add btn.Left, btn
Next
Dim j As Long
For j = 0 To .Count - 1
.GetValueList()(j).Text = "Button" & j + 1
Next
End With
End Sub
You could also use:
Sub create_new()
Dim counter As Long, MaxValue As Long, i As Long
Dim btn As Button, btnNew As Button
Dim FullBtnName As String
counter = 3
MaxValue = 0
'You could change sheet name
With ThisWorkbook.Worksheets("Sheet1")
'Loop all butons in the sheet
For Each btn In .Buttons
'Split the name to get its number
FullBtnName = btn.Name
If CInt(Split(FullBtnName, " ")(1)) > MaxValue Then
'Get the max number
MaxValue = CInt(Split(FullBtnName, " ")(1))
End If
Next btn
'Loop 3 times to create 3 shhets
For i = 1 To 3
Set btnNew = .Buttons.Add(.Range("A" & i + 5).Left, .Range("A" & i + 5).Top, .Range("A" & i + 5).Width, .Range("A" & i + 5).Height)
'Change button name & caption
With btnNew
.Caption = "Button " & MaxValue + i
.Name = "Button" & MaxValue + i
End With
Next i
End With
End Sub
The best way to solve this issue is:
Run the VBA to delete all buttons:
Sub Delete_Buttons()
Sheet1.Select
Sheet1.Buttons.Delete
End Sub
Save the file and close it.
Re-open the file and then insert the buttons again.
(Now it starts counting from Button 1 again)
So here's my objective: I need to execute different macros deppending on a multiple choice ListBox. I am a begginner with vba and some tasks get a bit harder for me at the moment.
there's a multiple choice ListBox with 9 options. If you choose the option "Exfoliación", it executes the macro called "macro4". This is fully customizable, so if I choose from the ListBox the option "Exfoliación" and "Estanqueidad", it will execute the macros 4 and 3 (the ones related to them).
I've seen some example surfinf the Internet, but they're about ListBox's working with columns, sheets, and so on. But there weren't much explanations working with macros.
The user selects the options and presses a Submit button in the worksheet called "Botón". the choices from the Listbox are marked with vector(i)=1. With a for loop the choices are read and executes the corresponding macros to those choices with the array a(i) that contains the names of those macros.
Sub Submit()
'Getting selected items in ListBox1
Dim vector(1 To 11) As Integer
Dim i As Integer
Dim a(1 To 9) As String
'Private Sub CommandButton1_Click()
For i = LBound(a) To UBound(a)
vector(i) = 0
Next i
With Sheets("Botón").ListBox1
Select Case (ListBox1.Text)
Case "Tornillo Resorte": vector(1) = 1
Case "Categoría Manguito": vector(2) = 1
Case "Estanqueidad": vector(3) = 1
Case "Exfoliación": vector(4) = 1
Case "Material vaina": vector(5) = 1
Case "Diseño EC": vector(6) = 1
Case "Curva Q vs Enriquecimiento": vector(7) = 1
Case "Curva Criticidad": vector(8) = 1
Case "Curva de carga t. enfriamiento": vector(9) = 1
Case "Condicioón de transporte": vector(10) = 1
Case "ATI": vector(11) = 1
Case ""
MsgBox "nothing selected"
Case Else
MsgBox Me.ListBox1.Text
End Select
Dim MN As String
For i = 1 To N 'Fill the array
a(i) = "macro" & i
Next
MN = "Módulo5" 'Module where i have the worksheet I'm working with
Dim N As Integer
N = 11
For i = LBound(a) To UBound(a)
If vector(i) = 1 Then
Application.Run MN & "." & a(i)
End If
Next i
End Sub
I find trouble with the Select Case (ListBox1.Text) statement.
It doesn't compile and don't know how to call the listBox with Select Case.
thank you in advance for your help :)
Edit: with a new code. Method with selection:
`Private Sub Command Button1_Click() 'This is a button that opens the multilist with the different options. It works correctly
Worksheets("Botón").ListBox1.Clear
ListBox1.Height=200
ListBox1.Width=250
Dim mylist As Variant
mylist=Array("Tornillo Resorte",...,"Condicioón de transporte")
ListBox1.List=mylist
End Sub
Sub Submit() ''here's the macro with the button assigned to execute the selection. This is where I get the problem.
With Sheets("Botón").ListBox1
MN = "Módulo5" 'Module where i have the worksheet I'm working with
For X = 0 To ListBox1.ListCount - 1
If ListBox1.Selected(X) = True Then
Application.Run MN & "." & .ListIndex + 1
Else
MsgBox "No se ha seleccionado ningún filtro"
End If
Next X
End With
End Sub
If you only wanted to select one macro - and assuming the macros are named sequentially macro1 to macrox, then you can just do this:
Sub Submit()
With Sheets("Botón").ListBox1
if .listindex = -1 then
MsgBox "nothing selected"
Else
MN = "Módulo5" 'Module where i have the worksheet I'm working with
Application.Run MN & "." & .listindex +1
End If
End With
End Sub
If you want to do more than one then you need to loop through the .selected array calling the macros sequentially
So I've been working on a spreadsheet that I'm going to use as a template for several more spreadsheets and I've gotten most of the template finished but I would like to add a feature involving the spinbar.
Currently I have 100 input buttons displayed and I know that I will not need 100 buttons for all the possible uses of the template, I just included 100 as a max.
I am looking to add a 1 - 100 spinbar so that it will automatically show/hide buttons depending on the number associated with the spinbar.
I should have no issues figuring out how to hide the buttons or show the buttons, but I cannot figure out the proper code to have buttons visible between 1 - 100.
Sub LocNum ()
Dim i As Integer
Dim n As Integer
n = Worksheets(1).Cell
For i = 1 To n
That's about as far as I can get, so if n is equal to 37 it should only have 37 buttons visible.
I'm getting my code from something I typed up previous before I took a break from it for quite awhile, here is the code.
Sub Populate()
Dim t As Integer
Dim i As Integer
Dim a As String
t = ActiveWorkbook.Sheets.Count - 1
i = 0
For i = 2 To t
a = i - 1
If (ActiveSheet.Shapes("" + "btn.index" & i).Visible = True) Then
ActiveSheet.Shapes("" + "btn.index" & i).Select
Selection.OnAction = "" + "Location" & a + ""
Selection.Characters.Text = ActiveWorkbook.Worksheets(i).Name
Else
Exit Sub
End If
Next i
End Sub
Any help would be appreciated.
Not entirely sure your workflow, but this can help you show/hide the buttons either based on the index (I don't recommend) or the name of the button. You just call this Sub providing the number of buttons to show, rest (index/name higher than the number) will be hidden.
I will let you play with the OnAction.
Option Explicit
Sub ShowButtonsUpTo(ByVal ButtonCount As Long)
Dim oButton As Button ' or Object
For Each oButton In Worksheets(1).Buttons
With oButton
' Based on Index (not recommend):
.Visible = (.Index <= ButtonCount)
' Based on Name (button name):
If InStr(1, .Name, "btn.index", vbTextCompare) = 1 Then
.Visible = (CLng(Replace(.Name, "btn.index", "")) <= ButtonCount)
End If
End With
Next oButton
End Sub
I dynamically create a userform named UserForm1. In it, I generate textboxes, which will be filled manually by a user. Afterwards I would like to read their value but I don't know how to call the (value of the) textbox.
The following bit of code is used to create and name the textboxes:
With UserForm1 'scaling userform
.Height = max_width
.Width = 600
End With
For test1 = 1 To nr_of_zeros + 1 'create textboxes
Set ctextbox = Controls.Add("forms.textbox.1", test1) 'creating textbox
With ctextbox 'scaling textbox
.Height = 20
.Width = 40
.Top = 40 + 25 * test1
.Left = 400
End With
So the textbox will have the name of the number (integer or long?) of test1.
I tried the following sentences to try to read the value of the textbox into: absorb_text but unsuccesfull so far. Does anybody know the correct complete way to call the above created textbox?
'ctextbox.name = Controls.Add("forms.textbox.1", test1) 'creating textbox
'absorb_text = forms("textbox").Controls(test1).Value
'absorb_text = forms.("UserForm1").textbox.(test1).value
forms.textbox.1.(test1)
strname = TextBox1(test1).Text
(Analog to, one does not call cell "A2" by)
.range("A2")
but with
Thisworkbook.worksheets("sheetname").range("A2").text
Thisworkbook.worksheets("sheetname").range("A2").value
Thisworkbook.worksheets("sheetname").cells(2,1).text
Thisworkbook.worksheets("sheetname").cells(2,1).value
Thank you very much! I was still wondering why/what the 1 does in "forms.textbox.1" I copied it because it worked, but am confused by its function.
Also in light of your discussion below: I believe, technically the code does not look for a control name that is equal to the/a number 1 but to a string character which happens to equal the character 1. hence it is not equal to a number but a character.
*argument against that is that it still works with: `If ctrl.Name = 1 Then' in which case I would think the 1 is treated as a number.
When you created your TextBoxes in your code line:
Set ctextbox = Controls.Add("forms.textbox.1", test1) the names of your Textboxes is 1, 2, 3, etc.
In order to read your TextBoxes (created at run-time) I loop through all Controls of the User_Form, check if it's type TextBox, and check the Name property of the Control.
Code
Option Explicit
Private Sub ReadRunTimeTextBox()
Dim ctrl As Control
Dim absorb_text As String
' loop through all control in user form
For Each ctrl In Me.Controls
' check if control is type TextBox
If TypeName(ctrl) = "TextBox" Then
' if control name is 1 (first created TextBox in your array)
If ctrl.Name = "1" Then
absorb_text = ctrl.Text
' the message box is for debug only
MsgBox absorb_text
End If
End If
Next ctrl
End Sub
Here are two more ways to refer to the dynamically added control
Const nr_of_zeros = 4
For test1 = 1 To nr_of_zeros + 1 'create textboxes
Debug.Print Controls(test1)
Next
Debug.Print Me![1]
Debug.Print Me![2]
Debug.Print Me![3]
Debug.Print Me![4]