skip to Main Content

MBOs in Automation Scripts: Working with MboSet Collections

Let’s start with defining some terms. The three biggest terms to define are MboSet, Mbo, and MboValueData. First, the acronym MBO stands for Maximo Business Object. This represents a generic record of data within Maximo. An MBO could be a Work Order, an Asset, an Item, or any of the other hundreds of record types in Maximo.

If we think of a spreadsheet of data, an MboSet would be a tab with columns and many rows of data. The data can be sorted or filtered in many ways. Again, this data could represent any record type in Maximo. An Mbo would be a single row of data represented within an MboSet. Finally, an MboValueData record would be a single cell in the spreadsheet that represents a column of data for a single row.

These terms are used in generic fashion because they have behaviors that can apply to any set of records in Maximo. For example, a set of Work Orders, Assets, Items, etc. can all be filtered, sorted, saved, and looped over in the same fashion. In fact, all record types follow a wide set of general behavior patterns. If you understand these patterns, you’re going to write much better automation scripts in Maximo.

This article will focus on the MboSet collection.

There are three ways to get a handle on an MboSet:

  1. Use the getThisMboSet() method on an Mbo. Most automation scripts will create an implicit variable at runtime of the script called mbo. This represents the record on which the script is operating. To get a handle back to the list that the current record is part of you can use some code that looks like this:
    mboSet = mbo.getThisMboSet()
    This is analogous to going back to the List tab in Maximo.
  2. Use the getMboSet() method on an Mbo. You can either get an MboSet of data related to the current record, as in a one-to-many relationship, or you can get an MboSet of unrelated data to the current record.
    mboSet = mbo.getMboSet("ASSET") or
    mboSet = mbo.getMboSet("$WOAPPR", "WORKORDER", "status = 'APPR' and siteid = 'BEDFORD'")
  3. Use the MXServer.getMXServer.getMboSet() method. If you have an existing Mbo in your code, it’s recommended that you use one of the first two options above. However, there are some automation script launch points that won’t contain the implicit mbo variable (such as Cron Task scripts, some of the Integration scripts, etc.). If that’s the case, then this is your option. You’ll need a userInfo variable defined to make this connection as a given user.
    mboSet = MXServer.getMXServer().getMboSet("WORKORDER", userInfo)

Most objects in the Business Components are collections of objects or the actual objects themselves. When the getMboSet() method is called, a set of objects is returned. When the set is first initialized it has zero members, but it can potentially be filled with all objects that have been saved in the database, depending on which methods are called to restrict the set.

For example, the code:

woSet = mbo.getMboSet("$WOAPPR", "WORKORDER", "status = 'APPR' and siteid = 'BEDFORD'")

returns a collection of WO objects (which represent approved work orders for the BEDFORD site). So far, the set has zero members, but after the following code executes:

wo = woSet.moveFirst()

the set contains all approved work orders in the BEDFORD site (or, more precisely, WO objects representing all approved work orders in the BEDFORD site). The methods moveNext() and moveLast() produce similar results (see below).

Note that the method also returns a remote reference to the object that has become the current member of the collection, in this case the first one. This holds true for the other methods that traverse collections as well (moveNext(), movePrev(), and moveLast()).

A set has a current member pointer that is maintained on the server. The current index of that pointer may be retrieved with the following:

woPos = woSet.getCurrentPosition()

The method returns -1 if there is no current member. Note that the first object in the collection is stored in the zeroth position.

The action of moveFirst() sets the current member pointer to the first position. The moveNext() method produces the identical result: the pointer is advanced one position. In the case of moveLast(), the pointer is set to the last position and all records in the collection are retrieved. This can be very expensive in performance terms and is generally not recommended.

If the current object itself is required, call the following:

wo = woSet.getMbo()

The method returns null if there is no current member. The getMbo() method can also return the object at an arbitrary position in the set; in this case the desired position is passed as an integer argument. The following code returns the first object in the collection.

wo = woSet.getMbo(0)

The current member pointer is important, as there are many methods in the MboSet class which operate on the current object in the set. Examples of these are setValue() and getString(). To change the current member pointer, use methods such as moveNext(), movePrev(), and add().

The contents of the collection can be restricted by using the setWhere() method. For example:

woSet.setWhere("wonum like '1%'")

This restricts the set to having only members whose work order numbers begin with the character “1”. This method must be called when the set is newly initialized, i.e. before any members have been placed in the set. If the set already has members, call the method:


This clears the current contents of the collection and generates a query to the database. Any modifications or additions made to the set are lost if they are not saved before reset() is called. The setWhere() and reset() methods can be called in either order.

When the setWhere() method is used, it must be passed a valid SQL where clause for the database platform the server is connected to.

Here’s an example of looping over an MboSet:

woSet = mbo.getThisMboSet()
wo = woSet.moveFirst()
while wo:
  #Do some things with the work order
  wo = woSet.moveNext()

For a complete description of all methods available, refer to the MboSet JavaDocs on the IBM Asset Management Developer Center.

Our next article will focus on reading single attributes from the current record in an MboSet.

This Post Has 18 Comments

  1. Walter I need your help. I cannot get my automation script to look at the current record. I have a custom object connected via relationship to the COMPANIES object, and want to fire the script on saving the Companies record. The script should insert a record into the new object. If you would like me to post the script please let me know. Thanks for any help.

    1. We haven’t covered this yet in this series, but the basics are:

      relatedSet = mbo.getMboSet("RELATEDCOMPANYSET")
      newMbo = relatedSet.add()
      newMbo.setValue("COMPANY", mbo.getString("COMPANY"))
      newMbo.setValue("OTHERATTRIBUTE", "OTHER VALUE")

      Hope this helps.

      1. Alex, sorry I called you Walter earlier. In my haste I made a mistake. The record is created at the child level and has to look up to the COMPANIES record as the parent. The problem is that even after creating a relationship, the child doesn’t know the parent’s primary key. Thanks for your help.

        1. No worries! I’ve been called worse… 🙂

          Again, something that hasn’t been covered yet but would be useful in your case is the getOwner() method on an Mbo. You can effectively traverse up the tree of related Mbo’s using that method. In your case, it might look like:

          parentMbo = mbo.getOwner()
          if parentMbo:
          mbo.setValue("COMPANY", parentMbo.getString("COMPANY"))
          mbo.setValue("OTHERATTRIBUTE", "OTHERVALUE")

  2. Alex, you are 100% correct. It worked first time. My problem is that I printed out the parentMbo (prior to fetching the COMPANY field) and it was some sort of index number, not the primary key, and it confused me. Thanks so much for your help. If you ever have a BIRT question, let me know. I’m better at BIRT than automation scripts.

  3. I need a script that shows an error message if an asset number that already exists in the asset table is entered.
    I don’t know how to make the comparison of the asset that is entered with the entire table of assets. can you support me

    1. Typically Maximo will throw an error immediately when a user attempts to manually enter an asset number that already exists in the database. However, if you want to test this manually, something like this should work:

      from psdi.mbo import SqlFormat

      whereClause = SqlFormat(mbo, "assetnum = :1 and siteid = :2")
      whereClause.setObject(1, "ASSET", "ASSETNUM", mbo.getString("ASSETNUM"))
      whereClause.setObject(2, "ASSET", "SITEID", mbo.getString("SITEID"))

      assetSet = mbo.getMboSet("$CHECKASSET", "ASSET", whereClause.format())
      if not assetSet.isEmpty():
      service.error("asset", "alreadyExists")

  4. Dear Alex,
    I need a script that check if current user is related with specific security group like MAXADMIN, system flag a checkbox on a field like isMaxadminGroup.
    I don’t know how to make the script. can you support me.

  5. dear Alex.
    thanks four your solution first. next i need your support that i want to know how to get the new record id generated after
    newMbo = relatedSet.add() command run. i am new to maximo environment.

  6. Thank you, Alex. I need your help.
    I’m trying to get a list of the selected items in an autoscript on a button on the main tab.
    I call mbo.getThisMboSet(), and it returns a set with only one item. First of the all selected items.
    I check mboSet.getQbeWhere() and it returns itemid = ‘1092’
    Why it returns the limited mboset and not the full from the List tab?

  7. Can you guys help me with the automation script that validate the location before creating the asset in assettable. Right now we are manually providing the location in the jsonmapping. I am looking for an script when assetcron is running, while creating an asset it should validate if the location exists or not, if exists take that location as reference while creating the asset in asset table. Any help would be appreciated.

  8. Hey Alex,
    I need a “Attribute Launch Point” script to compare date value from Parent table with existing multiple records of date values in the child table.
    Been trying the following script to do so, but it returns sql -104 error code,
    from psdi.server import MXServer
    from psdi.mbo import Mbo
    from java.util import Calendar
    from java.util import Date
    from java.text import SimpleDateFormat


    if(offstartdate <= datetime):
    errorkey = ' Start Date is less than Current Date'
    errorgroup = 'system'
    offbooking.setWhere("STARTDATE is not None")
    while(first is not None):
    if(startdate <= offstartdate <= enddate):
    errorkey = ' Start Date is between previously booked dates'
    errorgroup = 'system'
    print 'offstartdate'

    1. The name of the JVM should be available in the System Property. I believe this can be inspected via the MXServer.getMXServer().getConfig("") call. I haven’t tried this before, so the syntax may not be exactly that. Hope this helps.

  9. Hello Alex, in the first paragraph you state the following:

    An MBO could be a Work Order, an Asset, an Item, or any of the other hundreds of record types in Maximo.

    Is there a list of record types available? I would like to see all the different record types (all the hundreds that you mention). Thanks in advance.

    1. Bob – thanks for the reply. The full list of record types is available in the Database Configuration application in Maximo. Each object in that application is a Maximo Business Object (MBO).

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top
×Close search