2015年9月16日 星期三

[AP] Classes in LotusScript sample



Using Custom Classes in LotusScript - Part 1
Using Custom Classes in LotusScript - Part 2

Using Custom Classes in LotusScript - Part 1
Classes are used in LotusScript to work with the core Notes objects like NotesDocument and NotesDatabase. These classes are used to represent an object in Notes like a document or a database. Programmers use properties and methods to set and retrieve information about these objects. Programmers can create their own classes to represent an object. These custom classes can then be used across the application to save programming time and reduce code maintenance.

This tip is for advanced LotusScript programmers who are already familiar with subroutines and functions. See the list of TLCC courses at the start of this tip if you want to learn more about TLCC's LotusScript courses. TLCC also offers a free demonstration version of our beginner LotusScript course.

If you are a LotusScript programmer than you already have used the supplied classes that are in Notes. The NotesDocument class is an example of a class. The NotesDocument class is used to represent a particular Notes document. The line below assigns the first document from a Notes View to the object called doc:
Dim doc as NotesDocument
Set doc = MyView.GetFirstDocument

The doc object is now "instanstiated", meaning it points to an area in memory that contains information about this actual Notes document. The following example shows how to retrieve a document property:
MsgBox doc.LastModified


This object also has methods which are used to take an action. Below is one example used to save the object (the document) to the Notes database:
doc.Save(false, false )

Working with the Notes classes should be very familiar to you. Suppose you want to create your own object to represent your data?

Demonstration
Demonstration Database

The attached Database has a demonstration of the code in this tip.
  1. Detach the following Notes database to your Notes Data directory.CustClass.nsf
  2. Open this database using File | Database | Open.
  3. The demos are all agents. Using the Notes client go to the Actions menu to run the agents.
  4. The code can be viewed using the Domino Designer client.



 Creating a Custom Class

Let's assume our data is used to represent a person (it could be an employee, customer or vendor.) There are certain items about that person we want to represent:
    • Name
    • Address
    • City
    • State
    • Phone
The first step is to define the custom class. This is done with the Class statement. Classes are defined in the Declarations section of the LotusScript code. The Public keyword in front of the variables means that this variable can be accessed as a property (using the dot notation.)

Class Person
  Public firstname As String
  Public lastname As String
  Public Address As String
  Public City As String
  Public State As String
  Public Phone As String
End Class
    The class is used by declaring a object reference variable with the New keyword:

    Dim John As New Person

    Once defined the properties can be assigned and accessed. Below is the complete code:

    1.Sub Initialize
    2.  Dim cr As String
    3.  cr =  Chr(13)
    4.  Dim John As New Person
    5.  John.firstname = "John"
    6.  John.lastname = "Smith"
    7.  John.address = "Main Street"
    8.  John.city = "Miami"
    9.  John.state = "FL"
    10.  John.phone = "555-1212"
    11.  Msgbox "The information about John is:" + cr + John.firstname  + " " + John.lastname
        + cr + John.address + cr + John.city +", " +John.state +"   " + John.phone
    12.End Sub

    This code is demonstrated in the sample database as the agent "Basic Class".




     Working With Custom Classes

    Before diving deeper into the custom classes, let's explore what exactly is an object. The object created above is an area in memory that holds the data about this object, John, in this case. Many objects can be created using the same Person class. Objects can be assigned to another object reference variable. However, the assigned objects all point to the same area in memory. If an object's properties are changed than any other object pointing to the same memory location will also change. Objects are assigned to other objects (of the same class) by using the assignment operator (equals sign.)

    The code example below creates a John object like before. It then assigns John to Harry (which is the same Person class.) The code than changes a property for Harry. This also changes John's property as well. Objects can be assigned to other object reference variables and also stored in arrays.
    1.Sub Initialize
    2.  Dim cr As String
    3.  cr =  Chr(13)
    4.  Dim John As New Person
    5.  John.firstname = "John"
    6.  John.lastname = "Smith"
    7.  John.address = "Main Street"
    8.  John.city = "Miami"
    9.  John.state = "FL"
    10.  John.phone = "555-1212"
    11.Msgbox "The information about John is:" + cr + John.firstname  + " " + John.lastname   + cr + John.address + cr + John.city +", " +John.state +"   " + John.phone
    12.  Dim Harry As Person
    13.  Set Harry = John
    14.Msgbox "The information about Harry is:" + cr + harry.firstname  + " " + harry.lastname + cr + harry.address + cr + harry.city +", " +harry.state +"   " + harry.phone
    15.  Harry.firstname = "Harry"
    16.  Harry.lastname = "Jones"
    17.Msgbox "The information about Harry is:" + cr + harry.firstname  + " " + harry.lastname + cr + harry.address + cr + harry.city +", " +harry.state +"   " + harry.phone
    18.Msgbox "The information about John is:" + cr + John.firstname  + " " + John.lastname + cr + John.address + cr + John.city +", " +John.state +"   " + John.phone
    19.End Sub

    This code is demonstrated in the sample database as the agent "Assigning Objects".

    Variables that reference an object can be set to "nothing" so that they no longer point at data in memory. The line below sets John to nothing. Nothing is a keyword that can be used to delete the variable's reference. Any other variables that point to the same place in memory will still be valid. When there is no longer any object reference variables pointing to the data in memory than LotusScript will automatically release that memory (cleanup.)
    Set John = Nothing

    When John is now accessed an error will occur:

          
    To prevent this error you can test the object reference variable to determine if it is pointing to an actual object using the "Is" operator as follows:
    If John Is Nothing Then
      Msgbox "John does not point to anything."
    Else
      Msgbox "John's name is:" + cr + John.firstname  + " " + John.lastname
    End If

    This code is demonstrated in the sample database as the agent "Deleting Objects".

    Objects can also be deleted from memory by using the Delete keyword.
    Delete John

    This will cause the object to be removed from memory and all other objects that point to this object will now be "nothing."

    Using Custom Classes in LotusScript - Part 2
    Derived classes are custom classes whose definition is partly inherited from another class (the base class.) The derived class uses all the same properties and methods in the base class but can be extended to add new functionality. This tip is the second part of a two part tip on custom classes. To read part 1 click the following link:

    Click here to read Part 1 of this tip

    This tip is for advanced LotusScript programmers who are already familiar with subroutines and functions. See the list of TLCC courses at the start of this tip if you want to learn more about TLCC's LotusScript courses. TLCC also offers a free demonstration version of our Beginner LotusScript course.

    Demonstration
    Demonstration Database

    The attached Database has a demonstration of the code in this tip.
    1. Detach the following Notes database to your Notes Data directory.CustClas2.nsf
    2. Open this database using File | Database | Open.
    3. The demos are all agents. Using the Notes client go to the Actions menu to run the agents.
    4. The code can be viewed using the Domino Designer client.



     Using Derived Custom Classes

    Derived classes are simply a class that "extends" another class. All of the "base" class properties and methods are available to the derived class. Derived classes can be used to create a new class that uses the definition of the base class and adds more properties and methods unique to the derived class. In the last tip we used the Person class below as part of the code samples.
    1.Class Person
    2.Public firstname As String
    3.Public lastname As String
    4.Public address As String
    5.Public city As String
    6.Public state As String
    7.Public phone As String
    8.Public fullname As String
    9.age As Integer
    10.Sub New(fname As String, lname As String, address As String, city As String, state As String, phone As String)
    11.firstname = fname
    12.lastname = lname
    13.Me.address = address
    14.Me.city = city
    15.Me.state = state
    16.Me.phone = phone
    17.fullname = fname + " " + lname
    18.End Sub
    19.Sub setAge(a As Integer)
    20.age = a
    21.End Sub
    22.Function getAge() As Integer
    23.getAge = age
    24.End Function
    25.Function addToAge(i As Integer) As Integer
    26.age = age + i
    27.addToAge = age
    28.End Function
    29.End Class
      The Person class can be extended to create specialized classes for employees, customers, and/or suppliers. These extensions are "derived" classes. The Person class would be considered the base class. A simple derived class is shown below. This code was added to the Declarations section in addition to the Person class above. Note how there is one new public property for EmpNo (line 3) and one private property for salary (line 2.) There are also two methods, getSalary and setSalary. In addition, all the properties and methods of the Person class are available.
      1.Class Employee As Person
      2.salary As Double
      3.Public EmpNo As Single
      4.Sub new(fname As String, lname As String, address As String, city As String, state As String, phone As String)
      5.End Sub
      6.Sub setSalary( s As Double)
      7.salary = s
      8.End Sub
      9.Function getSalary() As Double
      10.getSalary = salary
      11.End Function
      12.End Class
        The code below uses this new derived class to create an Employee object:
        1.Sub Initialize
        2.Dim cr As String
        3.cr =  Chr(13)
        4.Dim John As New Employee("John","Smith","Main St.","Denver", "CO", "555-1212")
        5.John.setSalary(45000)
        6.Msgbox John.fullname & "'s salary is " & Format(John.getSalary(),"Currency") & "."
        7.End Sub
          This code is demonstrated in the sample database as the agent "Employee Class".


           Using New in Custom Classes

          In the example above, the New subroutine is empty of code statements. The New subroutine of the base (Person) class is called and all the parameters of the New subroutine are supplied to the New in the base class (remember, the code in the New subroutine executes when the object is first created) are passed to the Base class.) In the example above there is no need to have any extra code when the Employee class is created. However, suppose the New subroutine in the derived class has to perform additional processing when an object is created? Extra parameters can be added to the New subroutine in the derived class. Code can then be added to the New subroutine which is executed in addition to the code in the Base class. Whenever the arguments in the New subroutine of the derived class do not match up with the base class then the syntax of New is slightly different. The New subroutine in the derived class has to list the actual argument names that are passed into the base class. Below is the syntax from Lotus Designer Help:

          Sub New [ ( [ argList ] ) ] [ baseClass ( [ baseArgList ] ) ]
          statements ]
          End Sub

          baseClass ( [ baseArgList ] )
          Optional. The baseClass is the name of the class from which the derived class is derived. This name must match the baseClass name in the Class statement for the derived class.
          The baseArgList is a comma-separated list of arguments for the sub New of the base class. Note that these are actual arguments, not parameter declarations. This syntax enables a call of the New sub for the derived class to furnish actual arguments to the call of the New sub for the base class.
          Suppose in our example above we want to add an additional parameter when creating a new Employee to set the EmpNo. The class definition is shown below. Note on line 4 the arguments for New are not the same as the Person class (listed above.) There is an extra parameter for empno. Since the arguments no longer match up with the base class than the aruguments have to be listed in baseArgList. Note that these are not definitions but are the actual parameter names. Line 5 sets the EmpNo property which was passed into New.
          1.Class Employee As Person
          2.salary As Double
          3.Public EmpNo As Single
          4.Sub new(fname As String, lname As String, address As String, city As String, state As String, phone As String, empno As Integer) , Person(fname, lname, address, city, state, phone)
          5.Me.EmpNo = empno
          6.End Sub
          7.Sub setSalary( s As Double)
          8.salary = s
          9.End Sub
          10.Function getSalary() As Double
          11.getSalary = salary
          12.End Function
            Sample code to use this new Employee class is shown below.
            1.Sub Initialize
            2.Dim cr As String
            3.cr =  Chr(13)
            4.Dim John As New Employee("John","Smith","Main St.","Denver", "CO", "555-1212", 32)
            5.Msgbox John.fullname & "'s employee number is " & John.EmpNo & "."
            6.End Sub
            This code is demonstrated in the "Extending New" agent in the demonstration database.



             The With Statement
            A useful statement to use with custom classes (including the Domino Object Model) is the With statement. The With statement can be used to reference the properties and methods of an object without having to list the name of an object. In the example below the With statement on line 6 uses the object reference variable for John. In the With statement whenever a dot is used in front of a property or method it assumes the object to be referenced is John.
            1.Sub Initialize
            2.Dim cr As String
            3.cr =  Chr(13)
            4.Dim John As New Employee("John","Smith","Main St.","Denver", "CO", "555-1212", 32)
            5.Dim fullname As String
            6.With John
            7..setSalary(67000)
            8.fullname = .fullname
            9.Msgbox fullname & "'s employee number is " & .EmpNo & "."
            10.Msgbox .firstname & "'s salary is " & .getSalary & "."
            11.End With
            12.End Sub
              The With statement can be nested up to 16 levels.
              This code is demonstrated with the "With Statement" agent in the Demonstration database.
              The With Statement can also be very useful when dealing with the Notes Domino Objects as shown in the following code. It is used on line 17 to provide a shortcut for the reference to "Doc".
              1.Sub Initialize
              2.Dim session As New NotesSession
              3.Dim dbCur As NotesDatabase
              4.Set dbCur = session.CurrentDatabase
              5.Dim collUnprocessed As NotesDocumentCollection
              6.Set collUnprocessed = dbCur.UnprocessedDocuments
              7.Dim doc As NotesDocument
              8.'Set up arrays to hold part name and price
              9.Dim arrNames() As String
              10.Dim arrPrices() As Double
              11.Redim arrNames(0 To collUnprocessed.Count-1)
              12.Redim arrPrices(0 To collUnprocessed.Count-1)
              13.Dim i As Integer
              14.i=0
              15.Set doc = collUnprocessed.getfirstdocument
              16.Do Until Doc Is Nothing
              17.With Doc
              18.'There is no need to reference Doc, just use the dot notation by itself
              19.arrNames(i) = .partname(0)
              20.arrPrices(i) = .partprice (0)
              21.End With
              22.i=i+1
              23.Set Doc = collUnprocessed.GetNextDocument(doc)
              24.Loop
              25.'Do some further processing with the arrays....
              26.End Sub


                沒有留言:

                張貼留言