If not contain specific text = TRUE in UDF - excel

I need help to fix this UDF.
I need the result to be "Salentein Malbec" when
Familia is different from "ESPUMOSO" (done)
Marca is equal to "SALENTEIN"(done)
Cepa is equal to "MALBEC" (done)
Formato is equal to "B0750" (done)
Material does not contain the characters "TDF" (pending, i need help with this part)
Function PRODUCTDESCRIPTION(Familia, Marca, Cepa, Formato, Material)
If Familia <> "ESPUMOSO" And Marca = "SALENTEIN" And Cepa = "MALBEC" And Formato = "B0750" And Material <> "*TDF*" Then
PRODUCTDESCRIPTION = "Salentein Malbec"
End If
End Function

You can do it like this because of having a problem in the last part I am showing you that, you can use it in VBA also.
=ISNUMBER(SEARCH("TDF",D7))
Here is how you can do it in VBA, I have created a function for that just for testing, you can implement that in your code.
simply you can use InStr(whereTo, word) and it returns the position where the word is located at
InStr(whereTo, word) // return integer number.
here is a sample I have created for you.
Private Sub CommandButton1_Click()
Call SearchForWord("TDF", Sheet1.Range("D6"))
End Sub
Sub SearchForWord(word As String, whereTo As Range)
Dim foundAt As Integer
foundAt = InStr(whereTo, word)
If foundAt > 0 Then
TextBox1.Text = word + " has found at " + CStr(foundAt)
MsgBox "Cell not contain " + word + " at " + CStr(foundAt)
Else
TextBox1.Text = word + " has not found at " + CStr(foundAt)
MsgBox "Cell not contains " + word
End If
End Sub

Related

Translate formula quotation marks incl. replacements into VBA-readable formulae

Translate formula quotation marks incl. replacements into VBA-readable formulae
I was inspired to write this post by the recent question of
formula substitution using a constant.
At the same time, the frequent problem emerged that quotation marks
within a formula string should be replaced by double quotation marks in order
to make them readable in VBA.
Practical use case
A practical use case is to copy a table formula directly from a SO website
and "translate" it into a string-readable format.
But how is this supposed to be done with VBA means, since the direct input of
such an incomplete formula string in a procedure code without manually
added double quotation marks would immediately lead to an error?
Another feature would be to make replacements at certain points within
a formula template, for example with a constant or even with several
numerically identifiable markers.
I found a quick & dirty solution (without error handling) by analyzing a FormulaContainer procedure containing
exclusively outcommented formulae as these would allow any prior direct code input.
In order to distinguish them from the usual commentaries,
I decided with a heavy heart to use the Rem prefix (i.e. Remark) as an alternative, which we may still be familiar with from ancient Basic times.
My intention is not to show a perfect solution, but to stimulate further solutions
by demonstrating a possible way.
Question
Are there other work arounds allowing to copy tabular formulae with quotation marks directly and as possible replacement pattern into VBA procedures?
///////////////////////////////////
Main function QuickFormula()
References a FormulaContainer procedure containing exclusively formulae with Rem prefixes, such as e.g.
Sub FormulaContainer()
Rem =....
Rem =....
End Sub
This allows formula inputs with quotation marks similar to tabular cell inputs;
furthermore these inputs may contain string identifiers facilitating wanted replacements.
Option Explicit
'Site: https://stackoverflow.com/questions/70399681/how-many-quotes-to-put-around-a-formula-that-is-sending-an-empty-string
'Auth: https://stackoverflow.com/users/6460297/t-m
Function QuickFormula(ByVal no As Long, ParamArray repl() As Variant) As String
'Purp: - change indicated code line in FormulaContainer to code readable string and
' - replace enumerated identifiers with given value(s)
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'1) get REMark code line indicated by ordinal argument no
QuickFormula = getCodeLine("modFormula", "FormulaContainer", no)
'2a)replace "#" identifyer(s) with constant repl value
If Not IsArray(repl(0)) Then
QuickFormula = Replace(QuickFormula, "{1}", "#")
QuickFormula = Replace(QuickFormula, "#", repl(0))
If Len(QuickFormula) = 0 Then QuickFormula = "Error NA!"
Debug.Print no & " ~~> " & Chr(34) & QuickFormula & Chr(34)
Exit Function
End If
'2b)replace 1-based "{i}" identifiers by ParamArray values
Dim i As Long
For i = LBound(repl(0)) To UBound(repl(0))
QuickFormula = Replace(QuickFormula, "{" & i + 1 & "}", repl(0)(i))
Next
'3) optional display in immediate window
Debug.Print no & " ~~> " & Chr(34) & QuickFormula & Chr(34)
End Function
Help function getCodeLine()
Gets a given code line of the indicated procedure
Function getCodeLine(ByVal ModuleName As String, ByVal ProcedureName As String, Optional ByVal no As Long = 1) As String
'Purp: return a code line in given procedure containing "Rem "
'Note: assumes no line breaks; needs a library reference to
' "Microsoft Visual Basic for Applications Extensibility 5.3"
Const SEARCH As String = "Rem =", QUOT As String = """"
'1) set project
Dim VBProj As Object
Set VBProj = ThisWorkbook.VBProject
If VBProj.Protection = vbext_pp_locked Then Exit Function ' escape locked projects
'2) set component
Dim VBComp As Object
Set VBComp = VBProj.VBComponents(ModuleName)
Dim pk As vbext_ProcKind
'3) get no + 3 top code line(s)
With VBComp.CodeModule
'a)count procedure header lines
Dim HeaderCount As Long: HeaderCount = .ProcBodyLine(ProcedureName, pk) - .ProcStartLine(ProcedureName, pk)
'b) get procedure code
Dim codelines
'codelines = Split(.Lines(.ProcBodyLine(ProcedureName, pk), .ProcCountLines(ProcedureName, pk) - HeaderCount), vbNewLine)
codelines = Split(.Lines(.ProcBodyLine(ProcedureName, pk), no + 1), vbNewLine)
'c) filter code lines containing "Rem" entries
codelines = Filter(codelines, SEARCH, True)
End With
'4) return (existing) codeline no
If no - 1 > UBound(codelines) Then Exit Function ' check existance
getCodeLine = Replace(Replace(codelines(no - 1), QUOT, String(2, QUOT)), "Rem =", "=")
End Function
Example call
References all three formulae in the FormulaContainer (including an example of a non-existing number):
Sub EnterFormula()
With Sheet1.Range("X1") ' << change to any wanted target range
.Offset(1).Formula2 = QuickFormula(1, 6)
.Offset(2).Formula2 = QuickFormula(2, Array(10, 20, 30))
'two single argument inputs with same result
.Offset(3).Formula2 = QuickFormula(3, Array(17))
.Offset(4).Formula2 = QuickFormula(3, 17)
'not existing formula number in Rem code container
.Offset(5).Formula2 = QuickFormula(333, 17)
End With
End Sub
Example FormulaContainer
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Purp: formula container to be adjusted to code readable strings
'Note: Insert only Formulae starting with "Rem "-prefix!
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' # identifies constant replacement(s)
' {i} stands for enumerated replacements {1},{2}..{n}
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sub FormulaContainer()
Rem =IF($V#>0,IF($G#>$S#,($S#-$H#)*$K#+$Y#,($G#-$H#)*$K#+$Y#),"")
Rem =A{1}*B{3}+C{2}
Rem =A{1}+100
End Sub
Example output in immediate window
1 ~~> "=IF($V6>0,IF($G6>$S6,($S6-$H6)*$K6+$Y6,($G6-$H6)*$K6+$Y6),"""")"
2 ~~> "=A10*B30+C20"
3 ~~> "=A17+100"
3 ~~> "=A17+100"
333 ~~> "Error NA!"
Keep it simple stupid
Assuming either the currently selected cell formula or a textbox input, a simple Userform might act as a formula translator into a line of VBA code:
Basic Userform code
Needed: TextBox1, TextBox2, CommandButton1
Option Explicit
Private Sub CommandButton1_Click()
'Purp: Redouble inside quotation marks
Const Quot As String = """"
Dim assignTo As String
assignTo = "ws.Range(""" & Selection.Address(False, False) & """).Formula2 = "
Me.TextBox2.Text = assignTo & Quot & Replace(Me.TextBox1.Text, Quot, String(2, Quot)) & Quot
End Sub
Private Sub UserForm_Initialize()
'Purp: assume active formula as wanted input
Me.TextBox1 = Selection.Formula2
End Sub
Private Sub UserForm_Layout()
'Purp: example layout textboxes
'a) define textboxes
Dim textboxes() As String
textboxes = Split("Textbox1,Textbox2", ",")
'b) format
Dim i As Long
For i = 0 To UBound(textboxes)
With Me.Controls(textboxes(i))
.Font.Name = "Courier New"
.Font.Size = 12
.MultiLine = True
.EnterKeyBehavior = True
End With
Next i
End Sub
Possible extensions
Of course you might add an insertion routine (inserting e.g. {} brackets) as well as some replacement procedures like in my workaround above.
Just for fun, a basic insertion routine here:
Private Sub CommandButton2_Click()
'Purp: Insert brackets {}
With Me.TextBox1
.SetFocus
If InsertAtCursor("{}", Me.TextBox1) Then
.SelStart = .SelStart - 1
End If
End With
End Sub
Public Function InsertAtCursor(s As String, ctrl As MSForms.Control, Optional ErrMsg As String) As Boolean
'Purpose: Insert the characters at the cursor in the active control.
'Site: http://allenbrowne.com/func-InsertChar.html
'Return: True if characters were inserted.
'Arguments: s = the character(s) you want inserted at the cursor.
' ErrMsg = string to append any error messages to.
'Note: Control must have focus.
On Error GoTo Err_Handler
Dim prior As String 'Text before the cursor.
Dim after As String 'Text after the cursor.
Dim cnt As Long 'Number of characters
Dim iSelStart As Long 'Where cursor is.
Dim txt As String 'text with LineFeeds only
If s <> vbNullString Then
With ctrl ' --> UserForm Control
txt = Replace(.Text, vbCrLf, vbLf) ' LineFeeds only (MultiLine)
If .Enabled And Not .Locked Then
cnt = Len(txt) ' Zählung ohne vbCr's !
'SelStart can't cope with more than 32k characters.
If cnt <= 32767& - Len(s) Then
'Remember characters before cursor.
iSelStart = .SelStart
If iSelStart > 1 Then
prior = Left$(txt, iSelStart)
End If
'Remember characters after selection.
If iSelStart + .SelLength < cnt Then
after = Mid$(txt, iSelStart + .SelLength + 1) ' OP:2
End If
'Assign prior characters, new ones, and later ones.
.value = prior & s & after
'Put the cursor back where it as, after the new ones.
.SelStart = iSelStart + Len(s)
'Return True on success
InsertAtCursor = True
End If
End If
End With
End If
Exit_Handler:
Exit Function
Err_Handler:
Debug.Print Err.Number, Err.Description
Select Case Err.Number
Case 438&, 2135&, 2144& 'Object doesn't support this property. Property is read-only. Wrong data type.
ErrMsg = ErrMsg & "You cannot insert text here." & vbCrLf
Case 2474&, 2185& 'No active control. Control doesn't have focus.
ErrMsg = ErrMsg & "Cannot determine which control to insert the characters into." & vbCrLf
Case Else
ErrMsg = ErrMsg & "Error " & Err.Number & ": " & Err.Description & vbCrLf
End Select
Resume Exit_Handler
End Function

Check if Column List Contains Header via Regex - Excel vba

I'm trying to determine if a column has a header or not via VBA. Basically the column will have data following an unknown but identical regex pattern. My plan is to test if A2 has the same type regex string as A1. It would likely even be the same ID + 1. Eg
A1 = X001
A2 = X002
Func IsHeader("A") = True
A1 = ID's
A2 = X001
Func IsHeader("A") = False
I've got an idea to utilize an existing script I made to generate a regex pattern based on an input alphanumerical string, but I'm interested to see what other idea's/ways people might have of solving the issue. I realize there isn't much code, but I know I can do this and I'm working on it now. If you're not interested in answering, thats ok!
Update: Posted Answer, but I'm looking for more than a code review as I realize there is an exchange for that. I'd like to know better ways to achieve goal with a different attack vector.
This is what I got! I'm not sure how SO feels about code reviews, but im interested in what ppl think and how else they could "skin the cat" so please feel free to post an answer.
Sub Test()
If IsHeader = True Then
MsgBox "Has Header"
Else
MsgBox "No Header"
End If
End Sub
Public Function IsHeader() As Boolean
A1Pattern = RegExPattern(Range("A1").Value)
A2Pattern = RegExPattern(Range("A2").Value)
If A1Pattern = A2Pattern Then
IsHeader = True
End If
End Function
Public Function RegExPattern(my_string) As String
RegExPattern = ""
'''Special Character Section'''
Dim special_charArr() As String
Dim special_char As String
special_char = "!,#,#,$,%,^,&,*,+,/,\,;,:"
special_charArr() = Split(special_char, ",")
'''Special Character Section'''
'''Alpha Section'''
Dim regexp As Object
Set regexp = CreateObject("vbscript.regexp")
Dim strPattern As String
strPattern = "([a-z])"
With regexp
.ignoreCase = True
.Pattern = strPattern
End With
'''Alpha Section'''
Dim buff() As String
'my_string = "test1*1#"
ReDim buff(Len(my_string) - 1)
Dim i As Variant
For i = 1 To Len(my_string)
buff(i - 1) = Mid$(my_string, i, 1)
char = buff(i - 1)
If IsNumeric(char) = True Then
'MsgBox char & " = Number"
RegExPattern = RegExPattern & "([0-9])"
End If
For Each Key In special_charArr
special = InStr(char, Key)
If special = 1 Then
If Key <> "*" Then
'MsgBox char & " = Special NOT *"
RegExPattern = RegExPattern & "^[!##$%^&()].*$"
Else
'MsgBox char & " = *"
RegExPattern = RegExPattern & "."
End If
End If
Next
If regexp.Test(char) Then
'MsgBox char & " = Alpha"
RegExPattern = RegExPattern & "([a-z])"
End If
Next
'RegExPattern = Chr(34) & RegExPattern & Chr(34)
'MsgBox RegExPattern
End Function

Test several text boxes at once for any blanks

I want to check three different textboxes on a form (but not all) to see if any are left blank. Comparable to "If IsBlank," on the spreadsheet. From what I've read, it seems that IsEmpty can't be used this way? I've been playing with IsNull, but haven't found a proper syntax that would allow it to work. Surely there must be some simple, even standard, way of doing this? Maybe some other function I've never heard of?
(I know I can use If Txtbx1.value = "" Or If... (etc.)
—I'm looking for a shorter and more graceful way to do this.)
Thanks!
Consider using OR:
Sub dural()
If Txtbx1.Value = "" Or Txtbx2.Value = "" Or Txtbx3.Value = "" Then
MsgBox "at least one empty"
End If
End Sub
Match vs Array of Text Boxes feat. IsError, VarType and TypeName
All codes were in a user form code sheet and were run via command buttons on the user form where also the three text boxes were located.
In the first code, the result of Match is passed to the var (variant) variable and further evaluated. If there is at least one text box with no value ("" or vbNullString), var will return the position of the first found empty text box 1-based i.e. the first is 1, the second is 2 etc. unlike the Array which is 0-based i.e. the first element is 0, the second is 1 etc.
The second code is a presentation of the three choices that were studied in the first code.
The third code is a 'bad' code without variables you might be looking for.
Sub TextBoxFun()
Dim vntTB As Variant ' Text Box Array
Dim var As Variant ' Match Variant
Dim strTB As String ' Pass String
Dim lngTB As Long ' Pass Long
' Pass TextBoxes to Text Box Array.
vntTB = Array(TextBox1, TextBox2, TextBox3)
' Either:
var = Application.Match("", vntTB, 0)
' Or:
'var = Application.Match(vbNullString, vntTB, 0)
Debug.Print String(10, "'")
Debug.Print "IsError(var) = " & IsError(var) ' True
Debug.Print "VarType(var) = " & VarType(var) ' 10 or vbError
Debug.Print "TypeName(var) = " & TypeName(var) ' Error
Debug.Print String(10, "'")
' Line of Code / vbNullString Found ? >>> ' True False
Debug.Print var ' 1
' Depending on the first position of ' 2
' the found vbNullString or "". ' 3 Error 2042
lngTB = IsError(var): Debug.Print lngTB ' 0 -1
lngTB = VarType(var): Debug.Print lngTB ' 5 10
'lngTB = TypeName(var): Debug.Print lngTB ' Nope Nope
' TypeName returns always a string.
strTB = IsError(var): Debug.Print strTB ' False True
strTB = VarType(var): Debug.Print strTB ' 5 10
strTB = TypeName(var): Debug.Print strTB ' Double Error
End Sub
Sub TextBoxFunConclusion()
Dim vntTB As Variant ' Text Box Array
' Pass TextBoxes to Text Box Array.
vntTB = Array(TextBox1, TextBox2, TextBox3)
If IsError(Application.Match("", vntTB, 0)) Then
Debug.Print "No 'empty' text boxes (via IsError)."
Else
Debug.Print "At least one 'empty' text box (via IsError)."
End If
If VarType(Application.Match("", vntTB, 0)) = 10 Then
Debug.Print "No 'empty' text boxes (via VarType)."
Else
Debug.Print "At least one 'empty' text box (via VarType)."
End If
If TypeName(Application.Match("", vntTB, 0)) = "Error" Then
Debug.Print "No 'empty' text boxes (via TypeName)."
Else
Debug.Print "At least one 'empty' text box (via TypeName)."
End If
End Sub
Sub TextBoxFunMyChoice()
If IsError(Application.Match("", Array(TextBox1, TextBox2, TextBox3), 0)) _
Then
Debug.Print "No 'empty' text boxes (via IsError)."
Else
Debug.Print "At least one 'empty' text box (via IsError)."
End If
End Sub
Private Sub CommandButton1_Click()
TextBoxFun
End Sub
Private Sub CommandButton2_Click()
TextBoxFunConclusion
End Sub
Private Sub CommandButton3_Click()
TextBoxFunMyChoice
End Sub

VB6 Textbox fontweight manipulation

I have a VB6 application where I want to manipulate certain parts of a string I am outputting inside a textbox.
txtPhoneNums.Text = "Home: " + strHomeNo + vbCrLf _
+ "Mobile: " + strMobileNo + vbCrLf + "Work: " + strWorkNo + vbCrLf
It's nested inside an if statement that carries out various validations. I want to be able for example, in the above snippet to highlight the word "Work" and the appended string value "strWorkNo" in red and fontweighted bold. Can I do this easily without creating multiple textboxes (and leaving the other two values as default appearance?)
Thanks.
Image added for clarity. I want the two null field strings to be red and bold.
You want to use the RichTextBox. I would recommend that you don't try to mess around with the rich text format (RTF) itself, but instead use the standard methods.
Your code would be changed as follows:
Option Explicit
Private Sub Command1_Click()
WritePhoneNums "01020239", "07749383", "0234394349"
End Sub
Private Sub WritePhoneNums(ByRef strHomeNo As String, ByRef strMobileNo As String, ByRef strWorkNo As String)
Dim nPosBeginningOfWorkNo As Long
Dim nPosCurrent As Long
txtPhoneNums.TextRTF = vbNullString ' Clear existing code.
' Clear style to default.
ApplyNormalStyle txtPhoneNums
' Enter standard text. The selection will be at the end of the text when finished.
txtPhoneNums.SelText = "Home: " + strHomeNo + vbCrLf _
& "Mobile: " + strMobileNo + vbCrLf + "Work: "
' Save the cursor position, write the work number, and then save the cursor position again.
nPosBeginningOfWorkNo = txtPhoneNums.SelStart
txtPhoneNums.SelText = strWorkNo
nPosCurrent = txtPhoneNums.SelStart
' From this information, select the preceding text, and make it "selected".
txtPhoneNums.SelStart = nPosBeginningOfWorkNo
txtPhoneNums.SelLength = nPosCurrent - nPosBeginningOfWorkNo
ApplyHighlightedStyle txtPhoneNums
' Reset the selection to the end, and reset the text style.
txtPhoneNums.SelStart = nPosCurrent
txtPhoneNums.SelLength = 0
ApplyNormalStyle txtPhoneNums
txtPhoneNums.SelText = vbCrLf
End Sub
Private Sub ApplyNormalStyle(ByRef txt As RichTextBox)
txt.SelBold = False
txt.SelColor = vbBlack
End Sub
Private Sub ApplyHighlightedStyle(ByRef txt As RichTextBox)
txt.SelBold = True
txt.SelColor = vbRed
End Sub

Convert string to int if string is a number

I need to convert a string, obtained from excel, in VBA to an interger. To do so I'm using CInt() which works well. However there is a chance that the string could be something other than a number, in this case I need to set the integer to 0. Currently I have:
If oXLSheet2.Cells(4, 6).Value <> "example string" Then
currentLoad = CInt(oXLSheet2.Cells(4, 6).Value)
Else
currentLoad = 0
End If
The problem is that I cannot predict all possible non numeric strings which could be in this cell. Is there a way I can tell it to convert if it's an integer and set to 0 if not?
Use IsNumeric. It returns true if it's a number or false otherwise.
Public Sub NumTest()
On Error GoTo MyErrorHandler
Dim myVar As Variant
myVar = 11.2 'Or whatever
Dim finalNumber As Integer
If IsNumeric(myVar) Then
finalNumber = CInt(myVar)
Else
finalNumber = 0
End If
Exit Sub
MyErrorHandler:
MsgBox "NumTest" & vbCrLf & vbCrLf & "Err = " & Err.Number & _
vbCrLf & "Description: " & Err.Description
End Sub
Cast to long or cast to int, be aware of the following.
These functions are one of the view functions in Excel VBA that are depending on the system regional settings. So if you use a comma in your double like in some countries in Europe, you will experience an error in the US.
E.g., in european excel-version 0,5 will perform well with CDbl(), but in US-version it will result in 5.
So I recommend to use the following alternative:
Public Function CastLong(var As Variant)
' replace , by .
var = Replace(var, ",", ".")
Dim l As Long
On Error Resume Next
l = Round(Val(var))
' if error occurs, l will be 0
CastLong = l
End Function
' similar function for cast-int, you can add minimum and maximum value if you like
' to prevent that value is too high or too low.
Public Function CastInt(var As Variant)
' replace , by .
var = Replace(var, ",", ".")
Dim i As Integer
On Error Resume Next
i = Round(Val(var))
' if error occurs, i will be 0
CastInt = i
End Function
Of course you can also think of cases where people use commas and dots, e.g., three-thousand as 3,000.00. If you require functionality for these kind of cases, then you have to check for another solution.
Try this:
currentLoad = ConvertToLongInteger(oXLSheet2.Cells(4, 6).Value)
with this function:
Function ConvertToLongInteger(ByVal stValue As String) As Long
On Error GoTo ConversionFailureHandler
ConvertToLongInteger = CLng(stValue) 'TRY to convert to an Integer value
Exit Function 'If we reach this point, then we succeeded so exit
ConversionFailureHandler:
'IF we've reached this point, then we did not succeed in conversion
'If the error is type-mismatch, clear the error and return numeric 0 from the function
'Otherwise, disable the error handler, and re-run the code to allow the system to
'display the error
If Err.Number = 13 Then 'error # 13 is Type mismatch
Err.Clear
ConvertToLongInteger = 0
Exit Function
Else
On Error GoTo 0
Resume
End If
End Function
I chose Long (Integer) instead of simply Integer because the min/max size of an Integer in VBA is crummy (min: -32768, max:+32767). It's common to have an integer outside of that range in spreadsheet operations.
The above code can be modified to handle conversion from string to-Integers, to-Currency (using CCur() ), to-Decimal (using CDec() ), to-Double (using CDbl() ), etc. Just replace the conversion function itself (CLng). Change the function return type, and rename all occurrences of the function variable to make everything consistent.
Just use Val():
currentLoad = Int(Val([f4]))
Now currentLoad has a integer value, zero if [f4] is not numeric.
To put it on one line:
currentLoad = IIf(IsNumeric(oXLSheet2.Cells(4, 6).Value), CInt(oXLSheet2.Cells(4, 6).Value), 0)
Here are a three functions that might be useful. First checks the string for a proper numeric format, second and third function converts a string to Long or Double.
Function IsValidNumericEntry(MyString As String) As Boolean
'********************************************************************************
'This function checks the string entry to make sure that valid digits are in the string.
'It checks to make sure the + and - are the first character if entered and no duplicates.
'Valid charcters are 0 - 9, + - and the .
'********************************************************************************
Dim ValidEntry As Boolean
Dim CharCode As Integer
Dim ValidDigit As Boolean
Dim ValidPlus As Boolean
Dim ValidMinus As Boolean
Dim ValidDecimal As Boolean
Dim ErrMsg As String
ValidDigit = False
ValidPlus = False
ValidMinus = False
ValidDecimal = False
ValidEntry = True
For x = 1 To Len(MyString)
CharCode = Asc(Mid(MyString, x, 1))
Select Case CharCode
Case 48 To 57 ' Digits 0 - 9
ValidDigit = True
Case 43 ' Plus sign
If ValidPlus Then 'One has already been detected and this is a duplicate
ErrMsg = "Invalid entry....too many plus signs!"
ValidEntry = False
Exit For
ElseIf x = 1 Then 'if in the first positon it is valide
ValidPlus = True
Else 'Not in first position and it is invalid
ErrMsg = "Invalide entry....Plus sign not in the correct position! "
ValidEntry = False
Exit For
End If
Case 45 ' Minus sign
If ValidMinus Then 'One has already been detected and this is a duplicate
ErrMsg = "Invalide entry....too many minus signs! "
ValidEntry = False
Exit For
ElseIf x = 1 Then 'if in the first position it is valid
ValidMinus = True
Else 'Not in first position and it is invalid
ErrMsg = "Invalide entry....Minus sign not in the correct position! "
ValidEntry = False
Exit For
End If
Case 46 ' Period
If ValidDecimal Then 'One has already been detected and this is a duplicate
ErrMsg = "Invalide entry....too many decimals!"
ValidEntry = False
Exit For
Else
ValidDecimal = True
End If
Case Else
ErrMsg = "Invalid numerical entry....Only digits 0-9 and the . + - characters are valid!"
ValidEntry = False
Exit For
End Select
Next
If ValidEntry And ValidDigit Then
IsValidNumericEntry = True
Else
If ValidDigit = False Then
ErrMsg = "Text string contains an invalid numeric format." & vbCrLf _
& "Use only one of the following formats!" & vbCrLf _
& "(+dd.dd -dd.dd +dd -dd dd.d or dd)! "
End If
MsgBox (ErrMsg & vbCrLf & vbCrLf & "You Entered: " & MyString)
IsValidNumericEntry = False
End If
End Function
Function ConvertToLong(stringVal As String) As Long
'Assumes the user has verified the string contains a valide numeric entry.
'User should call the function IsValidNumericEntry first especially after any user input
'to verify that the user has entered a proper number.
ConvertToLong = CLng(stringVal)
End Function
Function ConvertToDouble(stringVal As String) As Double
'Assumes the user has verified the string contains a valide numeric entry.
'User should call the function IsValidNumericEntry first especially after any user input
'to verify that the user has entered a proper number.
ConvertToDouble = CDbl(stringVal)
End Function

Resources