Showing a MsgBox with variables depending on boolean - messagebox

Im kind of a beginner with programming but here is the thing:
I have different variables set as local, these variables are strings of chars, messages and at the same time I have a set of Booleans that will fill with True or False depending of some circumstances.
The idea is to show a single Message Box containing these variables ONLY IF the booleans are False.
An example in pseudocode:
Local string Greetings = "Hi, my name is"
Local string Name1 = "John"
Local string Name2 = "James"
Local Boolean name1 = .T.
Local Boolean name2 = .T.
If Name1 (Have some conditions)
name1 = .T.
endif
If name2 (Some conditions)
name2 = .F.
If name1 == .T. OR name2 == .T.
MsgBox(Greetings+":"+name1+name2,"Messagebox","Alert")
Endif
Sorry I cant describe a lot about which code it is. but it is like Clipper with Xbase.
The problem I have is than even if the condition of these variables are false, the message box will show the both of them, Do I need to put all the contingencies there? for example if I have 3 booleans, Do I need to do this with True,False,False - False,True,False etc?
Best Regards.

I do not see how name1 can possibly be FALSE. It starts as TRUE and if your first condition evaluates to TRUE, you assign it TRUE again. So name1 must be TRUE.
Depending on your logic you might want to have Local Boolean name1 = .F. in the beginning or name1 = .F. inside your first IF.

Related

VBA --- How to change UserForm properties name dynamically based on user input --- Template Literal

I'd like to change $$$ based on the user's input. I know their data type isn't a string, so I can't use string concatenation (e.g. "frm_" & "$$$" & ".lst_") or regular expression to replace $$$ into different name/variable/string. I am looking for a way like Template Literal in JavaScript (${}). Is there a similar way in VBA? Thanks.
If frm_$$$.lst_$$$_ABCDE.ListCount > 0 Then
frm_$$$.lbl_$$$_ACE.Caption = "Lorem ipsum: " & frm_$$$*.lst_$$$_ABCDE.ListCount
ElseIf frm_$$$.lst_$$$_ABCDE.ListCount = 0 Then
frm_$$$.lbl_TH_centercount.Caption = "Lorem ipsumt: 0"
frm_$$$.cmd_$$$_Save.Enabled = False
frm_$$$.cmd_$$$_Next.Enabled = False
End If
I expect the If/ElseIf condition is changed based on the user's input from above to below.
If the user's input is ABC then,
If frm_ABC.lst_ABC_ABCDE.ListCount > 0 Then
frm_ABC.lbl_ABC_ACE.Caption = "Lorem ipsum: " & frm_ABC.lst_ABC_ABCDE.ListCount
ElseIf frm_ABC.lst_ABC_ABCDE.ListCount = 0 Then
frm_ABC.lbl_TH_centercount.Caption = "Lorem ipsumt: 0"
frm_ABC.cmd_ABC_Save.Enabled = False
frm_ABC.cmd_ABC_Next.Enabled = False
End If
What about using CStr to convert the user input to a string? You could then define a variable as the converted user input and use the variable for string concatenation.

Issue with using the String.Contains()

I am relatively new to programming, and am starting off with VB.net using Microsoft VB Studio 2019. I usually use Python, and therefore take heavy advantage of the
> If String in("y","yes","YES"):
statement so I don't have to compare the string to every item individually.
I've been trying to do this on Virtual Basic for some time now, but have not even managed to get 1 value to compare to the string to work. I've tried 2 different methods, the first just being a basic String.Contains() command, which I've set out as such:
Dim UserSelection As String
Console.Write("Play again? ")
UserSelection = Console.Read()
If UserSelection.Contains("n") = True Then
UserPlaying = False
End If
My thought process here was that the computer would look at UserSelection, and if it contained the letter 'n' at any point then it would result as being True (eg: if UserSelection = 'no', 'nope', 'n' ext ext) However, every time I've ran this code, the result always comes back as false, no matter what UserSelection is.
I've also tried using the IndexOf command (which makes the search case insensitive) to see if it would work then, but again something seems to be up with it:
Dim UserSelection As String
Console.Write("Play again? ")
UserSelection = Console.Read()
Dim subtxt As String = "n"
Dim comp As StringComparison = StringComparison.OrdinalIgnoreCase
Dim result As Boolean = If(UserSelection.IndexOf(subtxt, comp) > 0, True, False)
If result = True Then
UserPlaying = False
End If
My indentation appears correct in both blocks of code, and I cannot for the life of me figure out what it wrong here.
If someone could help me with this (especially if you could adjust the code so that it could work with multiple comparisons) then that would be more than appreciated.
Thanks so much,
Alfie :)
Console.Read returns an Integer (documentation), so naturally it would return false. The method you're looking for is Console.ReadLine (documentation), which returns a string.
Take a look at this example:
Console.Write("Play again? ")
Dim input = Console.ReadLine()
Dim stopPlaying = input.IndexOf("n", StringComparison.OrdinalIgnoreCase) > -1
If (stopPlaying) Then
' the user replied with "n", "no", "nope", etc.
Else
' the user replied with something that did not contain the letter "n"
End If
Fiddle: https://dotnetfiddle.net/Fihq02
I just added .ToLower to the UserSelection string before the Contains so N or n would be recognized.
Private UserPlaying As Boolean
Sub Main()
Console.Write("Play again? ")
Dim UserSelection = Console.ReadLine()
If UserSelection.ToLower.Contains("n") = True Then
Debug.Print("It contains n")
UserPlaying = False
Else
Debug.Print("No n")
UserPlaying = True
End If
Console.ReadKey()
End Sub

How to Evaluate a Variable Value from a String?

I've been absolutely tearing my hair out over this. Is there a simple way to pull a variable value from a string? I'm trying to use this to cleanly check the value of multiple similar variables. Example:
Dim BoxString As String
For i = 1 To 100
BoxString = "response = Report" & i & "Box.value"
Application.Evaluate (BoxString)
If response = True Then
'...
End If
Next i
For context, I'm using this to evaluate which boxes on a UserForm were selected, and perform an action for each one that was.
Thanks so much in advance!

Using Global Variables in VBA

Just started using VBA within the past week, and am playing around with Sheets vs. Modules and defining variables. Here is the code I currently have:
Sheet1:
Dim writtenvoe As Boolean
Dim verbalvoe As Boolean
Dim voerequired As Boolean
Dim CA14 As Boolean
Dim CA15 As Boolean
Dim W2s As Boolean
Dim tranapp As Boolean
Module1:
Public Sub ImpDocs()
'Is written voe on file?
If Sheet1.CheckBox6.Value = True Or Sheet1.CheckBox8.Value = True Or Sheet1.CheckBox9.Value = True Or Sheet1.CheckBox10.Value = True Then writtenvoe = True Else writtenvoe = False
If Sheet1.CheckBox6.Value = True Then Sheet1.[O40] = "hello" Else Sheet1.[O40] = ""
If writtenvoe = True Then Sheet1.[O39] = "writtenvoe = true" Else Sheet1.[O39] = "writtenvoe=false"
'Is verbal voe on file?
If Sheet1.CheckBox11.Value = True Then verbalvoe = True
'Is a written VOE required?
If Sheet1.CheckBox16.Value = True Or Sheet1.CheckBox18.Value = True Or Not IsEmpty(Sheet1.[H33]) Then voerequired = True
If voerequired = True Then Sheet1.[J35] = "hello" Else Sheet1.[J35] = ""
'Are tax docs CA14 or CA15?
If Sheet1.CheckBox31.Value = True Or Sheet1.CheckBox7.Value = True Or Sheet1.CheckBox32.Value = True Or Sheet1.[H29].Value > 25 Then CA15 = True Else CA15 = False
If CA15 = False Then CA14 = True Else CA14 = False
'Are W-2's on file?
If Sheet1.CheckBox12.Value = True And Sheet1.CheckBox13.Value = True Then W2s = True
'Are 4506-T's on file?
If Sheet1.CheckBox60.Value = True And Sheet1.CheckBox61.Value = True Then tranapp = True
'Order Wage transcripts if W-2s and 4506-T not on file
If W2s = False And tranapp = False And CA14 = True Then Sheet4.fullCA14
End Sub
Also Module 1 (2nd Subroutine):
Public Sub test()
If writtenvoe = True Then Sheet1.[N37] = "Yes" Else Sheet1.[N37] = "No"
End Sub
I noticed that in this current format, Sub ImpDocs works well and the variables are determined correctly, but Sub test always comes back as false. However, if I put all of the code into module 1, everythis works as expected. It seems like only Sub test is affected from declaring variables in Sheet1 vs Module1. Is that true? If so, why?
Thank you.
Sheet1 is a Worksheet object, an instance of a class. So even if you declare everything Public on Sheet1, you won't be able to access them without first accessing the instance.
Dim is used for declaring local variables. It's also legal at module-level, but then it's equivalent to using Private to declare them: no variable declared with the Dim keyword is ever going to be publicly accessible - my recommendation is to use Dim for locals, and use Private/Public for module variables.
When you declare Public variables in a standard module (as opposed to a class module), you're effectively declaring global variables - each of which is accessible for both read and write, from anywhere in the project. If this sounds like a good idea, please take the time to research about "pros and cons of global variables" - regardless of the language, they're usually a recipe for disaster. You want your variables to be written by specific code only, and you want the scope of your variables to be as limited as possible.
Learn how to pass parameters to your procedures instead.
You're discovering the difference between standard modules and classes: pretty much everything around you (Application, Range, Sheet1, etc.) is an object. Objects are instances of a certain class (Excel.Application, Excel.Range, Excel.Worksheet, etc.), and each instance encapsulates its own state.
Standard modules are great for macro entry points, not so great for encapsulation - and encapsulation is one of the fundamental pillars of object-oriented programming (OOP).
This is a quirk on how VBA does its namespaces (https://en.wikipedia.org/wiki/Namespace). Back in Sheet1, you'll need to make writtenvoe a Public member of Sheet1:
Public writtenvoe As Boolean
Then, back in Module1, every time you want the writtenvoe of Sheet1, you must specify Sheet1.writtenvoe, e.g.:
'Is written voe on file?
If Sheet1.CheckBox6.Value = True Or Sheet1.CheckBox8.Value = True Or Sheet1.CheckBox9.Value = True Or Sheet1.CheckBox10.Value = True Then Sheet1.writtenvoe = True Else Sheet1.writtenvoe = False
When you moved writtenvoe out of Sheet1 and into Module1, you've effectively removed Sheet1.writtenvoe and created Module1.writtenvoe, thereby making something easily accessible by Module1. The namespaces of modules are very permissive, so anything declared Public inside a module is pretty much available anywhere - another module, any Sheet, any Class Module, etc.

cancel or hide input box in vba

I have a code which asks for an input between 1-3 using an InputBox which then runs a code depending on what input it is given. The problem i have is that i don't need that InputBox anymore, as the work i intend to do only uses one input which is 3.I tried removing the input box and just inserting 3 there but then the code doesnt do anything. I then tried to insert a default value in the box, but it still appears and needs me to click enter which is what i am trying to avoid. Pls how should i go about this problem.
My Code
Function GetTypeFile() As Integer
Dim strInput As String, strMsg As String
Dim Default
choice = 0
While (choice < 1 Or choice > 3)
Default = "3"
strMsg = "Type in the kind of entities to create (1 for points, 2 for points and splines, 3 for points, splines and loft):"
strInput = InputBox(Prompt:=strMsg, _
Title:="User Info", Default:=3, XPos:=2000, YPos:=2000)
'Validation of the choice
choice = CInt(strInput)
If (choice < 1 Or choice > 3) Then
MsgBox "Invalid value: must be 1, 2 or 3"
End If
Wend
GetTypeFile = choice
End Function
Your function returns the value to wherever it's called, so you could just use:
Function GetTypeFile() As Integer
GetTypeFile = 3
End Function
or just replace any calls to the function with the number 3.
So rather than something like:
Sub Test()
ThisWorkbook.SaveAs "MyFileName", GetTypeFile
End Sub
You'd have:
Sub Test()
ThisWorkbook.SaveAs "MyFileName", 3
End
Thank you all for your reply. I just understood what to do, by setting the variable which is dependent on the value in the inputbox to 3 instead of it being TypeDocument=GetTypeFile it is now TypeDocument=3 directly..I think that is what you all had been trying to say all the while. Thank you again.

Resources