Good and Bad Coding
Let's say you need a function and you go fishing on the Internet. Bingo! You've found it. But what's wrong? The code is awful. You can't use it. It is poorly written. Some of us can not afford spending days in search of good code once they've already found something that works. The business just does not stand still. So what?
What makes a program really good and nicely readable is a comment. Some of us work in a really quick pace and do not have time or intention to write it. I do not vote against comments, I just want to justify why the good code always says more than the best comment.
Let's take a look at some examples what is good and what is not very.
1. Use built-in constants.
Good:
res = (MsgBox "You've got mail. Open it?",vbYesNo or vbQuestion, App.Title)
If res = vbYes then
End if
Bad:
res = MsgBox ("You've got mail. Open it?", 36)
if res = 6 then
end if
2. Using IIF function often saves space and in simple cases adds clarity:
Good:
Res = Iif(A>B, A, B)
Not so good:
If A>B then
Res = A
Else
Res = B
End if
3. Use Select clause
When you are doing multiple selections it's the only choice.
It's not obvious when you have to select between 2 or 3 things. But, still I recommend using it.
Why? You might add a new condition at any time without messing up the whole program.
Good:
select case A
case 1:
case 2:
case else:
end select
Bad:
If A=1 then
'..
elseif A=2 then
'..
else
'..
end if
4. Always use Option Explicit
It really helps by checking the code syntax for you.
5. Avoid using non-restrictive or dynamic data types
It also helps when it comes to a later modifications.
Bad:
for k%=1 to 10
' ... some code
next
Good:
Dim k as Long
For k = 1 to 10
'... some code
next k
6. Use condition checking with caution
Good, if you use correct parentheses:
Dim Res as boolean
Res = (A=B)
'in some cases if you omit the parentheses you'll have problems
Good:
If A=B then
Res = true
Else
Res = false
End if
7. Error Handling
'rem Make it the habit in the very beginning of every function/sub include the following clause:
On Error Goto ErrHand
'? some code goes here
'and in the end of the function/sub make the label working
ErrHand:
If Err then
MsgBox Err.Description, vbExclamation, App.Title
Err.clear
End if
End Sub
The bad habit here would be skipping error handling at all or using On Error Resume Next, which is even worse. You will inevitably end up with long hours of searching for the hidden errors. The absolute worst thing here that might happen is when the error appears in one function and is transmitted to another function.
8. Window resizing
You'll never know what the user wants. The only thing he wants for sure is to be able to resize a window to a bigger size of a full screen. Make it happen. Use Form_Resize event.
But your form may contain controls that cannot be smaller than a certain size. Fix it.
In your code declare constants MINHEIGHT and MINWIDTH and use them.
Private Sub Form_Resize
On Error GoTo ErrHand
With Me
If .Height < MINHEIGHT Then .Height = MINHEIGHT
If .Width < MINWIDTH Then .Width = MINWIDTH
'?
9. Use With clause
Good:
With frmMyForm
.cboxNoAccess.Value = True
.cmdOk.Enabled = True
End With
' if you use With and then call form controls by their names preceded
' by dots, you'll get a full advantage of the IDE's typeahead feature.
' This will reduce your code generation time and help you to avoid
' misspellings.
Not so good:
cboxnoaccess.value = True
cmdok.enabled = True
10. Use "CaMeL" notation
This will help you to avoid many syntax errors before you hit F5 for the first time. Typeahead feature is the thing that will always guide you.
Good:
frmMyForm.lvListView.ListItems.Clear
Worse:
myform.listview1.Listitems.Clear
11. Use full names of classes in object declarations
Good:
Dim objMyObject as MyComponent.MyObject
Bad:
Dim myobject as MyObject
This will 1) ensure you always call the correct object, 2) allow you more easily switch to Late Binding in case you do not need Early Binding for that particular application.
12. Use Enum type for function parameters
Good:
Private Enum enumCity
Tampa
StPetersburg
London
Paris
End Enum
Private Sub CallCity(enCity as enumCity)
'..
End Sub
Bad:
Private Sub CallCity(enCity as integer)
'..
End sub
13. Forget the Integer data type
You work in the 32-bit environment anyway.
Good:
Private Function FunMult(byval nA as Long, byval nB as Long) as Long
FunMult = nA + nB
End Function
Bad:
Private Function FunMult(byval a as Integer, byval b as Integer) as Integer
'..
You'll inevitably end up with searching why in some cases the result value is smaller than one of the parameters J
14. Avoid using For clause when you do not know how many cycles your loop will go.
Good:
rs.MoveFirst
do while not rs.EOF
'?
rs.MoveNext
loop
Bad:
rs.MoveFirst
For k = 1 to 9999
If rs.EOF then exit for
'?
next
15. Always declare:
all your application-scope variables in a standalone BAS-module,
all module-scope variables in the very beginning of the module,
all function-scope variables in the very beginning of the function.
This will help you to find double-declarations, will help you to see all your currently active variables at the same time and in the same place.
16. Never declare class properties as simple variables like
Public MyProperty as string
Instead, use the Get-Let style:
Public property Let MyProperty(vNewValue as string)
'?
End property
Public property Get MyProperty as string
'?
End property
First, it allows you create unidirectional properties (read only, write only) and helps you to avoid breaking the interface compatibility if you want to change the object behaviour depending on the property value in the future.
17. Avoid using the same DLL file for Binary Compatibility in the Project Options. Create the copy of the DLL, rename it to something like *.CMP so it can not be occasionally overwritten be the next version.
To be continued?