Enhancing the Editor
(By Gregory Hampton)
I don't know if this will be as much use but one thing that I find difficult
to see are VB Comments. VB defaults the comment lines to a pale green. I have found a preference to
have the comments scream at me telling me what is going to happen or what
should happen. The way that I do this is to change the comment text format
to black text on a yellow background. It really makes the comments stand
out in the code window. It also has the ability to make it immediately
obvious that you don't have enough comments in the code. For those who are
not aware, you can change the text properties by selecting Tools/Options,
then click the Editor Format tab, and change the text format for several
options.
ByVal Arrays
Visual Basic only lets you pass arrays ByRef not ByVal. The reason is performance.
When you pass a parameter ByVal,
the system makes a copy of the parameter and passes the copy to the new
routine (sort of). Then if the routine modifies the copy, the change is
not seen in the original parameter.
That's no big deal for integers, doubles, and other "small" types. It
can be a bit of an issue for really big strings. If the string is really
huge, copying it will take a little while.
It can be an even bigger problem with arrays. If the array is big
enough, making a copy could take a relatively long time and use up a lot
of memory.
If you really want to work with a copy, make your own. If the_array is
an array of Integer, you can do this:
Dim array_copy() As Integer
array_copy = the_array
TheRoutine array_copy
Of course, you'll pay a small price in speed and memory if the array is
big.
Compressing Spaces
(By Bill Matthews)
This routine replaces multiple occurrances of spaces with single spaces.
' Replaces sequential spaces with single spaces.
' Spaces on either end are removed.
Private Function PreventDuplicateSpaces(Word)
Dim i, WordLength, Character, LastCharacter, NewWord
On Error GoTo ErrorHandler
WordLength = Len(Word)
For i = 1 To WordLength
Character = Mid(Word, i, 1)
If LastCharacter = " " And Character = " " Then
Else
NewWord = NewWord & Character
LastCharacter = Character
End If
Next i
PreventDuplicateSpaces = Trim(NewWord)
Exit Function
ErrorHandler:
' Insert your favorite error handler here.
End Function
Steve Okonski offers this version which is about 50 times faster.
Function fastremoveduplicatespaces$ (txt$)
Dim localtxt$, pt%
localtxt$ = Trim$(txt$)
Do
pt% = InStr(localtxt$, " ") ' 2 blank spaces
If pt% = 0 Then Exit Do
localtxt$ = Left$(localtxt$, pt%) + Trim$(Mid$(localtxt$, pt%))
Loop
fastremoveduplicatespaces$ = localtxt$
End Function
In Visual Basic 6, the following function is about the same speed as Steve's version and is a bit simpler.
Private Function CompressSpaces(ByVal txt As String) As String
Do While InStr(txt, " ") > 0
txt = Replace(txt, " ", " ")
Loop
CompressSpaces = txt
End Function
Click here to download a program that compares these routines.
Save Numeric Options
(By Trevor Finch)
As a programme develops more user options are often needed.
This is a method for saving lots of numeric options in a record without
having to create new integer or logical fields in a table.
The string 'ms_Options' is saved in a field in a table, and is initialised
to String(255, "G").
The reason for "G" is that it gives a range of -6 -> 250 that is all
printable ascii, so you can debug easily. In practice Asc("G") is a
constant, and there are other error checks.
Public Property Get Options(ai_Which as integer) as Integer
Options = Asc(Mid(ms_Options, ai_Which, 1)) - Asc("G")
End Property
Public Property Let Options(ai_Which as integer, ai_Value as integer)
Mid$(ms_Options, ai_Which, 1) = Chr$(ai_Value + Asc("G"))
End Property
List Available Symbols
(By Dario)
If you press Ctrl-J, the development environment shows a dropdown list of the symbols
that are appropriate at that point. For example, if you type "Me.Show", click on Show,
and press Ctrl-J, the dropdown list shows symbols available after "Me."
If you move to a blank line and press Ctrl-J, you'll see a list of constants,
functions, and properties appropriate at that point.
Larry Northcutt adds, "
If you press Ctrl-Spacebar it does the same thing and is much easier on the fingers as there is no stretch involved with the J character."
Use LSet
By Trevor Finch
I have been using Basic for some years, but VB for only a few, but I have
only just found out that LSet will copy a user data structure !!!
This will delete a record, and move all records up...
For i = iCurrent To iCount - 1
LSet Structure(i) = Structure(i + 1)
Next i
Help also says LSet can be used reading Binary files
Perhaps it can be used to read unsigned integers ?
[I think you can do this if you just want to carry the unsigned value around.
If you want to understand the value or modify it, you need to examine the pixels more
closely to see what they mean. -- Rod]
Learn Object Types
(By Rod Stephens)
If you want to know whether it is a particular type, do something like:
If TypeOf obj Is ListItem Then ...
If you want the name of the object's type, use:
MsgBox "The item is a " & TypeName(obj)
Control Infinite Loops
By Michael Vlastos
When you have trapped inside a non-ending loop, as you cannot press
any command buton or key, the only sulution is placing the command
"DoEvents" at the first line inside the loop:
Dim i As Long
For i = 1 To 1000000
DoEvents
...
Next i
[Actually DoEvents doesn't need to be the first line. Wherever you put it, it gives other parts of your program like a button that ends the loop a chance to receive events. -- Rod]
Faster Infinite Loops
By Cesare Cogliandro
Well, I have found that generally it's better to use the API function
GetInputState to check the presence of events in the app's input queue. I
don't know why the addiction of an "If" statement improves the code speed,
but it works very fine.
So you could replace the row
DoEvents
with
If GetInputState() Then DoEvents
Try to believe.
[The reason this makes things faster is that DoEvents allows all applications to process events, not just yours. This test allows DoEvents to run only when your program has events. -- Rod]
Dean Maynard points out that this method makes the program hog the system resources, prevents it from repainting (GetInputState only returns True when a mouse or keyboard event is pending, not when the form needs refreshing), etc. Dean found that the following code reduces the program's resource usage to practically nothing.
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Do While
DoEvents
Sleep 1
Loop
This allows the rest of the system to take action while your program sleeps.
Note that these two styles of program are in loops for different reasons. In the original program, we assume the program is performing some sort of important calculation and you might want to stop it. The loop lets the program continue computing.
Dean's program is a winsock application and it was waiting in a loop for something to happen. It wasn't trying to perform any calculations and hogging the CPU was bad. In Dean's words:
As far as I can tell, with the sleep call in there, your
app stays just as responsive, but does not hog nearly
the resources. To me, writing an app which hogs 90%+
resources is just bad programming "manners." unless
there's absolutely no other way around it.
Make Select Case Easier
By Richard Sheridan
Let us say that you are creating a string, by letting the user click on various combinations of labels...
lbl(0) = "Hello "
lbl(1) = " I'm "
lbl(2) = " Happy"
lbl(3) = " Sad"
...
sub lbl_click (index as integer)
string$ = string$+lbl(index).caption
You would have a series of select case statements to evaluate the string...
select case string$
case "Hello I'm Happy"
do something
case "Hello I'm"
this would be an error...
case else
do something else
end select
I realised that this could get very complicated, especially if you had loads of labels and valid / invalid combinations.
So I created an array as large as the number of labels:
arraylbl(n) as integer
Starting with the value of 1, each cell was (value*2) of previous cell: 1 2 4 8 16 32 64... This would give a unique code to every combination of labels:
lbl(0) and lbl(1) = 1 + 2 = 3
lbl(0) and lbl(1) and lbl(4) = 1 + 2 + 16 = 19
Now, when a label is clicked, add its lblarray() code to a variable, say IsLegal (as integer). Obviously, if the label is un-selected by the user, you would have to ensure it had previously been selected, before subtracting the value from IsLegal.
You can easily set up a select case, based upon just a few valid numbers:
select case IsLegal
case 3
' the string was valid
call goodstuff
case 19
'the string was valid
call goodstuff
case else
'invalid
call nogood
end select
Send your Tips and Tricks to feedback@vb-helper.com.
|