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.

    mbo

  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'")

    mbo

  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:

woSet.reset()

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.

Related posts

20 comments

  • User1971

    For what it’s worth, there are similar functions for Formulas and MBR too:
    SETQBE(): set qbe to a mboset variable (varname, attrname, qbeexp)
    SETWHERE(): set where clause to a mboset using a condition (varname, condname)

  • K Kunnuthara

    Hi Alex,

    I have the below code, however it breaks when setWhere() is closed obviously because no data exists in the DB for that query.
    Is there a way by which I can avoid the code breaking here?

    lSupSet = MXServer.getMXServer().getMboSet(“GSUPPORT”,MXServer.getMXServer().getSystemUserInfo())
    lSupSet.setWhere(“PMI='” + str(pmi) + “‘ order by GSUPPORTID DESC”)

    I am calling this from User exit after External Exit on an enterprise service response.

    Thanks in advance.

  • 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.

    • A
      Alex Walter

      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).

  • Ricardo

    there is a way to obtain the name of the jvm where the script is running?

    • A
      Alex Walter

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

  • Harshavardhan Kamepalli

    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

    offstartdate=mbo.getDate(“OFFSTARTDATE”)
    offbooking=mbo.getMboSet(‘BOOKINGSCRIPT’)
    cal=Calendar.getInstance()
    datetime=cal.getTime()

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

  • Venkatprasad

    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.

  • 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?

  • Anwar Indris

    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.

  • Zafar Alam

    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.

  • Diana Campos

    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

    • Alex Walter

      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")

  • It worked, Alex. Thanks so much!! If you ever have a question on BIRT, let me know. I can help you there…

  • 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.

  • Thanks Alex, I’ll give it a go.

  • Mark Fresa

    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.

    • Alex Walter

      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.

      • Mark Fresa

        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.

        • Alex Walter

          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")

Michael Woline

Technology Project Manager (PMP 2009-18) with 15 plus years’ experience building, migrating, and upgrading enterprise applications including Maximo and Peoplesoft. Industries include banking, insurance, and publishing. Career began as a developer writing code and SQL because solving puzzles and figuring out how things works is fun. For fun I used to kite board on the beach, and have resumed cycling with a goal of riding some of the routes of the Giro d'Italia and Tour De France.

Nick Bonfiglio

Hi, I'm Nick! I am relatively new to Maximo, but I've been working in the software and IT space for a good stretch of my career. Most of that time I’ve spent as a QA Engineer at a SaaS company, so I'm no stranger to the technical side of things. Outside of work, I spend most of my time with family. I enjoy cooking and trying out new recipes whenever I get the chance, most of all I love cooking on a good grill! Living in Florida, I take full advantage of the beach as much as I can. I like to keep things pretty simple just good food, family, and some sun!

Akilah

Hi, I’m Akilah! I work with Maximo and come from a background in Computer Engineering, where I picked experience with SQL, Python, and general IT troubleshooting (aka figuring out why things break and how to fix them). I also served as a communications lead during my senior capstone, which helped me get comfortable collaborating with teams and keeping things moving.

Chad

Chad started his CMMS and EAM solutions consulting career in the late 20th century. The past twenty-three years have primarily been focused on supporting Maximo in Life Sciences, Oil & Gas, Government facilities, and Manufacturing verticals. Chad especially enjoys discussions regarding logistics, inventory management, and process improvement. In his free time, he enjoys hunting, fishing, playing guitar, maintaining his small farm, and spending time with his family.

Mike

Mike is a jack-of-all-trades IT professional with 20+ years in manufacturing, starting as a Help Desk temp and working his way through admin, engineering, management, and architect roles. He loves solving problems and building tools to make work easier—Maximo gives him plenty of chances to do both. In his free time, Mike enjoys woodworking, the outdoors, playing synths and hand drums, reading, and learning. Given his druthers (whatever those are), he'd build a timber-framed cabin on 40+ acres of mixed hardwood forest for his future grandkids to work for free play in.

Shane

Maximo Analyst

With a background in Computer Science and Cybersecurity and a CompTIA Security+ certification, I bring both a technical foundation and a curiosity-driven mindset to everything I do. Since joining the industry, I’ve gained hands-on experience with IBM Maximo, including scripting, BIRT reporting, Maximo customization, configuration, and supporting long-term client projects. I've also attained my MAS8 certification. I’ve had the opportunity to work closely with clients, troubleshoot complex issues, and contribute to impactful system enhancements—all while continuously learning and growing in the field. I approach challenges with determination, thrive in collaborative environments, and enjoy finding creative solutions. Outside of work, I recharge by spending time with family and friends, playing video games, staying active, and experimenting in the kitchen.

Maximo Application Suite

Accelerated Time to Value
Lower Total Cost of Ownership
Scalable, Integrated Platform
Continuous Innovation & Updates

Visual Inspection

Accelerate Defect Detection
Flexibility to Train and Deploy
Increase Uptime 24/7 Real Time Monitoring
Better Worker Safety

Monitor

Enterprise Level Data Aggregation
Scaled Operations
AI Deductions
Advanced Root Cause Analysis

Predict

Condition Based Maintenance
Lower Costs
Better Asset Availability
Reduced Risk

Manage

Comprehensive View of Assets
Understand Resource Attributes, Configuration and Relationships
Drill Down View

Health

Improve Reliability
Performance Insight
Better Planning
Clean Data
Optimization – Data, Costs, Risks

Mobility

Boost Productivity
Safer Workplace
Reduce Knowledge Gaps
Avoid Downtime

Maximo Assist

AI-Powered Troubleshooting & Guidance
Faster Issue Resolution in the Field
Knowledge Capture & Reuse Across Teams
Smarter Decisions with Contextual Insights

Dexter

Maximo Analyst

Dexter began his career in the warehouse field. Developing his skills in inventory control, accounts payable, shipping, and receiving, and procurement. While working at Apex he was learning the Maximo system in and out. Eventually learning it so well he taught everyone how to use it. Eventually becoming a system administrator for the Apex site.

A fun fact about Dexter is that he was an Elvis impersonator for 24 years. He enjoys singing, fishing, golf, and playing pool. He's an avid movie buff, most likely you'll find him watching the latest movie.

Chip

Client Relations Specialist

Chip is new to Maximo but has worked for various software companies through his career in both a sales and client relations role. In his spare time, Chip likes to golf, travel and work on projects around the house, especially those with an artistic touch. He is also up for any type of competition whether that be playing cards, board games or recreational sports.

Sarah

Maximo Analyst

Sarah is a recent graduate starting her asset management career. She counts fast learning and determination as key skills that she’s applying to become an Maximo pro! Sarah’s background in IT Services and studies in computer science have strengthened her natural problem-solving skills and desire to help others through technology. In her free time, Sarah enjoys baking, sewing, reading comic books, and building her own video game.

Vishal

Maximo Analyst

Hey there! I’m a Maximo Developer with hands-on experience working across IBM Maximo 7.5.x, 7.6.x, MAS 8, and MAS 9. My focus is mainly on database administration, system integrations, automation scripting, UI customizations, and Maximo admin tasks like BIRT reporting and migration management. I’ve also dabbled in integration work and enjoy finding smart, efficient solutions to everyday challenges in Maximo.

When I’m not working, you’ll probably find me gaming on my PS5 over the weekend or exploring the latest tech trends to keep myself up to speed.

Xavier Galarza

Maximo Analyst

I'm a motivated and curious professional with hands-on experience across multiple Maximo projects, including leading several initiatives. My goal is to continue deepening my expertise in Maximo so I can guide others in unlocking its full potential. I am also fully certified in MAS8. With a strong background in development and a natural problem-solving mindset, I enjoy tackling challenges and learning from those around me. I'm passionate about continuous improvement—both technically and personally—and thrive when I'm surrounded by talented, knowledgeable peers. Outside of work, I enjoy playing video games, watching sports, and staying active with pickleball.

Courtney LeBlanc

Business Analyst

Courtney is a polished Maximo consultant with over 10 years working in the industry. She has worn many hats including QA Specialist, Trainer, Functional Lead, Project Lead and Business Analyst. A point of great professional pride for Courtney is helping clients meet their needs and realize the power of their investment. Being a part of the process that helps clients learn how to use their system and get the most out of it is a great feeling at the end of the day.

Bob Richardson

VP of Products (Ninja)

Bob leads A3J Group’s operational services and heads up our Maximo Ninja product line. With over 50 successful Maximo projects under his belt and MAS 8 certifications in both functional and technical tracks, Bob brings deep experience and steady leadership to every engagement. He has played a key role in the development of many of A3J Group’s most advanced solutions.
Outside of work, Bob enjoys traveling with his wife, spending time outdoors, and occasionally pondering life’s mysteries from his garage—possibly while thinking about squirrels.

Kelly Nimmo

VP of Products (MxMobile)

Kelly Nimmo leads A3J Group’s product development and serves as a senior analyst and consultant with over 14 years of IBM Maximo experience. She is a co-architect and lead developer of MxMobile, our flagship mobile solution, and holds MAS 8 certifications in both functional and technical disciplines. Known for blending technical depth with practical insight, Kelly plays a key role in designing and delivering innovative Maximo-based tools. Outside of work, she enjoys fishing the Florida waters and teaching soccer skills—like the “around the world”—to her nieces and nephews.

Kim Walter

COO

Kim began her career in Investment Banking in the Biotech and Tech sectors. After leaving banking, she focused on executive strategic development evolving her business building skills. Co-founding A3J Group was a natural fit with the idea of creating a fierce ninja style unit that outperforms all others. In her free time, she is training for her next eventing competition or studying to become a Master of Wine or practicing her tornado kick. She could be with her family hiking or surfing or cooking. But she’s definitely not sitting around doing nothing.

Alex Walter

CIO

Alex brings 18 years of Maximo/EAM consulting experience in Life Sciences, Oil & Gas, Water/Waste Management, Government facilities, and much more. He has been awarded the honor of IBM Champion from 2018-2021, and is the brainchild behind our revolutionary mobile solution MxMobile.

In his free time he buys camping gear, enjoys a good circular saw and spends time with his family hiking, surfing and being outdoors.

Enhancement

• Configuration
• Integration & data loading
• Report improvement
• Screen view & workflow changes

Sustainability

• Report
• Troubleshoot
• Learn
• Teach
• Lead

Change Management

• Advanced systematic improvements
• Tailored procedure implementation
• Script-, report-, and application-level source and document control through Git repository software
• Training on how to document and deploy changes

Monitoring

• Active monitoring of your IBM Maximo system’s heartbeat
• Triggered notifications and support tickets when Maximo is not responding
• Automated Escalations based on the health of various critical background processes.
• Periodic and quarterly scheduled system health checks

System Support & Trouble Shooting

•On Demand Support
•Advanced Troubleshooting
•Access to A3J Group’s Maximo Support Environment to submit trouble tickets
•Directly report bugs, request fixes and enhancements

System Patching & Environment Refreshes

• Tentative, bi-annual feature pack releases from IBM
• Minor patches (defined by the last number in the version model)
,• Quarterly lower environment refreshes

Admin

MxAsk

Create new self-service requests in a wizard-style format, and view the details of their open service requests.

MxApprove

Accept, reject, and reassign assignments, review assigned records, and view your workflow inbox.

MxMobile

A suite of mobile applications designed to integrate with IBM Maximo Asset Management. These apps modernize workflow, expedite inventory processes, reduce time spent on data entry, and more.

Workflow

MxMeter

View and enter meter readings, view trends in graphical format, and create readings while in offline mode.

MxAsset

Scan barcodes and view maintenance facts. Create meter readings, work orders or service requests. Toggle asset downtime.

MxWork

Create new work orders on the go, view existing work orders and attachments, and capture fingertip electronic signatures.
0