• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 241
  • Last Modified:

Lotus script design question

I'd like to get some feedback on my design issue.  My code goes through the docs in a view. Each doc has the name of a piece of software, the cost and the users who have it. I take each user's name, looks up their user record and gets their group and unit number, etc. I take this and create/update a different doc, which I pull into a set of views totaling the data by unit, or group, etc.

To do this I build an array with the group and user name. (example: accounting - John Smith). I sort the array, so now it's in group order. Then I carefully traverse down the list, parse out the group name and create a group record and update it with the users criteria. Always checking for a change in the group name.

This works, but it feels like such a clumsy solution.  Have any of you written a similar app? I'd appreciate any feedback on the approach.
0
BillTr
Asked:
BillTr
  • 5
  • 5
  • 2
2 Solutions
 
Sjef BosmanGroupware ConsultantCommented:
Have you ever used Lists in LotusScript? It is a kind of referential array. An example:

Dim DeptUsers List As String

DeptUsers("Accounting")= "John Smith"

If IsElement(Users("HR")) Then
      ...
Else
      ...
End If
Forall d In DeptUsers
      Print ListTag(d)
End Forall

Without your code it's hard guessing what it looks like. Maybe the List is what you're missing. Look it up in the Designer Help database, start with words like ListTag and IsElement in the Index.

I think that composite list types are also allowed, even your own classes.
0
 
mbonaciCommented:
I would suggest you to read about object oriented programming in Designer help:
http://www-12.lotus.com/ldd/doc/domino_notes/6.5.1/help65_designer.nsf/b3266a3c17f9bb7085256b870069c0a9/6eddea077c945e8f85256e00004a02ee?OpenDocument

Arrays and lists of classes:
http://www-12.lotus.com/ldd/doc/domino_notes/6.5.1/help65_designer.nsf/b3266a3c17f9bb7085256b870069c0a9/dd071f4703e6c31385256e00004a063d?OpenDocument


That way you get scalable code which is easy to modify, maintain or maybe one day transfered to Java or other full object language (read about encapsulation)...


E.g. you should have object like this:
Class software
	Private name As String
	Private cost As Long
	Private users List As String
 
	'you init software like this Dim s As New Software( doc ), and it all gets assigned to your private members
	Sub New( doc As NotesDocument )
		name = doc.softwareName(0)
		cost = CLng( doc.softwareCost(0) )
 
		Forall user In doc.users
			users( user ) = "1"
		End Forall
	End Sub
	
	'Property Get and Property Set...
 
	'Methods...
 
 
End class

Open in new window

0
 
BillTrAuthor Commented:
I am attaching a file with some examples of what I have. This part of the code takes an array of sorted user names and looks up each users unit data. This is done by stepping through a sorted view of the user docs. I keep track of my position in the view, rather than starting from the top when the name changes. So the sorts are critical.

The code works, but I guessing there's a better approach. Let me know. Thanks!

.ps
I attached the file because the code snippet window is a bit narrow so the text wraps, making it hard to read. Perhaps there's a way around that?
LotusScript.txt
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

 
Sjef BosmanGroupware ConsultantCommented:
Sheesh, that's some code to dive into...

It seems you're doing some sort of iterated lookup on a user's name. Why not a sorted view, first column the user's name, and then a view.GetDocumentByKey(CurName, true) ?? Or is it a standard view you can't fiddle with? It's not the standard Public Address Book, so the design is probably yours.

> TARGETPos=ENTRYPos       ' force us out of the while loop
Replace by
      Exit Do

The code with the strings and the Instr() can maybe be replaced using the List type.

      Dim OldList List As String
      Dim Added List As String

Adding one name to a collection is just
      OldList(CurGroup)= CurGroup

The Instr-test is
      If IsElement(OldList(CurGroup)) Then

Because I made it a List of strings, walking through the list is a peas-a-cake:
      Forall le In OldList

Does this help you?
0
 
mbonaciCommented:
Trust me, try object-oriented approach, as I suggested...
Go doc by doc through the view and for each doc call
Dim s As New Software( doc )

and after that add it to the list of software objects:
softwareList( doc.universalID ) = s


Declare list like this:
Dim softwareList List As Software


It takes little more time when you set it up, but afterwards, when you have to modify something it becomes trivial...
The most important thing is that some other developer can use your class without worrying about implementation and you can change implementation without worrying who uses your class, just method signatures (function name, what receives and what returns) must remain the same...

0
 
BillTrAuthor Commented:
Thanks for the fast response. Sorry it's so messy. Here's some more background.

The view is sorted. I had tried a getbykey, but thought it ran too slow. The array of users represents all the users that are associated with a given piece of software. In some cases it can be a long list and I could be repeating the getbykey 100 times for one set of users. The approach I hacked together, while ugly to look at, only traverses the user view one time for a set of users. It ran in about half the time. Though perhaps there's is trick to speeding up the getbykey? Like do something on the view side to cache the key?

I had originally used lists instead of arrays, but I ran into problems sorting the very large lists; and the sort is critical if I want to use the approach above.  So I starting pulling things into arrays and sorting the array. Then I realized that the item is really an array, so I removed the lists.

I'm looking at your suggestions... Ya know, now that I think about it, I didn't define my lists as list types. I had just dim'd them as strings. I'll look into that.












0
 
Sjef BosmanGroupware ConsultantCommented:
How many users do you have to visit in the view? All of them? Where does the list of users come from? What is in the documents?

If your document contains a multi-value field containing the users who have that software, you could make a categorized view by username!
0
 
BillTrAuthor Commented:
Good questions.

List of users: There is a "Service" Doc that contains the history of a piece of software (or service), the cost, notes on upgrades and the list of users who have the software. This is a delimited text field that is controlled by a Action on the form that reads a "User" Doc that contains data relative to each user. Access is  controlled. Only valid users are pulled in.  My code currently executes from a view of these Service documents.

Users in the view: I don't visit all the users in the view. I drop out after the last user in the array has been read.

We do have catagorized view of the software by username. What we don't have is way of totaling the cost of software by organization, because the users go across dept lines. My code pulls the users from the software, then pulls the org data from each user's record, which is used to populate a new form that is organizes the same data by dept, unit, etc.

0
 
Sjef BosmanGroupware ConsultantCommented:
Too tired to look at this now. Tomorrow's another day.

Just another thought you might ponder over: a @DbLookup is about 10 times faster than a GetDocumentByKey.
0
 
BillTrAuthor Commented:
Having some trouble with the is element. I am using the code in the snippet I just attached. The OLDList contains my first value. I can see it in the debugger, but the if then is not seeing it correctly and drops into the else. Maybe I'm not bracketing it right?
      
Having some trouble with the is element. I am using:
GroupCount = 1	
PREVGROUP = ""		
For i=1 To Ubound(GroupNameAll) 
CURGROUP = GroupNameAll(i)
If CURGROUP <> PREVGROUP Then 
	GroupName(GroupCount) = CURGROUP
	GroupCount = GroupCount + 1 
	PREVGROUP = CURGROUP
	If Iselement(OLDLIST(CURGROUP)) Or Iselement(ADDED(CURGROUP)) Then
' skip if on the old or added list		
	Else 
	'ADDED = ADDED & "; " & CURGROUP
	ADDED(CURGROUP) = CURGROUP
	End If

Open in new window

0
 
Sjef BosmanGroupware ConsultantCommented:
It could be an uppercase/lowercase problem? See the Option Compare statement in your Designer Help database.
0
 
BillTrAuthor Commented:
Sorry to be so slow in closing this.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

  • 5
  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now