How do I display an empty string when a variable is not initialized? - basic

Im trying to display an empty string which is pretty straight forward, how is their a way to display an empty number for an integer? i have the example below.
Sub()
Dim s As String
Dim Number As Integer
'using a space in double quote
s = " "
'this will display an empty string, well not really empty but the space will make it empty
msgbox(s)
so basically im trying to do the same thing integer whereas when you use a msgbox for it
it displays nothing.

You should make a function for your needs
function ShowNumberNonZero( n ) as string
if n = 0 then
ShowNumberNonZero = ""
else
ShowNumberNonZero = Trim(n)
end if
end function
and then
msgbox(ShowNumberNonZero(Number))

If you don't set your integer at all, calling MsgBox will assign it 0 and it will display 0. The only way to make it so that it will display nothing would be to use an if statement or a function.
It might look something like this:
Private Sub Run()
Dim number As Integer
Message(number)
End Sub
Private Sub Message(ByVal input As Integer)
If input = 0 Then
MsgBox("")
Else
MsgBox(input)
End If
End Sub

Related

In VBA, how to extract the string before a number from the text

From ActiveWorkbook.name, I would like to extract the strings that are before (left side of ) the numbers. Since I want to use the same code in multiple workbooks, the file names would be variable, but every file name has date info in the middle (yyyymmdd).
In case of excel file, I can use the below formula, but can I apply the same kind of method in VBA?
=LEFT(A1,MIN(FIND({0,1,2,3,4,5,6,7,8,9},ASC(A1)&1234567890))-1)
Example: MyExcelWorkbook_Management_20200602_MyName.xlsm
In above case, I want to extract "MyExcelWorkbook_Management_".
The most basic thing you could do is to replicate something that worked for you in Excel through Evaluate:
Sub Test()
Dim str As String: str = "MyExcelWorkbook_Management_20200602_MyName.xlsm"
Debug.Print Evaluate(Replace("=LEFT(""X"",MIN(FIND({0,1,2,3,4,5,6,7,8,9},ASC(""X"")&1234567890))-1)", "X", str))
End Sub
Pretty? Not really, but it does the job and got it's limitations.
You could use Regular Expressions to extract any letters / underscores before the number as well
Dim str As String
str = "MyExcelWorkbook_Management_20200602_MyName.xlsm"
With CreateObject("vbscript.regexp")
.Pattern = "^\D*"
.Global = True
MsgBox .Execute(str)(0)
End With
Gives:
MyExcelWorkbook_Management_
So basically you want to use the Midfunction to look for the first numerical character in your input string, and then cut your input string to that position.
That means we need to loop through the string from left to right, look at one character at a time and see if it is a digit or not.
This code does exactly that:
Option Explicit
Sub extratLeftText()
Dim someString As String
Dim result As String
someString = "Hello World1234"
Dim i As Long
Dim c As String 'one character of your string
For i = 1 To Len(someString)
c = Mid(someString, i, 1)
If IsNumeric(c) = True Then 'should write "If IsNumeric(c) = True AND i>1 Then" to avoid an "out of bounds" error
result = Left(someString, i - 1)
Exit For
End If
Next i
MsgBox result
End Sub
Last thing you need to do is to load in some workbook name into your VBA function. Generally this is done with the .Name method of the workbookobject:
Sub workbookName()
Dim wb As Workbook
Set wb = ActiveWorkbook
MsgBox wb.Name
End Sub
Of course you would need to find some way to replace the Set wb = ActiveWorkbook line with code that suits your purpose.

VBA Inputbox to Prevent Decimals

I am trying to develop a tool that will help standardize a description catalog of products. I want to have an input box prompt a user to enter a size. I want to encourage size entries like "5-1/2" and prevent users from entering "5.5". Ideally, if the size was entered with a decimal and not a dash with a fraction, I want a message box to pop up saying they can not do that. It would then need to re-show the input box.
Here is what I have -
Private Sub CS_Other_Click()
Unload Me
Sheets("Fill In").Activate
Worksheets("Fill In").Range("C2").NumberFormat = "#"
Dim other_casing_size As Variant
other_casing_size = InputBox("Fill in the casing size. Syntax MUST be in the form of X-X/X", "New Casing Size")
Range("C2") = other_casing_size
I just dont know the code to prevent an entry with decimals. Even better, if i knew how to code an exact syntax to include or exclude anything I wanted that would be perfect.
Thanks
A while loop, which checks the input string for a dot or comma would work quite ok, I guess:
Sub TestMe()
Dim inputString As String
Dim inputNumeric As Boolean
inputString = InputBox("Please, enter a number!")
inputNumeric = isNumeric(Evaluate(inputString))
Do While InStr(1, inputString, ".") Or _
InStr(1, inputString, ",") Or _
Not inputNumeric
If Not CBool(inputNumeric) Then
MsgBox "You tried to cancel or entered empty value!"
Exit Do
End If
MsgBox "Please, do not write dot or comma!"
inputString = InputBox("Please, enter a number!")
inputNumeric = isNumeric(Evaluate(inputString))
Loop
End Sub
The isNumeric() checks the input for being able to be converted to numeric. Thus 5-1/2 should be ok.
Concerning cancellation or entering empty value from the InputBox() - it really depends on the business logic of the "app", but in the case above - there is a msgbox and it exits the loop.
Write a separate function responsible for that prompt, and use it e.g. like this:
Dim casingSize As String
If GetCasingSize(casingSize) Then
ActiveSheet.Range("C2").Value = casingSize
End If
The function needs to return a Boolean for this to work - it returns True if the input is valid, False if there's no valid input to work with (e.g. prompt was cancelled). What makes this work, is passing the result as a ByRef argument, like this:
Public Function GetCasingSize(ByRef outResult As String) As Boolean
Do
Dim raw As Variant
raw = InputBox("Casing size?")
If VarType(raw) = vbBoolean Then
'handle cancelled prompt:
Exit Do
End If
If ValidateFractional(raw) Then
'handle valid input:
outResult = CStr(raw)
GetCasingSize = True
Exit Do
End If
'handle invalid input:
If MsgBox("The value '" & raw & "' is not valid. Try again?", vbYesNo) = vbNo Then
Exit Do
End If
Loop
End Function
Note the ValidateFractional function is its own concern - a separate, Private function would work, but I'd recommend making it Public, and unit-testing it to make sure it works as intended given a wide variety of edge-case inputs - and having it in a separate function means the logic in GetCasingSize doesn't need to change if the validation needs to be fine-tuned; for example this naive implementation uses the Like operator and would work for 5-1/4, but not for e.g. 15-5/8:
Public Function ValidateFractional(ByVal value As String) As Boolean
ValidateFractional = value Like "#[-]#/#"
End Function
Using Regular Expressions for this would probably be a good idea.

How to evaluate the typename of a value in a conditional in visual basic?

I am using visual basic to write macros for excel. I have already looked up several tutorials and all of them use "If TypeOf [object] Is [typename] Then" in order to check whether the value of a cell is of a certain Type. For instance, in my code I try to evaluate whether the value in cell A1 is a string in order to move it. My code:
Private Sub CommandButton1_Click()
If TypeOf Range("A1").Value Is String Then
Range("B1").Value = Range("A1").Value
End If
End Sub
However the word "String" gets highlighted and I get an error that says: Compile error:
Expected: Object or type name
I have been stuck for quite sometime and simply cannot find or search for a way out of it. Please help.
You can use TypeName():
If TypeName(Range("A1").Value) = "String" Then
Assuming, there's a Worker class:
Sub F()
Dim x As Integer
Dim j As Long
Dim w As Object
Set w = New Worker
MsgBox TypeName(w) '// Worker
MsgBox VarType(w) '// 9 = vbObject
If TypeName(x) = "Integer" Then
End If
If VarType(x) = vbInteger Then
End If
If VarType(j) = vbLong Then
End If
End Sub

"If strMyString.Contains, Then strMyString.Contains, Else Boolean" Procedure

I need help with a-
"If strMyString.Contains, Then strMyString.Contains, Else Boolean" Procedure
I am trying to find the name "lordgun" within a very big data Log. For all the times it's listed, I want to list it to the right of my data.
Here is the my whole attempt thus far-
Option Explicit
Public Function linecontains()lordgun As Boolean
Dim strMyString As String
Dim TargetString1 As String
Dim TargetString2 As String
'Returns True if cell contains substring, False otherwise
If strMyString.Contains("lordgun.org")
Else strMyString.Contains("") Then
End If
End Function
One way is to use the instr function.
This function returns an int. If it returns a value > 0 then the string was found.
e.g:
If Instr(1, MyString, SearchFor, 0) >0 Then
Else
End if

Compile error "expected: end of statement"

I have the following calcScores function written:
Function calcScores(category As String) As Integer
Dim count As Integer
count = 0
For Each Ctl In UserForm1.Controls
If Ctl.Tag = category And TypeName(Ctl) = "CheckBox" Then
Dim box As MSForms.CheckBox
Set box = Ctl
If box.Value = True Then
count = count + 1
End If
End If
Next
calcScores = count
End Function
This function takes a tag named "category" as a string and then checks the form for all check boxes with that tag and counts the ones that are checked. I know it works and counts the right number, because I have slightly edited it to output it's value to a label on the form instead of returning it.
When I try to call it in another function like this:
Function sortScores()
Dim scores(0 to 5) as Integer
scores(0) = calcScores "rChk"
**CODE CONTINUES**
End Function
I get an error that says "Expected: End of Statement" as soon as I leave the line that assigns the function's return to scores(0). calcScores is assigned before sortScores, and was succesfully called in a sub before using the same syntax.
Any idea what the error could be?
Call you function like this
scores(0) = calcScores("rChk")
Functions are called like that. Subs are called by
subName argument

Resources