Auto Resize a CommandButton based on string length - excel

I have several commands buttons with text whose captions change based on various inputs. Also want to mention that these are command buttons on the worksheet itself, not on a form.
Is there a way to Auto Resize so that the button width accommodates the length of the text?
Here's a snippet of the pertinent code:
Sub FixButtonWidth()
'Create Button
Set rbtn = ActiveSheet.Buttons.Add(0, 0, 30, 20)
'User enters a string of some length
ShowThis = InputBox("What do you want to call your button?", "Button Name", "")
'Button Caption changes to whatever the user input
rbtn.Caption = ShowThis
'This next line is the problem:
'The width needs to be based on the width of the string
'Len(ShowThis) only gives the number of characters in the string . . .
'Since letters like 'Z' are much wider than letters ...
'like i (for example), Len(ShowThis) is not a good solution.
rbtn.Width = 500
End Sub

Like I said use rbtn.AutoSize = True after the set rbtn... part. And remove rbtn.width = 600
Sub FixButtonWidth()
'Create Button
Set rbtn = ActiveSheet.Buttons.Add(0, 0, 30, 20)
'User enters a string of some length
ShowThis = InputBox("What do you want to call your button?", "Button Name", "")
rbtn.AutoSize = True
'Button Caption changes to whatever the user input
rbtn.Caption = ShowThis
'This next line is the problem:
'The width needs to be based on the width of the string
'Len(ShowThis) only gives the number of characters in the string . . .
'Since letters like 'Z' are much wider than letters like i, for example Len(ShowThis) is not the solution
'rbtn.Width = 500
End Sub

Related

Changing Value of Combo Box to another Value in VB

I am trying to change the value of a combo box value "Black Shredded - 7.90" to just show "Black Shredded" when it is selected
Dim intIndex As Integer
Dim strString1 As String
Dim strString2 As String
strString1 = cboProduct.SelectedItem
intIndex = strString1.IndexOf(" ")
strString2 = strString1.Remove(intIndex + 9)
If cboProduct.SelectedIndex = 0 Then
cboProduct.Text = strString2
End If
I went through the values and they show as they should but it isn't changing the combobox value what could I be doing wrong?
If you have just added Strings to the ComboBox in the first place then you need to replace the existing item with the new value. This:
cboProduct.Text = strString2
should be this:
cboProduct.Items(cboProduct.SelectedIndex) = strString2
You can just use 0 rather than cboProduct.SelectedIndex, given that you have already confirmed that that is the index at that point.
Setting the Text property doesn't affect the items at all. If DropDownStyle is set to DropDown then the specified text will be displayed but no item will be selected. If DropDownStyle is set to DropDownList then the item with that text will be selected, if one exists. Either way, no item is added or changed.

Problem with multiline string in userform

I am having a issue with multiline stings in a userform.
When a user selects a option, the code checks if the selected answer matches the correct answer and then shows if right or wrong. But in either case the code says it is wrong.
Example of a option is:
If you see the string, brush it off sideways
Place icepack/cold flannel to reduce swelling
Elevate area to reduce bloodflow
Private Sub OptionButton1_Click()
rowNum = Selection.Row - Selection.ListObject.Range.Row
DeclareVars
Column = examtable.ListColumns("Right ans").DataBodyRange(rowNum)
CorrectAns = examtable.ListColumns("Right ans").DataBodyRange(rowNum).Offset(0, Column)
RightWrong.Visible = True
If OptionButton1.Caption = CorrectAns Then
RightWrong.BackColor = &HFF00&
RightWrong.Caption = "Right"
Else
RightWrong.BackColor = &HFF&
RightWrong.Caption = "Wrong"
End If
End Sub
What i am expecting is that if correct, shows right, or wrong if incorrect
If I understand correctly you have multiple option buttons below one another? Option button one will always have the same caption. If it is selected it can become true (indicated by the black dot), but the caption will not change.
Lets say it looks like this
two option buttons
Then the upper is called OptionButton1, the lower OptionButton2.
You can check
If OptionButton1 then
RightWrong.BackColor = &HFF00&
RightWrong.Caption = "Right"
Else
RightWrong.BackColor = &HFF&
RightWrong.Caption = "Wrong"
End if
You could use a combobox (these are the drop down menus).
You could populate it with an array of the strings you want to test and ask if the answers concur.
When loading the user form use
Private Sub UserForm_Activate()
ComboBox1.list = Array("brush it off sideways", "Place icepack/cold flannel to reduce swelling", "Elevate area to reduce bloodflow")
End Sub
this will look as followed
The user form with the list open
Then you can say combobox.value = CorrectAns

Roman numeral page numbers for table of contents

I'm generating word docs entirely in VBA and am aiming to have roman numeral page numbers for my table of contents and numeric page numbers for the remainder of the document. My table of contents spans multiple pages and is variable in page size.
How would I achieve roman numeral page numbers for only a table of contents of variable page span?
Any help would be greatly appreciated.
If you don't know where to start, try this approach in Word:
Insert a section break after the table of content pages.
Turn on the macro recorder
Format the page numbers in the first section with Roman numerals
select the next section and unlink it from the previous section
Format the page numbers in the second section with regular numbers
Turn off the macro recorder.
Adjust the code as required.
I also find Word fiddly in this area, so here's some code to show one possible example. The code clears the content of the current document (so don't run it in your existing document!!), then generates a few headings, followed by a table of contents, both of which are then split by a section break. The section break allows different formatting of the page number (roman numerals for the first section, and arabic for the second). Change the for loop up to 100 will demonstrate multiple ToC pages. Might point you in the right direction. Cheers.
Option Explicit
Public Sub PageNumbers()
Dim myRange As Range
Dim Counter As Long
Dim myTOC As TableOfContents
' Delete word document content
ActiveDocument.StoryRanges(wdMainTextStory).Delete
' Add in some headings for testing
Set myRange = ActiveDocument.Range(0, 0)
For Counter = 1 To 10
myRange.InsertAfter "Heading " & Counter
myRange.Style = WdBuiltinStyle.wdStyleHeading1
myRange.InsertParagraphAfter
Next
' Add in a page number
With ActiveDocument.Sections(1)
.Footers(wdHeaderFooterPrimary).PageNumbers.Add _
PageNumberAlignment:=wdAlignPageNumberLeft, _
FirstPage:=True
End With
' Add in a section break at the start of the document
Set myRange = ActiveDocument.Range(0, 0)
myRange.InsertBreak Type:=wdSectionBreakNextPage
myRange.InsertParagraphAfter
' Insert a table of contents (into the first section)
Set myRange = ActiveDocument.Range(0, 0)
Set myTOC = ActiveDocument.TablesOfContents.Add(myRange, True, 1, 3, False)
' Format the page number of the first section to have roman numerals
With ActiveDocument.Sections.Item(1).Footers.Item(1).PageNumbers
.NumberStyle = wdPageNumberStyleLowercaseRoman
.HeadingLevelForChapter = 0
.IncludeChapterNumber = False
.ChapterPageSeparator = wdSeparatorHyphen
.RestartNumberingAtSection = False
.StartingNumber = 0
End With
' Format the page number of the second section to have arabic numerals
With ActiveDocument.Sections.Item(2).Footers.Item(1).PageNumbers
.NumberStyle = wdPageNumberStyleArabic
.HeadingLevelForChapter = 0
.IncludeChapterNumber = False
.ChapterPageSeparator = wdSeparatorHyphen
.RestartNumberingAtSection = True
.StartingNumber = 1
End With
End Sub
The Output:

Draw Shape Based on Cell Values

All,
I have code that creates a shape based on based on inputted values in the macro itself. I am wanting to have the values of shape type, width, and height specified by the user (location of shape on the sheet is indifferent to me right now). The user would input the aforementioned numerical values for width and height into the cells and click a button which would output the shape type and size the user wants.
In my case, there will be a drop down box for "rectangle" and "circle". I don't know how to get the code to read those words and convert it '1' and '9', respectively. I may just have the user choose 1 or 9 to create the shape.
I would also like to add text to the center of the shape. Again, I have created a code for this but it is within the macro. I would like to have the code reference a cell value instead. I assume it would be the same as above.
Thank you for any assistance.
Sub AddShape()
Dim s As Shape
Dim ws As Worksheet
Set ws = Sheets("Deck Layout")
'add a shape
Set s = ws.Shapes.AddShape(1, 80, 80, 75, 75)
'make it nearly white
s.Fill.ForeColor.RGB = RGB(245, 245, 255)
'show text within it
s.TextFrame.Characters.Text = "1"
s.TextFrame.Characters.Font.ColorIndex = 2
With s.TextFrame.Characters(0, 0)
s.TextFrame.HorizontalAlignment = xlHAlignCenter
s.TextFrame.VerticalAlignment = xlVAlignCenter
.Font.Color = RGB(0, 0, 0)
End With
End Sub
Since you've already got parts of the answer in the comments, I'll focus on the shape picking.
Have a look at this:
Dim ShapeType As MsoAutoShapeType
Select Case LCase(ws.Range("b1").Value)
Case "rectangle"
ShapeType = msoShapeRectangle
Case "circle"
ShapeType = msoShapeOval
End Select
Set s = ws.Shapes.AddShape(ShapeType, 80, 80, 75, 75)
It will find the value in B1, convert it to lower case and the test it for "rectangle" and "circle" and the set the ShapeType to a corresponding value.
You can use 1 and 9 instead, but that is bad practice. Use the defined constants - it will make your code much easier to read.

Validate a TextBox before the _Change event is fired

I've got a form that has 3 TextBox controls on it: stock code, quantity, certificate number. The stock code TextBox is set to focus automatically when the form is loaded.
I've also attached a bar code scanner to my PC, as the user wants to be able to either scan a bar code to populate the TextBox, or manually type the data in.
The labels being scanned contain two bar codes. One is a certificate number and the other a stock code.
The stock bar code has a prefix of "SBC/", whilst a certificate bar code is prefixed with "C/".
When the user scans a bar code, if the TextBox in focus is the stock code TextBox, then I want to run a check as below.
Private Sub txtStockCode_Change()
On Error GoTo errError1
If Len(txtStockCode.Text) >= 5 Then
If bChangeCode Then
If Left(txtStockCode.Text, 2) = "C/" Then
msgbox "You have scanned the certificate barcode; please scan the stock barcode."
txtStockCode.Text = ""
Else
bChangeCode = False
txtStockCode.Text = Replace(txtStockCode.Text, "SBC/", "")
txtStockCode.Text = Replace(txtStockCode.Text, "*", "")
End If
End If
End If
Exit Sub
Let's say the focus is currently on the stock code TextBox.
If the stock bar code is scanned, the following should happen:
Stock code length is greater than 5
Left 5 characters do not = "C/", so correct code has been scanned
TextBox text value is updated to remove all * and the prefix of "SBC/"
E.g. "SBC/A12-TR0*" becomes "A12-TRO"
and
Certificate number length is greater than 5
Left 5 characters do = "C/", so incorrect code has been scanned
MsgBox to user
TextBox value is reset to ""
However, no matter which code is scanned into the stock code TextBox, the value is never validated.
E.g. "SBC/A12-TR0*" remains as "SBC/A12-TR0*" and "C/29760" remains as "C/29760"
As the validation code is the same in the certificate TextBox, the same pattern is repeated vice versa.
Why are my values not updating, or how can I validate the input before the _Change is fired?
EDIT
I've now changed my code to
Private Sub txtStockCode_Change
If txtStockCode.Text <> "" Then
txtStockCode.Text = Replace(txtStockCode.Text, "SBC/", "")
txtStockCode.Text = Replace(txtStockCode.Text, "*", "")
End If
End Sub
But it still displays the prefix of SBC/, yet is removing the two * characters (at the start and end of the barcode as is required for the scanner to read it as a barcode)
You could try to set the barcode reader to return Enter key at the end of the scanned barcode and then use the Keypress event to check it and make your changes.
Sub txtStockCode_KeyPress(KeyAscii As Integer)
If KeyAscii = vbKeyReturn Then
If Len(txtStockCode.Text) >= 5 Then
If bChangeCode Then
If Left(txtStockCode.Text, 2) = "C/" Then
msgbox "You have scanned the certificate barcode; please scan the stock barcode."
txtStockCode.Text = ""
Else
bChangeCode = False
txtStockCode.Text = Replace(txtStockCode.Text, "SBC/", "")
txtStockCode.Text = Replace(txtStockCode.Text, "*", "")
End If
End If
End If
End If
End Sub

Resources