I've been receiving a few requests for tips following a posting on the
Outlook-Dev email list, so I thought I might as well write down what I can
and put it up for all to see... here goes.
I wish someone would put this gen up on a website to aid amateurs like me.
It appears a large number of newbies start out into the world of Outlook
automation with this selfsame app...
(Sorry, I'm writing all this from memory and a dekko at the code (the app's
been working fine for months now) so there may be other "gotchas" which I
might've missed... but for a 'free' readymade application, if you can get it
to work with a few minor patches like below, who's to complain?)
====
1. The sample form code checks if the "Subject" field is filled out to
decide whether the form is in Read or Compose mode in the Item_Open()
procedure. This will obviously fail if the user has posted the Help Request
without filling out a subject - something that is not validated on send.
So, instead of:
'If (Item.Subject <> "") Then 'if Subject is filled
I use:
'if Ticket ID is assigned
If (Item.BillingInformation <> "") Then
The form code copies the Ticket ID to the BillingInformation field, which
would be empty if the item has not been sent. I have changed the code
slightly, so that the Ticket ID number is written to the BillingInformation
native field on Item_Send() instead of in the Item_Open() procedure. This
guarantees that you identify the "mode" (Compose or Read) correctly. Of
course, you could use other methods such as checking Item.Size
2. Also, the "Ticket ID", a unique number, is generated by concatenating
numbers derived from the current date/time and the user ID (CurrentUser).
This has a subtle "Y2K" problem: the implied type of Ticket
ID/BillingInformation is number, so if the date number has trailing zeroes,
these are truncated, causing the code to bomb: The assigned help task would
fail on the Send Mail to User option, because the Ticket ID generated by the
script would lose trailing zeroes and thus no longer match up when the
script tries to locate the History item.
The fix is simple; generate the number by concatenating user ID and date
number, rather than the other way around.
The fixed code:
UserName = Application.GetNameSpace("MAPI").CurrentUser
'Trim the user name of spaces
Trimmed = TrimUserName(UserName)
NowID = Now
'Get date as numbers only
MyDate = CreateDateAsNumber(NowID)
'Set the ticket id for this item
'==> Switched the strings around to avoid trailing zeroes:
TicketID = Trimmed & MyDate
Item.UserProperties.Find("TicketID").Value = TicketID
' Placing Ticket ID in Billing information because only a native field
' can be used later by the "Items.find" method
Item.BillingInformation = TicketID
3. Another problem is in the ChangeProblemType() procedure. The code in
this section is commented out in the original form - because it doesn't
work! There are some minor errors; the corrected code is below. I had a
tough time troubleshooting this one: I didn't notice the extraneous "Add"
method tacked on to the original Set Mypage = ... line which totally threw
the code.
Sub ChangeProblemType()
'Modify the code below if you want to populate the "Assigned to"
'field if the "Problem Type" changes (this changes the list of
'technicians with the Problem Type)
Set MyPage = Item.GetInspector.ModifiedFormPages("Ticket")
MyPage.Controls("AssignedTo").Clear
Select Case item.userproperties.find("Problem Type").Value
Case "FirstType"
MyPage.controls("AssignedTo").AddItem("Sriram N A")
MyPage.controls("AssignedTo").AddItem("Other Charlie")
MyPage.controls("AssignedTo").Value = "Sriram N A"
Case "SecondType"
...
Case "ThirdType"
...
Case Else
MyPage.controls("AssignedTo").Value = "Poor Me"
End Select
End Sub
4. In the CreateDateAsNumber(ByVal NowID) procedure:
NowID has earlier been assigned the value of Now, or the current date/time.
The code -
For li = 0 To 16
CharName = Mid(UCase(NowID), li + 1, 1)
AscName = Asc(CharName)
will fail for single digit month numbers, since Len(charname) = 16, so that
the Asc function will choke on a null value. Fix is of course to set the
counter correctly:
For li = 0 To Len(NowID)-1
----
*A couple more caveats:*
- On the (hidden) Message page of the request form, set the default
recipient address to the address of the public folder for the Help Desk
folder (which should be at the same level as the Assigned Help Tasks
folder). In my case, since I could not have the folder address added to the
Global Address List, I used the folder's SMTP address property as the
default value for the recipient. You can determine this value by adding the
folder to your personal address book, then looking at the contact
properties. You could also have the administrator uncheck the "Hide from
Address Book" field in Advanced properties for the Public Folder, in order
to use "Help Desk" as the addressee.
- Fill in a default subject also on this page (You could, for instance,
determine some other useful property of the sender for this field, or just
specify a generic default).
- The technician names that you add to the combo box (using the AddItem
method above) should be readily resolvable without conflicts, since the form
code will fail on assignment if the technician's name cannot be resolved to
a valid recipient. In other words, the names should appear as they do in
the address book. Alternatively, you will need to use the Resolve method to
check beforehand.
- Outlook 98, in my experience, has particularly severe and intractable
problems with the forms cache, so that revisions to your form might not
"take". While it is easy enough to simply delete the frmcache.dat file for
Outlook 97/2000 users, it ain't so straightforward with OL98. There's even
a KB article somewhere on this. To avoid grief, make sure the forms are in
final shape before you deploy. Better still, banish Outlook 98 and deploy
Outlook 2000 across your organisation (it's free!), making sure you install
CDO support.
- Some likely problems and fixes are described at:
http://support.microsoft.com/support/kb/articles/Q187/9/84.ASP
http://support.microsoft.com/support/kb/articles/Q259/6/26.ASP
http://support.microsoft.com/support/kb/articles/Q181/0/57.ASP
- Be careful when you make revisions to the form. For instance, if you are
modifying the form after opening a 'New Help Request' from the PF, the All
Fields page would already contain a number against the Ticket ID property,
which would then get saved if you publish this modified form. Generally,
save a copy of the form definition (.fdm) and the template (.oft). Ensure
version numbers are updated upon revision on the Properties page. When
opening a form for modification, hold down the Shift key, so that code does
not fire.
- You might need to uncomment this portion of the code:
' if this form is sent to somebody's INBOX (instead of the HELP DESK),
' uncomment these
'Set OneFolder =
Item.Application.ActiveExplorer.CurrentFolder.Parent.Parent.Folders("Public
Folders")
'Set TwoFolder = OneFolder.Folders("All Public Folders")
'Set TaskFolder = TwoFolder.Folders("Assigned Help Tasks")
and set TaskFolder appropriately. Beware of one-off forms in this scenario.
- One peculiar behaviour is that the message area does not take focus (get
enabled for typing) upon the first click - the user might need to click once
more before he can begin typing. Another of life's little mysteries.
The people who should place help requests through this mechanism
(conveniently grouped into a distribution list) need "Author" permission on
the Help Desk folder to work. Only the relevant forms are allowed in the
related folders, using the "Only Forms Listed Above" option on the Forms
property tab.
Launcher form:
To make life easier, I have a "Launcher" post form as the default for the
help request folder, with this code:
Function Item_Open()
Set objFolder = Application.ActiveExplorer.CurrentFolder
Set objItem = objFolder.Items.Add("IPM.Note.Help Request")
objItem.Display
Item_Open = False
End Function
I have also created an intranet page where a user can directly launch the
form, or navigate to the Help Desk folder. But that's another story...
For the adventurous, there is (or used to be) a complete web-based Help Desk
application free to download, with all kinds of advanced features. The only
link I could find when I searched just now was:
http://www.microsoft.com/Mind/0697/messaging.htm
but it's gotta be hidden in there somewhere.
Assigned Help Tasks form:
- Uncomment the call to AddFieldsToFolder and the corresponding function
code, when using with a Public Folder.
- Change the line:
set MyPage = item.GetInspector.modifiedformpages.Add("Ticket")
To
set MyPage = item.GetInspector.ModifiedFormPages("Ticket")
The final word:
The app can be extended in various ways, for e.g. to dynamically list the
names of technicians from a distribution list (when assigning),
automatically select technician based on problem type, get various user
details like location, phone etc. to populate the request form automatically
from the relevant address book entries etc. - all easy enough to do, once
you grasp the object model.
All in all, wrestling with the HelpDesk sample application is probably one
of the better ways of familiarising the aspiring Outlook forms developer
with the issues involved in Outlook development.
--
Sriram N A