Passing userform textbox values to a function - vba

I'm trying to use a mathematical function entered into a userform and evaluate it at a specific point. I'm not sure if this is possible as I'm fairly new to VBA. When I enter 24 * t - 1.2 * t ^ 2 into the textbox and hit the command button I get a type mismatch error.
Here's the code I'm using.
Function vel(t)
vel = TextBox1.Value
End Function
Private Sub CommandButton1_Click()
Dim outp As Long
outp = vel(5)
MsgBox outp
End Sub

Related

How do I refer to form object within report code

I know I had a similar post but it was closed before it was solved. I have more information now that might help. All the code is on the report vba module. So I’m trying to call a form object with report code
Code:
Do.Cmd.OpenForm “FormOne”, acNormal
Forms!FormOne.Visible = False
If Forms!FormOne.Form!Authorization.Value = 1 Then
Me.Label1.Caption = “Report A Details”
ElseIf Forms!FormOne.Form!Authorization.Value = 2 Then
Me.Label1.Caption = “Report B Details”
End If
End Sub
The part where I open the form and make it invisible works. The If/Else statement doesn’t work but also doesn’t give any errors. I also tried replacing the second (!) with (.) but the same thing happened.
Because question was typed on iPad my quotes look like smart quotes.
I would prefer to set the title using the report OpenArgs property. Here is your form button click event.
Private Sub Command1_Click()
Dim args As Variant
If Me.Authorization.Value = 1 Then
args = "Report A Details"
ElseIf Me.Authorization.Value = 2 Then
args = "Report B Details"
End If
DoCmd.OpenReport "Report1", acViewPreview, OpenArgs:=args
End Sub
and here is the report open event
Private Sub Report_Open(Cancel As Integer)
If Not IsNull(Me.OpenArgs) Then
Me.Label1.Caption = Me.OpenArgs
End If
End Sub

Advanced customization of InputBox edit control

So I have some basic VBA code:
Sub Test()
' Set error handler
On Error GoTo ErrorHandler
Dim strElevation As String
strElevation = InputBox("Enter elevation difference:", "Create Cross Lines", 0.5)
Exit Sub
ErrorHandler:
Call ReportError("Test")
End Sub
And it looks fine:
Is it possible to extend this so that the edit box will only allow a numeric value to 2 decimal places? Or is it simply too much work?
I know how to format text itself, eg: Format("1234.5678", "#.00"). But can the actual edit control have any customization itself?
You basically have three options here... In order of difficulty:
1. Validate the input
This uses the native InputBox() function as you have in your code sample above. You can return the value into a string variable, then do your validation at that point to make sure the data is formatted the way you want. If it doesn't pass, then display the input box again.
2. Custom VBA form
If you create your own VBA User Form, you can customize the text box to use a specific format, and perform the validation before the form accepts the input and closes. This is probably the most user-friendly approach, but involves a little more code than the first method.
Example:
Create sample VBA form with two input boxes and a command button. Name them txtDiff1, txtDiff2, and cmdOK respectively.
Double-click one of the controls, and add the following code to the code module behind the form:
Option Explicit
Private Sub cmdOK_Click()
MyElevationDifference = txtDiff1 ' (or txtDiff2)
Unload Me
End Sub
Private Sub txtDiff1_AfterUpdate()
Dim dblValue As Double
If IsNumeric(txtDiff1) Then
' Determine rounded amount
dblValue = Round(txtDiff1, 2)
' Automatically round the value
If dblValue <> CDbl(txtDiff1) Then txtDiff1 = dblValue
Else
MsgBox "Please enter a numeric value", vbExclamation
End If
End Sub
Private Sub txtDiff2_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
Dim dblValue As Double
If IsNumeric(txtDiff2) Then
' Determine rounded amount
dblValue = Round(txtDiff2, 2)
' Require a max of 2 decimal places
If dblValue <> CDbl(txtDiff2) Then
Cancel = True
MsgBox "Please only use 2 decimal places", vbExclamation
End If
Else
MsgBox "Please enter a numeric value", vbExclamation
' Cancel change
Cancel = True
End If
End Sub
Paste the following into a regular code module. (This is how you can get the input in your main code through the custom form. Essentially the form assigns a value to the global variable, and you reference that after showing the form.)
Option Explicit
Public MyElevationDifference As Double
Public Sub GetElevationDifference()
UserForm1.Show
MsgBox "Elevation difference: " & MyElevationDifference, vbInformation
End Sub
Now when you run GetElevationDifference(), you will see a couple different approaches demonstrated on the user form. The first text box automatically rounds the input, while the second text box does not allow the user to continue unless they correct the input to use two decimal places or less.
Of course you will want to add some error handling and make the form look nice, but this gives you a simple example of how to use a VBA form to get user input. They involve a little more code, but obviously provide a huge level of additional flexibility over the simple InputBox() function.
3. Windows API calls
Just for completeness, there are ways to use Windows API calls to actually affect the controls on an input box, but this would end up being far more complex than the first two approaches, and I would not recommend it for something like this.
this is how you can restrict to input box to allow only numeric values:
strElevation = Application.InputBox(prompt:="Enter elevation difference:", Title:="Create Cross Lines", Default:=0.5, Type:=1)
https://msdn.microsoft.com/en-us/vba/excel-vba/articles/application-inputbox-method-excel
To validate the lenght, you can use the following code:
Do
strElevation = Application.InputBox(prompt:="Enter elevation difference:", Title:="Create Cross Lines", Default:=0.5, Type:=1)
If Len(strElevation) > 2 Then MsgBox "You typed in too many characters... 2 maximum!"
Loop While Len(strElevation) > 2
Private Sub TextBox1_AfterUpdate()
If InStr(1, Me.TextBox1.Value, ".") > 0 Then
If Len(Mid(Me.TextBox1.Value, _
InStr(1, Me.TextBox1.Value, "."), _
Len(Me.TextBox1.Value) - InStr(1, Me.TextBox1.Value, "."))) > 2 Then
Me.TextBox1.SetFocus
MsgBox "cannot have more than 2 decimal places"
End If
End If
End Sub
Apply to your situation but this gets you there
Sub Test()
' Set error handler
On Error GoTo ErrorHandler
Dim strElevation As String
strElevation = InputBox("Enter elevation difference:", "Create Cross Lines", 0.5)
If InStr(1, strElevation, ".") > 0 Then
If Len(Mid(strElevation, InStr(1, strElevation, "."), Len(strElevation) - InStr(1, strElevation, "."))) > 2 Then
MsgBox "cannot have more than 2 decimal places"
End If
End If
Exit Sub
ErrorHandler:
Call ReportError("Test")
End Subc

VBA : InputBox wrongly used previous User Input without prompting for new input

This is the VBA code I am learning to write (got some reference from the Internet)
Public whatyousay As String
Sub testing()
b14
b15
End Sub
Function WorksheetExists(WSName As String) As Boolean
On Error Resume Next
WorksheetExists = Worksheets(WSName).Name = WSName
On Error GoTo 0
End Function
Sub b14()
Dim sh As Worksheet
Do Until WorksheetExists(whatyousay)
whatyousay = InputBox("Enter sheet name")
If Not WorksheetExists(whatyousay) Then MsgBox whatyousay & " doesn't exist.", vbExclamation
Loop
If WorksheetExists(whatyousay) Then Sheets(whatyousay).Activate
End Sub
Sub b15()
ThisWorkbook.Worksheets(whatyousay).Range("A1").Value = xxxx
End Sub
I must have wrongly adjust the code, as I can't find anyone having the same problem on the Internet.
When the button is clicked, it is supposed to prompt user input for the sheet name, then perform some actions.
Now, the problem I am facing is that the button only prompt user input for one time. If it was clicked the second time, it will used the previous user input without prompting.
Can anyone of you please point me to the right direction?
You are not erasing what was left in whatyousay during the last loop.
Sub b15()
ThisWorkbook.Worksheets(whatyousay).Range("A1").Value = xxxx
whatyousay = vbnullstring '<~~ remove the string from last time
End Sub
Personally, I avoid public vars. You can do the same thing by passing the string var into the secondary sub as a parameter.

VBA Error 1004 When Calling A Module with an Argument

This is my first post so bear with me.
I get a run-time error 1004 when I try calling a module from my user form and passing on an argument. I'm sure the answer is pretty obvious but I'm new to passing on arguments.
From User Form when clicking submit button:
Sub SubmitButton_Click()
Dim addRowValue As Integer
addRowValue = LineBox.Value
MsgBox "Add " & addRowValue & " rows."
Call Sheet1.ResizeTable(addRowValue)
End Sub
From Sheet1:
Sub ResizeTable(addRowValue As Integer)
Dim rng As Range
Dim tbl As ListObject
Set tbl = ActiveSheet.ListObjects("DATA_INPUT")
Set rng = Range("DATA_INPUT[#All]").Resize(tbl.Range.Rows.Count + _
addRowValue, tbl.Range.Columns.Count)
tbl.Resize rng
End Sub
Call Sheet1.ResizeTable works fine but when I add the argument is when I get the error. Also, the module ResizeTable() works fine when I change the variable addRowValue to a set number and run it.
Thanks for any help!
Problem is you are assigning a string to variable of type integer.
Change
addRowValue = LineBox.Value
To
addRowValue = CInt(LineBox.Value)
EDIT: You might also want to ensure the user enters a numeric value so have something like:
If IsNumeric(LineBox.Value) Then
addRowValue = CInt(LineBox.Value)
Else
MsgBox "Please enter numeric value", vbCritical
LineBox.Value = ""
End If

How to Select All Text in TextBox After textBox.Setfocus Using Access VBA

I need to select all the text in a textbox of an Access form when I click (or double click) into it. i tried the following code, unsuccessfully:
Me.txt_CompraPreco.SelStart = 0
Me.txt_CompraPreco.SelLength = Len(Me.txt_CompraPreco)
thanks in advance.
You can use the code shown below. If it doesn't work, place a breakpoint at the first line of code. If it doesn't stop on your breakpoint, then your event is not recognized.
Option Compare Database
Option Explicit
Private Sub txt_CompraPreco_Click()
If Len(Me.txt_CompraPreco & "") = 0 Then Exit Sub
Me.txt_CompraPreco.SelStart = 0
Me.txt_CompraPreco.SelLength = Len(Me.txt_CompraPreco)
End Sub
I was looking for a solution regarding this problem, I have the same issue, however, I have a solution to it, I'm not sure if it's efficient, but here's my code:
'Declare a flag
Public flagDblClick As Boolean
'Double click event
Private Sub txtbox_DblClick (Cancel As Integer)
flagDblClick = True
End Sub
'Mouse up Event
Private Sub txtbox_MouseUp(Button As Integer, Shift As Integer, X as Single, Y as Single)
If flagDblClick Then
flagDblClick = False
txtBox.SelStart = 0
txtBox.SelLength = Len(txtBox.Value)
End If
End Sub
This code will resolve your problem (use with userform).
txt_CompraPreco.SetFocus
Me.txt_CompraPreco.SelStart = 0
Me.txt_CompraPreco.SelLength = Len(Me.txt_CompraPreco)
My trial and error found this.
If your textfield is formatted as a Standard Number and you have set the decimal places to a certain length, you will run into trouble when you enter a single digit. For example if your decimal places in the field properties is set to 2 and you enter "1", you will display "1.00". To get the entire field (1.00) selected, you must specify the .Text property when you determine the .SelLength (not the default .Value property)
Me.txtYourFieldname_GotFocus
Me.txtYourFieldName.SelStart = 0
Me.txtYourFieldName.SelLength = Len(Me.txtYourFieldName.Text)
End Sub
This works for me:
Dim bSelect As Boolean
Private Sub fieldX_Click()
If bSelect Then
'Select text only at first mouse click then user can click again
'and is able to put mouse pointer where he prefers
Me.fieldX.SelStart = 0
Me.fieldX.SelLength = Len(Me.fieldX)
bSelect = False
End If
End Sub
Private Sub fieldX_GotFocus()
bSelect = True
'Select text if field got focus via keyboard, Enter or TAB
'this is not enough if field got focus via mouse click
Me.fieldX.SelStart = 0
Me.fieldX.SelLength = Len(Me.fieldX)
End Sub