Edge cases in IsNumeric- is this overthinking it - vba

I have code which looks like this:
Select Case IsNumeric(somevariable)
Case True
Resume Next
Case False
Call notnum
Else
Call MyErrorHandler
End Select
Is this overthinking it? Is there a chance IsNumeric will return something other than True or False here or is this bad programming practice?

Don't need the else as it will be true or false however, just a note the Else should be Case Else (moot point though as you are about to delete it)
Based on this though I wouldn't use a case for only 2 options:
If IsNumeric(somevariable) then
Resume Next
Else
Call MyErrorHandler
End if
Edit: Here is how error checking works:
Sub SheetError()
Dim MySheet As String
On Error GoTo ErrorCheck
MySheet = ActiveSheet.name
Sheets.Add
ActiveSheet.name = MySheet
MsgBox "I continued the code"
ActiveSheet.name = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
MsgBox "I will never get to here in the code"
End
ErrorCheck:
If Err.Description = "Cannot rename a sheet to the same name as another sheet, a referenced object library or a workbook referenced by Visual Basic." Then
Resume Next
Else
MsgBox "Error I am not designed to deal with"
End If
End Sub
Copy and paste this module to your personal workbook or to a new workbook and run it, step through line by line using F8 to see how it is actually dealing with the error.

From OP's comment I'm not using my error handler. I want to do stuff with the hopefully numeric output
Sub demo()
Dim inputs As Variant
inputs = InputBox("Prompt", "Title", "Default")
If Not IsNumeric(inputs) Then
notnum
Else
' Do what you want with numeric input inside the Else
End If
' Maybe do more stuff irrespective of input
End Sub
Sub notnum()
' do not numeric stuff here
End Sub
Or if you want to keep prompting for numeric input until the users gets it right or cancels
Sub demo2()
Dim inputs As Variant
Do
inputs = InputBox("Enter something Numeric", "Title", "Default")
Loop Until IsNumeric(inputs) Or inputs = vbNullString
If Not inputs = vbNullString Then
' Do wht you want with numeric input inside the Else
End If
' Maybe do more stuff irrespective of input
End Sub

Input box can have different type of input validation. Try this
something = Application.InputBox("Pls Insert the Number", Type:=1)
If something = False Then Exit Sub
'Type:=0 A formula
'Type:=1 A number
'Type:=2 Text (a string)
'Type:=4 A logical value (True or False)
'Type:=8 A cell reference, as a Range object
'Type:=16 An error value, such as #N/A
'Type:=64 An array of values

Related

VBA_Processing a value as 29160012040000TZ

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: )

VBA User form gives warning if duplicate is found

I think I need to try and make this question easier. So here goes;
I am creating a User form in Excel that will act as a data capture form.
In this form I have a Textbox called PolBX In this a is placed and at submission data in PolBX is copied into the "G" column using this code
Cells(emptyRow, 7).Value = PolBX.Value. This works great.
I discovered that there may be instances where the User may accidently use the same Unique Id number twice. so I am trying to find out how to code it that after the User has entered the Unique Id number it would check for that string (Consists of letters and numbers). if it finds the string already in the 7th column(G) it must say something like
"Policy number already Used, please try again"
I am thinking I will need to use the following subroutine
Private Sub PolBX_AfterUpdate()
End Sub
Can some please assist with creating this code...
Also can you please explain what you are doing as I started VBA about a week ago
You can add the following code to search for your policy number, and if nothing found then PolLookup = Nothing.
Option Explicit
Sub Test()
On Error GoTo ErrHandler
Dim ws As Worksheet, PolLookup As Range, LookupRng As Range
Set ws = ThisWorkbook.Worksheets(1)
'This is the range you want to search, it can be a long range
'or it can be a single cell.
Set LookupRng = ws.Range("A:A")
'Range.Find is looking for your value in the range you specified above
Set PolLookup = LookupRng.Find("YourLookupValue")
'PolLookup = Nothing if it didn't find a match, so we want to use
'If <NOT> Nothing, because this suggests .Find found your value
If Not PolLookup Is Nothing Then
Err.Raise vbObjectError + 0 'Whatever error you want to throw for finding a match
End If
'Exit before you reach the ErrHandler
Exit Sub
ErrHandler:
If Err.Number = vbObjectError + 0 Then
'Handle your error. Do you want to stop completely? Or have the
'User enter a new value?
End If
End Sub
Basically, after your user enters their value in your UserForm, just make a call to this Sub to do a quick lookup.
Playing around I discovered a Much easier way! I included a Button with he following code attached
Private Sub CommandButton8_Click()
Search = PolBX.Text
Set FoundCell = Worksheets("sheet1").Columns(7).Find(Search,LookIn:=xlValues, lookat:=xlWhole)
If FoundCell Is Nothing Then
MsgBox "No duplicates found"
Else
MsgBox "This policy has already been Assessed" & "Please assess a different case"
PolBX.Value = ""
End If

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.

Run-time error '424;" Object Required for case function

i can not figure this out below is the code.... I hit the error for the 2nd case to open the form frmBookingLCL.show the form name is correct. I can't figure this out. the line with the **** us the error line. HELP!!
Public Sub SendBookingEmail()
StartTime = Timer
With Session
'check first 2 letters of shipper's code, if not US raise error
If IsStartPositionCorrect(5, 14, 2, "US") <> True Or IsStartPositionCorrect(5, 2, 8, "Customer") <> True And GetDisplayText(4, 20, 1) <> "0" Then
If MsgBox("You don't appear to be in Logis ocean export US file. Please enter the file first and then run the macro.", vbOKOnly, "Export file verification....") Then
Exit Sub
End If
End If
sTypeOfMessage = "booking"
sShipmentType = Trim(.GetDisplayText(9, 61, 3))
sFileType = Trim(.GetDisplayText(4, 32, 1))
bFullVersion = False
'On Error GoTo ErrHand
'Get Outlook if it's running
Set oOutlookApp = GetObject(, "Outlook.Application")
'collect data fields for the e-mail body
GetAllLogisDataBooking
'Blow up the question form
Select Case sShipmentType
Case "FCL", "CMF", "CCS", "FPR"
frmBookingFCL.Show
Case "LCL", "GWY", "CLD"
frmBookingLCL.Show**********ERROR HERE
Case Else
frmBookingFCL.Show
'frmBookingOthers.Show
End Select
End With
Finish = Timer
TimeTook = Finish - StartTime
MyMacroStats = GetProcedureStats("Booking Confirmation", TimeTook)
Exit Sub
ErrHand:
If Err = 429 Then
MsgBox "Please note you must start Microsoft Outlook first."
End
End If
End Sub
Most likely, the error is in your user form. See the code comments.
I tried to replicate the issue below:
Sub test()
'/Sub to load the user form.
Dim x As String
x = "a"
Select Case x
Case "a", "b", "c"
UserForm1.Show '/ It Will error-out here during debugging.
End Select
End Sub
Code in UserForm1
Private Sub UserForm_Initialize()
'/ Code from : https://msdn.microsoft.com/en-us/library/office/gg251554.aspx
'/ Actually the error happens here.
Dim RetVal ' Implicitly a Variant.
' Default property is assigned to Type 8 Variant RetVal.
RetVal = CreateObject("Excel.Application")
RetVal.Visible = True ' Error occurs here.
End Sub
So going by your intialize code, either you are missing or have incorrect name for one of these controls.
frTrucker,CheckBox1,txtPickupDate. Once you correct them, the error will be gone.

Simple Excel VB Cell value change - Error #1004: Application-defind or object-defined error

i've been trying to fix this error for hours now and i can't seem to see what it is that i am doing wrong here.
My macro is as it follows:
Function testValueChange(cell As Range)
On Error GoTo ErrorHandler
Dim testValue As String
testValue = Range(cell.Address)
MsgBox testValue
Range("Q2") = "new value"
Exit Function
ErrorHandler:
MsgBox "Error #" & Err & " : " & Error(Err)
End Function
I am able to retrieve the "testValue" correctly and it is displayed on the MsgBox. However, when i try to set a new value to the cell "Q2", i get the error "Error #1004: Application-defined or object-defined error."
There are several entries for that error over the web but none of them in this situation when i'm trying to simply set a String value to an empty cell!
The cell "Q2" is empty, i've chosen that cell specifically because it is not merged, nor referenced on another function or anything.
Thanks in advance for all the help!
I'm on Linux OS right now so I can't test this in Excel, but try setting a range object first then assigning the value with .value property. i.e:
Dim RNG as Range
Set RNG = Range("Q2")
RNG.value = "new value"
If you not interested in a return then shahkalpesh has the answer, but if your interested in monitoring the macro silently when run from somewhere else then return boolean like so.
Function testValueChange(cell As Range) as boolean
TestValueChange = TRUE
On Error GoTo ErrorHandler
Dim testValue As String
testValue = Range(cell.Address)
MsgBox testValue
Range("Q2") = "new value"
Exit Function
ErrorHandler:
testValueChange = FALSE
End Function
Usage in a vba sub.
If testValueChange then
'process worked
Else
'process didn't work
End if
Unless testvalue was ment to be testValueChange and returned as a string?
You cannot assign values to cells, or change them in any manner, when calling from a Function (or from a call chain that has started by a Function). Only a Sub will work. The only exception is that function value can be assigned to the cell containing the function reference