Ok, so I have a series of input boxes pop up for the user and I know I want to check if the user hits cancel or "X" then I will have to check its return value.
EX answer = inputbox("lelele") if answer = "" then end else end if.
My problem is I have 4 input boxes in a row and I don't want to have to do a separate if statement for every input box so is there a way I can check all three in some sort of try catch block or while loop?
Below is the code I am actually using. Keep in mind that I am trying to catch a cancel every step along the way, so any time anyone clicks cancel the program immediately stops running.
'column you want to first select for copying
ColSelect = InputBox("which column do you want to select ColCopyFrom")
'the column you are comparing it to
ColCompare = InputBox("which column do you want to compare to ")
'where you are copying data from
ColCopyFrom = InputBox("which column do you want to copy data ColCopyFrom")
'where you are copying data to
ColCopyTo = InputBox("which column do you want to copy data to")
<
This is what I want to do for every box
if ColSelect = "" then
exit
else
'do nothing
end if
if ColCompare = "" then
exit
else
end if
You could wrap the inputbox into a function passing the prompt as a parameter like this and use END to break:
Function myInputBox(prompt As String) As String
Dim ib As String
ib = InputBox(prompt)
If ...
'... do some checking here
Else
End 'stop dead here
End if
myInputBox = ib
End Function
On the other hand, you might think about using a UserForm instead for enhanced usability.
Could you create a function and call it to check for each input? By creating a function once you can call upon it as many times as necessary, in your case 4 times. When you call the function you can then substitute the variable to check against
'first inputbox
Call checker(ColSelect)
'second input box
Call checker(ColCompare)
'etc
This is the function to check and you will see the variable name is cancel. This will take the variable entered (in the example ColSelect) and then give it a new name. This can be anything you like
sub checker(cancel)
if cancel = "" then
exit
else
'do nothing
end if
end Sub
Related
I created a couple of user forms which operate a data in separate report workbook. My script can successfully proceed a value in digit type. Unfortunately the circumstances have changed and now it has to work with a Serial Numbers as: 29160012040000TZ. With that new value script after starting the Sub, open a report, but it never enter into a 'with' statement. It doesn't look for a value or doing something else. Just open a report workbook and freeze.
Below you can see the code lines where issue is present and a little description:
Single_PHA is a text window in User Form where user can enter a a value, proceeding value is 29160012040000TZ
Private Sub Wydaj_button_Click()
Workbooks.Open Filename:="N:\ENGINEERING\1. ENGINEERS\Mateusz Skorupka\PHA_Cleaning_report_path\PHA_CLEANING_REPORT.xlsm", ReadOnly:=False
Dim REPORT As Workbook
Set REPORT = Application.Workbooks("PHA_CLEANING_REPORT.xlsm")
Set TABLE = REPORT.Worksheets("Main_table")
...
With TABLE.Range("A1")
If Single_PHA = True Then
If Not IsError(Application.Match(Single_PHA.Value, .Range("A:A"), 0)) Then
Single_PHA_row = TABLE.Range("A:A").Find(What:=Single_PHA.Value, LookIn:=xlValues).Row
.Offset(Single_PHA_row - 1, 4).Value = Date
REPORT.Close SaveChanges:=True
Single_PHA.Value = ""
Exit Sub
Else
MsgBox "Numer seryjny głowicy nie istnieje w bazie"
REPORT.Close SaveChanges:=False
Exit Sub
End If
End If
End With
In VBA I don't know how to open something like debugger or make the print instruction which would show me how the variables look on specific steps.
I am not sure if VBA read the value as 29160012040000TZ as string. I tried to declare at the beginning a variable as Single_PHA_STR as String and the proceed it as just text, but no wins there:
Dim Single_PHA_STR As String
...
With TABLE.Range("A1")
If Single_PHA = True Then
Single_PHA_STR = Str(Single_PHA.Value)
If Not IsError(Application.Match(Single_PHA_STR, .Range("A:A"), 0)) Then
Single_PHA_row = TABLE.Range("A:A").Find(What:=Single_PHA_STR, LookIn:=xlValues).Row
.Offset(Single_PHA_row - 1, 4).Value = Date
REPORT.Close SaveChanges:=True
Single_PHA.Value = ""
Exit Sub
Else
MsgBox "Numer seryjny głowicy nie istnieje w bazie"
REPORT.Close SaveChanges:=False
Exit Sub
End If
End If
End With
I noticed that if in VBA IDE I write a bold value 29160012040000TZ, I get an error
Expected line number or label or statement or end of statement
and the value is highlighted in red.
Could someone help me in that field and explain the nature of issues:
To reproduce a situation you can create a simply user form with one TextBox and one CommandButton. In the same worksheet as user form in a column A put a values: 29160012040000 and 29160012042027IR
Then make a sub which execute after double click on command button with code:
Private Sub CommandButton1_Click()
With Worksheets("Sheet1").Range("A1")
If Text_box1 = True Then
If Not IsError(Application.Match(Text_box1.Value, .Range("A:A"), 0)) Then
Text_box1_row = Worksheets("Sheet1").Range("A:A").Find(What:=Text_box1.Value, LookIn:=xlValues).Row
.Offset(Text_box1_row - 1, 4).Value = Date
Text_box1.Value = ""
Exit Sub
Else
MsgBox "PHA SN not exist in a database"
Exit Sub
End If
End If
End With
End Sub
Then try to input in a UserForm's TextBox a value = 29160012040000 and you will see that script successfully filled a forth column in row with current date. Then try to input a value 29160012042027IR and you will see that nothing happened. Script don't proceed that value at all.
So that is my issue and question indeed. How to process a value with letters at the end like: 29160012042027IR : )
I also tried to focus a script statement on one specific cell in which is a text value "29160012042027IR" that which I input into a UserForm TextBox. Looking with a debugger both of variables in if statement have the same text value, but still script miss that statement and go to else instructions : (
I mean abut: If Range("A3").Text = Text_box1.Text Then
When I change a statement for "If Range("A3").Value = Text_box1.Value Then" the same thing happen.
Private Sub CommandButton1_Click()
With Worksheets("Sheet1").Range("A:A")
If Text_box1 = True Then
If Range("A3").Text = Text_box1.Text Then
Text_box1_row = Worksheets("Arkusz1").Range("A:A").Find(What:=Text_box1.Value, LookIn:=xlWhole).Row
.Offset(Text_box1_row - 1, 4).Value = Date
Text_box1.Value = ""
Exit Sub
Else
MsgBox "PHA SN not exist in a database"
Exit Sub
End If
Else
MsgBox "Other loop"
End If
End With
End Sub
IMPORTANT NOTICE:
I found the main issue. I made wrong if condition, it should be:
If Single_PHA <> "" Then previously I have got: If Single_PHA = True Then, and there the results is a value not the boolean type.
Everything works. Thank everyone very much for help.
Topic is ready to be closed.
PS: thank you Tom for suggestion and tip with debugger: )
I created a field name 'tool_used' in which I specified some values and 'others' is one of its value. We can select multiple values from this box. I want to specify a condition that if the value of the field is others then a next field is visible that is 'other_tool'. I write a code for it but it gives a error 13 and when I debug it shows please specify a value in the field..
Please provide me the solution
My code is
Private sub tool_used_AfterUpdate()
If me.tool_used.value = "others" then
Me.other_tools.visible = true
Else
Me.other_tools.visible = False
End If
End sub
Since the list is multi select, you need to loop through the ItemsSelected.
Dim item As Variant
With YourListBox
For Each item In .ItemsSelected
Debug.Print .ItemData(item)
Next item
End With
What happens if more than one item is selected, one of them is "Other"?
Edit:
Loop and set a flag if the "Other" option is selected. If not, the other_tools control will remain hidden.
Dim item As Variant, flag As Boolean
With YourListBox
For Each item In .ItemsSelected
If .ItemData(item) = "Other" Then flag = True: Exit For
Next item
End With
other_tools.Visible = flag
A similar question has been asked multiple times, but I have a slightly different ask. I have used some code from superuser that restricts users from pasting values into data validation ranges:
Private Sub Worksheet_Change(ByVal Target As Range)
'Does the validation range still have validation?
If HasValidation(Range("DataValidationRange")) Then
Exit Sub
Else
Application.Undo
MsgBox "Error: You cannot paste data into these cells." & _
"Please use the drop-down to enter data instead.", vbCritical
End If
End Sub
Private Function HasValidation(r) As Boolean
'Returns True if every cell in Range r uses Data Validation
On Error Resume Next
x = r.Validation.Type
If Err.Number = 0 Then HasValidation = True Else HasValidation = False
End Function
This is great and it works, but I am wondering if it can be taken one step further. The reason users may want to paste into these fields is because they are moving data from one spreadsheet to the other. I have the validation there to ensure the spelling is correct (important for other uses). Is it possible for a user to paste something into the data validation field and it doesn't deny it, based on the code above, IF the value matches something inside the data validation list? Seems ambitious, not sure if it is possible.
Edit: The list is stored in another tab, not hardcoded into the data validation menu
If the Validation isn't Nothing and its type is xlValidateList (underlying value 3), then you can use Validation.Formula1 to get the "list".
That's the easy part.
If Formula1 doesn't start with an = sign, you're looking at a plain comma-separated list of values.
This function gets you a 1-dimensional array with all the valid values of the specified target, regardless of how the data validation list is defined:
Public Function GetValidationValues(ByVal target As Range) As Variant
Dim dataValidation As Validation
Set dataValidation = target.Validation
If dataValidation Is Nothing Then Exit Function
If dataValidation.Type <> xlValidateList Then Exit Function
Dim values As Variant
If Left$(dataValidation.Formula1, 1) <> "=" Then
'plain comma-separated list of values
values = Split(dataValidation.Formula1, ",")
Else
'validation list is a range address, or a named range
Dim rngValues As Range
Set rngValues = Application.Evaluate(dataValidation.Formula1)
If rngValues.Columns.Count > 1 Then
values = Application.Transpose(Application.Transpose(rngValues))
Else
values = Application.Transpose(rngValues)
End If
End If
GetValidationValues = values
End Function
All that's left to do is to determine whether your pasted value is in that array.
Hello I'm trying to automate a value into a website that has two list boxes in it.
For the first List box this code works, However It doesn't work for the second list box. I can't just copy and paste this code below it for the second one even if I change the variable "a". Any help is appreciated!
For a = 1 To cats.Options.Length
If cats.Options(a).Text = "Option One" Then
cats.selectedindex = a
Exit For
End If
Next a
If you're working with multiple lists then you should come up with a re-useable block of code which you can call for any list+value.
Something like:
Function SetByTextValue(lst as object, v as string) As Boolean
Dim a as long
For a = 0 To lst.Options.Length - 1
If lst.Options(a).Text = v Then
lst.selectedindex = a
SetByTextValue = True
Exit Function
End If
Next a
End Function
Then in your main code you can do something like:
If Not SetByTextValue(cats, "Option One") Then
'not found
Else
'...proceed with next list
End If
I have solid experience in C++ but am still getting used to the syntax of VBA and I think that's what's tripping me up in my code.
What I'm trying to do is have a button that asks the user for a name. If the name entered is in column B, then tell the user the name was found and select where it is (no problem with this). If the name is not found, then ask if the user wants to try another name (no problem with this, either).
Where I'm having trouble is with the "Cancel" buttons. At any time, I want the user to be able to hit "Cancel" and immediately stop the loop, but stay in the sub because I'll be adding to this later.
Here's the code:
Dim inputName As String
Dim row As Integer
Dim i As Integer
Dim tryAgainResponse As Integer
tryAgainResponse = vbOK
'Ask user for name they would like to replace'
inputName = InputBox("What is the name of the person you would like to find? (First Last)")
'Find the row that the name is located and tell the user where it is'
Do While tryAgainResponse = vbOK
For i = 1 To 1000
If Cells(i, 2).Value = inputName Then
MsgBox ("Found the name! It's located at cell B" & i & ".")
ActiveSheet.Cells(i, 2).Select
tryAgainResponse = 0
Exit Do
End If
Next i
tryAgainResponse = MsgBox("We didn't find the name you were looking for. Please try again.", vbOKCancel)
If tryAgainResponse = vbCancel Then
Exit Do
End If
inputName = InputBox("What is the name of the person you would like to find? (First Last)")
Loop
I've tried plenty of things, but the main error is when you hit cancel for the first MsgBox, it tells you the name was found in the first blank square.
Any help or suggestions would be greatly appreciated! This is my first VBA program, so it's not the prettiest, but it's definitely a lot of fun. Thanks!
I'm not sure if I'm understanding what you're asking for, and I can't comment for clarification, but I think your hang up is that when you click cancel on the INPUT box, your input box is returning a blank string, and the rest of your code is then finding a blank cell.
Use the Application.Input Method, declare your input string as a variant, and test if it is false. If it is, use an Exit Sub to exit the macro. You could also test if your input string = "" and then exit the macro if true with the code you have.
From MrExcel
There are 2 versions of InputBox in VBA.
The InputBox Function is called without an object qualifiier and returns the contents of the text box or a zero-length string ("") if the user clicks Cancel.
The InputBox Method is a member of the Application object, so it is called by using Application.InputBox. It returns the contents of the text box or False if the user clicks Cancel. It is more versatile than the InputBox Function because it has a Type argument which specifies the return data type.
The function InputBox() will return an empty string if cancelled. The empty string will compare equal to the first cell that is empty.
Here's the doc of the function: http://msdn.microsoft.com/en-us/library/6z0ak68w(v=vs.90).aspx