by Rde (54 Submissions)
Category: Miscellaneous
Compatability: Visual Basic 5.0
Difficulty: Beginner
Date Added: Wed 3rd February 2021
Rating: (5 Votes)
Some very basic but handy tips for newbies (and maybe not so newbies). Hope you learn something.
I've added quite a bit more to the article, mostly very basic info on the vb language, but we all had to learn this stuff when we started out.
A Brief History of Basic
- BASIC - Beginner's All-purpose Symbolic Instruction Code.
- This language was developed in the early 1960's at Dartmouth College.
- Answer to complicated programming languages (FORTRAN, Algol, Cobol...). First timeshare language.
- In the mid-1970's, two college students write first Basic for a microcomputer (Altair) - cost $350 on cassette tape. You may have heard of them: Bill Gates and Paul Allen.
- Every Basic since then is essentially based on that early version. Examples include: GW-Basic, QBasic, QuickBasic.
- Visual Basic was introduced in 1991.
Tips
In VB's Tools > Options > Editor Format tab > Code Colors
Select Identifier Text > then Foreground > Dark Red!
I recommend that you uncheck:
Tools > Options > Editor tab > Auto Syntax Check
Syntax checking is still enabled but instead of freezing the editor until you dismiss the msgbox and correct the error, the offending code is simply displayed in red, allowing you to continue coding unhindered, and can return to the 'red devil' when finnished what you're doing. Rd.
I often see this:
Dim var1, var2, var3 As String
This initializes 2 variants and 1 string, it's the same as this:
Dim var1 As Variant, var2 As Variant, var3 As String
I assume the coder desires:
Dim var1 As String, var2 As String, var3 As String
Use VarType or TypeName to see for yourself.
Added this bit thanks to Timothy Marin. Some say not to use these (and james kahl has a point) but it's up to you:
Dim fff$ ' Declares a String variable
Dim hhh% ' Declares a Integer variable
Dim ggg& ' Declares a Long variable
Dim iii! ' Declares a Single variable
Dim jjj# ' Declares a Double variable
Dim kkk@ ' Declares a Currency variable
I often see this:
If Dir$(sFileName) <> "" Then
' I believe I have a file,
' do some work on it
End If
This code will fail if sFileName = "" because Dir will return the name of the first file found (with any name) You can do this instead:
If sFileName <> "" Then
If Dir$(sFileName) <> "" Then
' We have a file, do some work on it
End If
End If
Or as Luke H so rightly pointed out, you should do this:
If LenB(sFileName) <> 0 Then
If LenB(Dir$(sFileName)) <> 0 Then
' We have a file, do some work on it
End If
End If
This lot's from Bruce McKinney's book 'Hardcore VB'
That statement works until you specify a file on an empty floppy or CD-ROM drive. Then you’re stuck in a message box. Here’s another common one:
fExist = FileLen(sFullPath)
It fails on 0-length files — uncommon but certainly not unheard of. My theory is that the only reliable way to check for file existence in VB (without benefit of API calls) is to use error trapping. I’ve challenged many Visual Basic programmers to give me an alternative, but so far no joy. Here’s the shortest way I know:
Function FileExists(sSpec As String) As Integer
On Error Resume Next
Call FileLen(sSpec)
FileExists = (Err = 0)
End Function
This can’t be very efficient. Error trapping is designed to be fast for the no fail case, but this function is as likely to hit errors as not. Perhaps you’ll be the one to send me a Basic-only ExistFile function with no error trapping that I can’t break. Until then, here’s an API alternative:
Function ExistFileDir(sSpec As String) As Boolean
Dim af As Long
af = GetFileAttributes(sSpec)
ExistFileDir = (af <> -1)
End Function
I didn’t think there would be any way to break this one, but it turns out that certain filenames containing control characters are legal on Windows 95 but illegal on Windows NT. Or is it the other way around? Anyway, I have seen this function fail in situations too obscure to describe here. Bruce McKinney.
Here's my solution:
Function FileExists(sFileSpec As String) As Boolean
If (sFileSpec = vbNullString) Then Err.Raise 5
On Error GoTo NoGo
Dim Attribs As Long
Attribs = FileSystem.GetAttr(sFileSpec)
If (Attribs <> -1) Then
FileExists = ((Attribs And vbDirectory) <> vbDirectory)
End If
NoGo:
End Function
Function DirExists(sPath As String) As Boolean
If (sPath = vbNullString) Then Err.Raise 5
On Error GoTo NoGo
Dim Attribs As Long
Attribs = FileSystem.GetAttr(sPath)
If (Attribs <> -1) Then
DirExists = ((Attribs And vbDirectory) = vbDirectory)
End If
NoGo:
End Function
Data types in VB
Numeric Data : Integers (whole numbers without decimal
places) and Real (decimals, or floating-point numbers).
Suf
Type
Storage
Range
Byte
1 byte
0 to 255
%
Integer
2 bytes
-32,768 to 32,767
&
Long
4 bytes
-2,147,483,648 to 2,147,483,647
!
Single
4 bytes
-3.42823E+38 to -1.401298E-45 (neg) and
1.401298E-45 to 3.42823E+38 (pos)
#
Double
8 bytes
-1.79769313486232E+308 to
-4.94065645841247E-324 (negative) and
4.94065645841247E-324 to
1.79769313486232E+308 (positive)
@
Currency
8 bytes
-922,337,203,685,477.5808 to
922,337,203,685,477.5807 (the extra
precision ensures accuracy to 2 dec places)
Decimal
12 bytes
+/-79,228,162,514,264,337,593,543,950,335
(with no decimal, or up to 28 decimal places)
+/-7.9228162514264337593543950335
Shift State
Constant
Value
Description
vbShiftMask
1
SHIFT key bit mask.
vbCtrlMask
2
CTRL key bit mask.
vbAltMask
4
ALT key bit mask.
Presently, only three of the 32 bits in the Shift parameter
are used. In future versions of Visual Basic, however, these
other bits may be used. Therefore, as a precaution against
future problems, you should mask these values appropriately
before performing any comparisons. Use a bitwise And to mask
the Shift parameter:
Dim ShiftState As Integer
ShiftState = Shift And vbShiftMask
In the above example ShiftState will hold zero if the Shift
key was not pressed, or one if pressed (in any combination
with the Ctrl and Alt keys). Likewise, you can mask the Shift
parameter against vbCtrlMask to return zero or two, and
vbAltMask to return zero or four.
Dim ShiftDown As Boolean
Dim CtrlDown As Boolean
Dim AltDown As Boolean
ShiftDown = (Shift And vbShiftMask) = vbShiftMask
CtrlDown = (Shift And vbCtrlMask) = vbCtrlMask
AltDown = (Shift And vbAltMask) = vbAltMask
True-conditions perform faster. So, if you can make assumptions about
your conditions, set up the code so that the test returns True.
Before continuing, SAVE your project to disk for safety!
Max Path Length
Const MAX_PATH As Long = 260
The maximum length, in characters, of a file path supported by the
specified file system. A filename component is actually that portion
of a file path between backslashes.
Under NT (Intel) and Win95 it can be up to 259 (MAX_PATH - 1) characters
long. This length must include the drive, path, filename, commandline
arguments and quotes (if the string is quoted).
Notice that the MAX_PATH constant is assigned 260 on Windows 9x systems.
This is because it combines the root ("x:\"), the Maximum Component Length
value (255), plus a possible trailing backslash ("\") character.
Len(sPath) <= 3 + 255 + 1 or Len(sPath) < MAX_PATH
The complete path must be less than MAX_PATH characters.
Logical Operators
The logical operators enable you to combine two or more sets of
conditional comparisons.
And
Both sides must be True (to return True)
Or
Only one side need be True, or both
Xor
Only one side must be True, not both
Not
Reverses (inverts) boolean condition
The And logical operator requires both sides to be True to
return True.
If (x >= 1) And (x <= 10) Then ...
The Or logical operator needs only one side to be True to
return True. This operator is really an Inclusive Or.
If (y = 0) Or (z <> 10) Then ...
The Xor logical operator requires that only one side CAN be
True to return True. Therefore, its is an Exclusive Or.
If (count1 = limit) Xor (count2 = limit) Then
CountSyncErrorOccured
End If
The Not logical operator inverts the boolean value.
The following two code examples both reverse the value:
result = Not (expression)
result = (expression) Xor True
Be careful with the Xor and Not operators, as they only work
(as you might expect) with boolean True and False values. So
expression must evaluate to a boolean True or False value.
Note - True equates to -1, and False equates to 0.
Because zero equates to False, and all other numbers equate
to True when tested within a conditional (an If statement for
example) you can generally do this:
If iNum Then
'Do something
End If
If iNum is not zero it will equate to True, including
negative values:
3 = True
2 = True
1 = True
0 = False
-1 = True
-2 = True
-3 = True
But if you wanted to reverse the condition as follows,
it may not work as you expect:
If Not iNum Then
'Do something
End If
Only if iNum is -1 will the conditional equate to False.
Any other value including zero will equate to True:
Not 3 = -4 ' True
Not 2 = -3 ' True
Not 1 = -2 ' True
Not 0 = -1 ' True (Not False)
Not -1 = 0 ' False (Not True)
Not -2 = 1 ' True
Not -3 = 2 ' True
So do the following when using Not with numeric values:
If Not CBool(iNum) Then
'Do something
End If
Not CBool(3) = False ' Not True
Not CBool(2) = False ' Not True
Not CBool(1) = False ' Not True
Not CBool(0) = True ' Not False
Not CBool(-1) = False ' Not True
Not CBool(-2) = False ' Not True
Not CBool(-3) = False ' Not True
Note that Xor works the same.
Conditional Operators
VB supports six conditional operators:
= Equal to
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to
<> Not equal to
VB also supports a special kind of conditional operator:
Like Performs comparisons using wildcards
Here are the widcards that can be used with Like:
* Any character or characters
? Any alpha character (letters)
# Any numeric character (numbers)
[] Encloses possible characters
- Specifies a range
e.g:
"This string" Like "This*" returns True
"This string" Like "This ???ing" returns True
"Numeric 123" Like "Numeric ###" returns True
"Version 2 b" Like "Version [123] *" returns True
"" Like "[]" returns True
"E" Like "[C-H]" returns True
Use the [] to test for a possible character within a group.
By using a hyphen (–) to separate the upper and lower bounds
of the range, charlist can specify a range of characters. The
meaning of a specified range depends on the character ordering
valid at run time (as determined by Option Compare and the
locale setting of the system the code is running on). Using
the Option Compare Binary, the range [A–E] matches A, B, C, D, E.
With Option Compare Text, [A–E] matches A, a, À, à, B, b,... E, e.
The range does not match Ê or ê because accented characters
fall after unaccented characters in the sort order.
Mathematical Operators
The mathematical operators perform calculations on numerical
values:
() Parenthesis
^ Exponentiation (Power Of)
* Multiplication
/ Division
\ Integer Division
Mod Modulus
+ Addition
- Subtraction
Operator Precedence
Precedence is the order of importance given to operators in VB.
In other words, precedence determines which part of an expression
will be executed first.
The following is the order of precedence from highest to lowest:
() Parenthesis
^ Exponentiation (Power Of)
* / \ Mod Multiplication, Division, Int Division and Modulus
+ - Addition and Subtraction
Like Performs comparisons using wildcards
Not Reverses (negates) boolean condition
And Both sides must be true
Or Only one side need be true, or both
Xor One side must be true, but not both
Before continuing, SAVE your project to disk for safety!
Byte arrays are the only way to store binary data in a stable
format that won't be modified by Unicode conversion.
To Add a text file or other non-standard file into a VB project
edit the .vbp file and insert a line similar to this:
RelatedDoc=readme.txt
The file will be displayed in the Resources section of the
project explorer.
A loop used to remove selected items from a list without error:
For i = lstData.ListCount - 1 To 0 Step -1
If lstData.Selected(i) Then lstData.RemoveItem i
Next
Option buttons use the property .Value = True|False while
Checkboxes use the property .Value = 0|1|2 to specify checked.
You can put more than one statement on a line by separating them
with a colon :
Dim myInt%: myInt = 0
Thanks Timothy Marin for this tip.
Before continuing, SAVE your project to disk for safety!
If you want to place controls in a frame but already have the controls
on the form, just select all controls (with selection tool or hold down
the CTRL key as you click each control), and CUT, then place the
frame on the form, then with the frame selected, PASTE.
KeyPress and KeyDown Events
The KeyPress event occurs when the user presses the Uppercase and
Lowercase letters, Numeric digits, Punctuation keys, and the Enter,
Tab, and Backspace keys.
Some VB Constants are: vbKeyReturn, vbKeyTab and vbKeyBack.
KeyPress events capture just the main ASCII characters (letters,
numbers and punctuation) plus Backspace, Enter and Tab.
KeyPress handles the shift state itself, passing the event procedure
the correct code. The event object recieves the keycode (as was or
modified) AFTER the procedure ends.
This makes KeyPress the event handler to use when you wish to process
and/or modify the characters before they are displayed in the form's
event object.
KeyDown events capture ALL keyboard keys, but only recognize letters
in all caps, so you must test for shift state as well for lowercase.
KeyUp (like KeyDown) receives only uppercase keycodes.
KeyDown does not wait to pass the key code on to the form object,
while KeyPress passes the key code on to the event object after
the procedure ends.
With KeyDown the event object handles the shift state itself, so
the event object receives upper or lowercase according to the shift
and caps lock key states - then the KeyDown event procedure runs.
You might think that you could save space by declaring a
variable As Byte or As Integer instead of As Long. However, on
32-bit operating systems the code to load a Long is faster and
more compact than the code to load shorter data types.
Not only could the extra code exceed the space saved, but there
might not be any space saved to begin with — because of alignment
requirements (32-bit) for modules and data.
Subs and Funcs
A subroutine does not return a value.
Private Sub cmdSubCalculate_Click()
Call multiply1(2, 3)
End Sub
Private Sub multiply1(ByVal x As Integer, ByVal y As Integer)
Dim z As Integer
z = x * y
txtResult.Text = z
End Sub
A function returns a value by assigning the resulting
value of its processing to a 'variable' (the name of the
function) which is returned to the calling subroutine or
function.
Private Sub cmdFuncCalculate_Click()
txtResult.Text = Multiply2(2, 3)
End Sub
Private Function Multiply2(ByVal x As Integer, ByVal y As Integer) As Integer
Dim z As Integer
z = x * y
Multiply2 = z
End Function
Both subs and functions can have arguments passed by
reference, allowing the source variable to be modified
by the procedure.
Private Sub cmdByRefCalculate_Click()
Dim z As Integer
If (Multiply3(2, 3, z) Then
txtResult.Text = z
End If
End Sub
Private Function Multiply3(ByVal x As Integer, ByVal y As Integer, ByRef z As Integer) As Boolean
z = x * y
Multiply3 = True
End Function
You can add quit confirmation to a windows standard exit methods:
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
' A forms QueryUnload event occurs immediately before the
' form unloads.
' UnloadMode is zero when a window is closed by using any
' of the standard exit methods (by clicking the [x] close button,
' by selecting close from the windows context menu, by pressing
' ALT-F4, or by double-clicking the window icon in the top-left
' corner).
' Cancel (passed by reference to the event) is zero (False), and
' so the form will unload; False means 'not to Cancel the unload'.
' You can cancel the unloading of the form by setting Cancel to
' one (True); so saying 'yes to Cancel the unload'.
If UnloadMode = 0 Then
Dim dialogtype As Integer
Dim title, msg As String
Dim response As Integer
dialogtype = vbYesNo + vbQuestion
title = "Name of program"
msg = "Are you sure?"
response = MsgBox(msg, dialogtype, title)
If response = vbNo Then
Cancel = True
End If
End If
End Sub
The UnloadMode variable in the Query_Unload event indicates how
this event was triggered by containing one of the five values in
the following table.
QueryUnloadConstants:
vbFormControlMenu = 0
The user chose the Close command on the Control-menu box.
vbFormCode = 1
The application used the Query_Unload method itself.
vbAppWindows = 2
The operating system is being shut down, or the user is
logging off.
vbAppTaskManager = 3
The application is being shut down by the Task Manager.
vbFormMDIForm = 4
An MDI form, which closes all child forms belonging to it,
is being closed.
vbFormOwner = 5
The owner of the form is closing.
Select Case Statement
Executes one of several groups of statements, depending
on the value of an expression.
Select Case Index
Case 0
Grade = "first"
Case 1
Grade = "second"
Case 2
Grade = "third"
Case 3
Grade = "fourth"
Case 4
Grade = "fifth"
Case 5
Grade = "sixth"
End Select
The same Case Statement using colons:
Select Case Index
Case 0 : Grade = "first"
Case 1 : Grade = "second"
Case 2 : Grade = "third"
Case 3 : Grade = "fourth"
Case 4 : Grade = "fifth"
Case 5 : Grade = "sixth"
End Select
VB also offers a way of testing for a condition
with the Is keyword added to Case:
Select Case testscore
Case Is >= 80
student_grade = "A"
Case Is >= 65
student_grade = "B"
Case Is >= 50
student_grade = "C"
Case Else
student_grade = "F"
End Select
So the following two examples are the same:
Select Case Format(today, "mmmm")
Case "January": optjan.Value = True
Case "February": optfeb.Value = True
Case "March": optmar.Value = True
Case "April": optapr.Value = True
Case "May": optmay.Value = True
Case "June": optjun.Value = True
Case "July": optjul.Value = True
Case "August": optaug.Value = True
Case "September": optsep.Value = True
Case "October": optoct.Value = True
Case "November": optnov.Value = True
Case "December": optdec.Value = True
End Select
Select Case Format(today, "mmmm")
Case Is = "January": optjan.Value = True
Case Is = "February": optfeb.Value = True
Case Is = "March": optmar.Value = True
Case Is = "April": optapr.Value = True
Case Is = "May": optmay.Value = True
Case Is = "June": optjun.Value = True
Case Is = "July": optjul.Value = True
Case Is = "August": optaug.Value = True
Case Is = "September": optsep.Value = True
Case Is = "October": optoct.Value = True
Case Is = "November": optnov.Value = True
Case Is = "December": optdec.Value = True
End Select
The usage for the Case Is format allows the testing of conditions
that don't have to be an exact match (=), but can also be other
conditions (>, <, >=, <=, etc). Only the use of simple comparisons
are allowed, so no logical operators (And, Or, Xor, or Not) can
be used.
Select Case varInteger
Case Is <= 150: MsgBox "Is 150 or less"
Case Is <= 200: MsgBox "Is between 151 and 200 inclusive"
Case Else: MsgBox "Is 201 or greater"
End Select
It is important to realize that with such conditional tests the order
of each Case Is matters. Consider if the above Case statement was
like this:
Select Case varInteger
Case Is <= 200: MsgBox "Is 200 or less"
Case Is <= 150: MsgBox "Is 150 or less"
Case Else: MsgBox "Is 201 or greater"
End Select
Even if the integer value was below 150 the condition would still
execute only the code corresponding to the first Case tested.
In addition to the formats used above, Select Case statements can
also include the To keyword, as follows:
Select Case Asc(Char)
Case 65 To 90: MsgBox "Uppercase 'A' to 'Z' inclusive"
Case 97 To 122: MsgBox "Lowercase 'a' to 'z' inclusive"
End Select
You can combine the different formats into a single Case statement:
Select Case varInteger
Case 100 To 130, 140
MsgBox "Is between 100 and 130 inclusive, or is 140"
Case 150 To 180, 190, Is >= 200
MsgBox "Is between 150 and 180 inclusive, or is 190, or is 200 or greater"
Case Else
MsgBox "All else (below 100, 131 to 139, etc)"
End Select
You also can specify ranges and multiple expressions for
character strings.
In the following example, Case matches strings that are exactly
equal to everything, strings that fall between nuts and soup in
alphabetic order, and the current value of TestItem:
Case "everything", "nuts" To "soup", TestItem
Gaussian Rounding
A remark by René Rhéaume, 21.09.01
This "Banker's" method uses the Gauss rule that if you are
in an perfect half case, you must round to the nereast digit
that can be divided by 2 (0,2,4,6,8). This rule is important
to obtain more accurate results with rounded numbers after
operation.
Now, an example :
2 digits 2 digits
Unrounded "Standard" rounding "Gaussian" rounding
54.1754 54.18 54.18
343.2050 343.21 343.20
+106.2038 +106.20 +106.20
========= ======= =======
503.5842 503.59 503.58
Which one is nearer from unrounded result? The "Gaussian" one
(Difference of 0.0042 with "Gaussian/Banker" and 0.0058
with "Standard" rounding.)
Another example with half-round cases only:
1 digit 1 digit
Unrounded "Standard" Rounding "Gaussian rounding"
27.25 27.3 27.2
27.45 27.5 27.4
+ 27.55 + 27.6 + 27.6
======= ====== ======
82.25 82.4 82.2
Again, the "Gaussian" rounding result is nearer from the
unrounded result than the "Standard" one.
René Rhéaume
[email protected]
Rd.