Inspired by some of the posts in the DeveloperWorks forums and on StackOverflow, I thought I would post some more basic concepts and how I handle them. I am not saying my way is the best way, this is just what works for me. I am sure there will be more posts in the future”…”
I will also mention a few other things I noticed while reading the code posted in the forums.
Retrieve something that doesn´t exist
The question is how to identify what dates there are no documents created for. This is where lists are very useful. Richard Schwartz answered this question and posted some good code.
Rich suggests to create a list of dates, with each list item having an initial values of false, and then loop through the documents. As each document is processed, the value of the corresponding list item is changed from false to true. You can then go through the list and see which dates still have a value of false, those dates are missing documents.
My version of the same code is to actually delete the list item you have a match for, instead if setting it to true. In the end you have a list of just the items of dates without a corresponding document.
Write readable code
This could be a blog entry all by itself. But I notice that much of the code in the DeveloperWorkds forums is hard to read”´”. Partially because any tabs or multiple spaces used for indenting the code is stripped out, but also because the posters don´t write easy-to-read code.
Variable names are often not descriptive:
Dim db1 As NotesDatabase
Dim db2 As NotesDatabase
Dim thisdb As NotesDatabase
Dim nabdb As NotesDatabase
Which one is easier to understand? In my opinion (and I am sure you agree) the second variant. Also function names and other variables should be named so you understand what they do and what kind of data they contain.
Comments are mostly non-existing. It is not that hard to add some comments to the code that explain what the code is doing. But don´t explain every line of actual code (it should be self-explanatory, if variables are named correctly), explain what a particular section of code is intended to do.
Here is a section of code from an agent I wrote earlier this week:
'*** Read PhotoUNID field in LossControl document'*** and build a list of the UNID values in the fieldphotoUNID = lcdoc.GetItemValue("PhotoUNID")(0)If photoUNID<>"" Then '*** Create array of values and put into photolist tmparray = FullTrim(Split(photoUNID,";")) ForAll t in tmparray If t <> "" Then photolist(t) = t End If End ForAll End If
The comments above will help the next person to look at the code to quickly understand what it is intended to do.
More on variables
Use Option Declare/Option Explicit. This will find many errors, especially for more inexperienced programmers, where variables are misspelled or missing, something that is a very common reason for posts in the forums.
Another thing that a surprisingly large number of posters seem to struggle with is how to correctly declare variables. I see many cases where several variables are declared on one row, but only the last one has the data type. The author of the code was thinking it would apply to all the variables:
Dim FirstName, LastName, Street, City, PostalCode, State as String
This will declare State as String, but all other variables as Variant. This is not unique for Lotusscript, Visual Basic (on which Lotusscript is based) works the same way.
I always declare each variable on a separate line. This makes it easier to find a particular variable if I am looking for it. I also declare all variables in the beginning of the code/function, again to make it easier to find it in the future. Finally I order the declarations in the same order:
1. Notes UI classes (so they are easy to locate, in case I need to rewrite the code to be used in a server-based agent.
2. Notes backend classes. I always declare them in the order they are being used, as this also is how the classes are structured.
3. Variables and custom classes, in the order they are used.
Here is an example, from the same agent as above:
Dim session As New NotesSession Dim photodb As NotesDatabase Dim lcdb As NotesDatabase ' LossControl DB Dim lcview As NotesView Dim lccol As NotesViewEntryCollection Dim lcentry As NotesViewEntry Dim lcdoc As NotesDocument Dim photodoc As NotesDocument Dim rtitem As Variant Dim rtnav As NotesRichTextNavigator Dim rtlink As NotesRichTextDocLink Dim cnt List As Long Dim photoUNID As String Dim unid As String Dim photolist List As String Dim verifiedlist List As String Dim tmparray As Variant Dim photos As String
As you can see, I also put a comment there, to explain what lc stands for.
I also try to use a list for counters, instead of having a number of separate variables. Doing that makes the code easier to read and understand, despite it actually being longer:
cnt("Total") = lccol.Count cnt("Processed") = 0 cnt("Updated") = 0 cnt("UpdatedPhoto") = 0
cnt("Processed") = cnt("Processed") + 1 If cnt("Processed") Mod 10 = 0 Then Print cnt("Processed") & " of " & cnt("Total") End If
See how easy that code is to read?
Use the Debugger
I see many messages where the poster is getting an error message, or an unexpected result (or no result at all). Sometimes a large chunk of code is posted, but no indicator where the error happens.
It seems like very few (at least of the obviously less experienced programmers) use the debugger at all. In most cases they would quickly find the problem that way, instead of asking why they get “object variable not set” or “type mismatch” errors somewhere in 100 lines of code”…”
Yes, the debugger has limitations, and it could use some new features (like breaking when a particular variable has a specified value or match an expression), but it is a huge help even in the current form.
Understand Data Types
Many problems are because the programmer did not understand what data type different functions returns, or even (in some cases) what the different data types means. One poster (I can´t find the post right now) had code like this:
Dim x As Integer x = 0 x = x + 3.5 MsgBox x
He was the surprised that the message box displayed the value 4… I think understanding data types is a requirement of being a programmer, even if the language you work with is forgiving or don´t require variables to be declared.
Analyze the problem
Another common issue I see is that it seems like the programmer just got an assignment and started to write code, without thinking through what the actual process is going to be. He/she often write him/herself into a corner, or is so focused on solving it with existing knowledge (e.g. “has to be @Formula language”), that the difficulty level of the task approaches impossible. Or the code will be extremely convoluted.
Think through the problem, break it down into small problems/steps. Break each of those down into even smaller steps, etc. Finally you have a good specification, and often even pseudo code. It m
ay be that the user requesting the program/functionality (a.k.a. stakeholder) is saying how he want it to be done, but that is really not the stakeholders responsibility. He/she should just explain what the end result should be, and the developer will design the best solution.
I have examples where a manager comes to me and asks for a report “in Excel” of data in a Notes database. That is because the manager in this case was used to working in Excel, and thought of how Excel displays data as the way he wanted it.
I could very easily create a report directly in Notes, displaying exactly the same information. Since I asked what the end result was supposed to be, and how the data was supposed to be used (and by whom), I could avoid Excel altogether and built a pure Notes solution.
This is where experience comes in, things like that is not something you can just pick up at college/university. If you don´t have the analytical/problem solving skills, you will struggle as a programmer. You might be able to write code under strict guidance, or you might even be able to eventually complete the assignment, but it will most probably not be the best/fastest solution, even if the code will work.
Two good blog entries are Separating Programming Sheep from No-Programming Goats (CodingHorror, July 2006) and Why Can´t Programmers.. Program? (CodingHorror, February 2007). Programming consists of problem solving and analytical skills, fundamental skills (like data types, how functions works, recursion different kind of branching/looping), as well as understanding the language and platform you use. If you are missing any of those things, you will probably not be a very good programmer.