An OmniPlan project includes the team members, equipment and materials needed to bring the project to fruition. Every person, piece of infrastructure, and raw ingredient that contributes to reaching the project’s goal is counted as a resource.

Creating resources works much like creating tasks. Like tasks, resources can also exist in hierarchical groups.

Instance Properties

Here are the properties of an OmmiPlan resource:

Instance Functions

Here are the functions that can be called on an instance of a Resource.

Resource Types

Here are the various types of OmniPlan resources:

rsc = actual.rootResource.addMember() rsc.type = = "Backhoe" rsc.costPerHour = 275

Resource Assignment Types

The process of adjusting project resources can effect interaction with other project elements. Resource Assignment Types determine the method used in calculating any adjustments.

rsc = actual.resourceNamed("Bob Jones") if(rsc){ task = actual.rootTask.addSubtask() task.addAssignment(rsc) task.resourceAssignmentType = ResourceAssignmentType.adjustAssignedUnits }

Generating a Reference to a Resource

To generate a reference to a specific resource, use the resourceNamed("resourceName") function of the Scenario class. Pass-in the name of the resource to the function called on a scenario (actual or baseline) and the result will be either a reference to the first matching resource, or null — indicating that no matching resource was located:

In the following example, a reference to the specified resource is generated and used to assign the resource to a new task:

rsc = actual.resourceNamed("Margret Jensen") if(rsc){ task = actual.rootTask.addSubtask() task.addAssignment(rsc) }

Here’s a script variation that creates a resource if one doesn’t already exist:

resourceName = "Bob Sykes" rsc = actual.resourceNamed(resourceName) if(!rsc){ rsc = actual.rootResource.addMember() = resourceName }

Import People Data from File

This Omni Automation action plugIn will create new staff resources using the data read from either a chosen TSV (tabbed-delimited) or CSV (comma-separated) file.

Note that the action plugIn incorporates the use of the FilePicker class to enable the user to choose the file to import.

Also note that, for this example plugIn, the exported data has two columns: the staffer’s full name, and the staffer’s email address. (DOWNLOAD EXAMPLE FILES)

/*{ "type": "action", "targets": ["omniplan"], "author": "Otto Automator", "identifier": "com.omni-automation.import-people-from-file", "version": "1.0", "description": "Will create new resources using the person data read from a chosen comma- or tab-delimited file.", "label": "Import People from File", "shortLabel": "Import People" }*/ var _ = function(){ var action = new PlugIn.Action(function(selection, sender){ // action code // selection options: project, tasks, resources // CREATE INSTANCE OF FILEPICKER var picker = new FilePicker() picker.folders = false picker.multiple = false TSVtype = new FileType("") CSVtype = new FileType("public.comma-separated-values-text") picker.types = [TSVtype,CSVtype] // DECLARE THE PROMISE VARIABLE var pickerPromise // CHECK PLATFORM if(app.platformName === "iOS"){ msg = "Tap ”Continue” and choose the comma- or tab-delimited text file to import from the forthcoming file picker:" var alert = new Alert("Select File", msg) alert.addOption("Continue"){ pickerPromise = }) } else if (app.platformName === "macOS"){ picker.message = "Choose the comma- or tab-delimited text file to import:" pickerPromise = } // READ AND PROCESS CONTENTS OF THE CHOSEN TEXT FILE pickerPromise.then(function(urls){ url = urls[0] var typeIndicator = (url.string.endsWith(".tsv")) ? 0:1 url.fetch(function(data){ data = data.toString().split(/\r?\n/) var items = new Array() for(var i = 0; i < data.length; i++){ if(typeIndicator === 0){ items.push(data[i].split(/\t/)) } else { items.push(data[i].split(",")) } } // GET THE CURRENT RESOURCE EMAIL ADDRESSES var resourceEmails = new Array() actual.rootResource.descendents().forEach((rsc)=>{ if (rsc.type === ResourceType.staff &&{ resourceEmails.push( } }) // CREATE NEW RESOURCE FOR EACH UNIQUE ITEM items.forEach((item)=>{ // TRIM ENCASING QUOTES IF SOURCE IS CSV var personName = (typeIndicator === 0) ? item[0]:item[0].replace(/^\"+|\"+$/gm,'') var personEmail = (typeIndicator === 0) ? item[1]:item[1].replace(/^\"+|\"+$/gm,'') // ADD PERSONS WITH UNIQUE EMAIL AS RESOURCES if (!resourceEmails.includes(personEmail)){ newResource = actual.rootResource.addMember() newResource.type = ResourceType.staff = personName = personEmail resourceEmails.push(personEmail) } }) }) }) }); action.validate = function(selection, sender){ // validation code // selection options: project, tasks, resources return true }; return action; }(); _;

 01-10  The action metadata determines which Omni applications are targeted by the action, the action’s Automation menu and toolbar titles, and the version and description of the action.

 11-82  The main function that contains the action code.

 12-73  Create a new instance of the Action class that includes a callback function that receives references to the selection and sender objects as its default parameters.

 17  Create and store an instance of the FilePicker class.

 18-19  Set the properties of the file picker to allow the selection of a single file.

 20-21  Create instances of the FileType class for files that contain either comma-separated-values or tab-separated-values.

 22  Assign the file types of the file picker instance to the created file types.

 24  Declare a variable that will contain the JavaScript promise object that is returned when the file picker is called.

 38-71  Calling the then() function on promise object will enable the processing of the chosen file, whose file URL is passed as an array into the callback function.

 39  The file URL for the chosen file is extracted from the passed URL array (the passed-in array contains a single-item)

 40  A JavaScript ternary statement returns a value of 0 if the file URL ends with “tsv” or 1 if the file URL ends with “csv.”

 41-70  The fetch() function is used to extract the data from the file, and passes the data object into the callback function.

 42  Convert the passed-in data to text and then delimit it by paragraphs or linefeeds into an array of text objects.

 43  Create an empty array to hold the split data objects.

 44-50  Iterate the array of text objects and split each one based upon whether the data of the source file was tab- or comma-delimited. The resulting JavaScript object will contain two text items, and will be appended to the previously created array.

 51-57  To ensure that duplicate resources are not created, generate a list of the existing resource emails, which will be used for comparison before creating a new resource.

 52-69  Use the JavaScript forEach() function to create new resources using the data from each of the retrieved text pairs.

 53-54  If the source data was comma-delimited, strip the encasing quotes from each text string of the object.

 63-68  If the potential email address is not in the list of existing resource emails, then create a new resource set its name and email address.

 67  Append the email address of the created resource to the list of current email addresses.

 75-79  The resulting boolean value of the validation function determines whether the action plugIn appears in the Automation menu.

Resource Groups

A Resource Group is a resource that contains other resources. It is often used to create “teams” assigned to specific tasks.

The following script example creates resource groups for the teams imported from a chosen JSON data file (DOWNLOAD) (example data generated by

[ { "name": "Red Team", "members": [ { "email": "", "phone": "800-604-1071", "name": "Lewes Dell 'Orto", "role": "Food Chemist" }, { "email": "", "phone": "694-301-1238", "name": "Markos Covendon", "role": "Programmer Analyst I" }, { "email": "", "phone": "793-362-0138", "name": "Sylas Wolton", "role": "Developer IV" }, { "email": "", "phone": "215-981-3559", "name": "Shirlene Stockport", "role": "Product Engineer" }, { "email": "", "phone": "373-419-0679", "name": "Biron Gerant", "role": "VP Sales" } ] }, { "name": "Blue Team", "members": [ { "email": "", "phone": "486-110-7943", "name": "Farris Baugham", "role": "Nurse" }, { "email": "", "phone": "511-593-7065", "name": "Sonnnie Bird", "role": "Research Associate" }, { "email": "", "phone": "324-905-1600", "name": "Hill Stangroom", "role": "Marketing Manager" }, { "email": "", "phone": "929-853-7355", "name": "Thebault Chislett", "role": "Editor" }, { "email": "", "phone": "515-924-8322", "name": "Eldredge Durand", "role": "Food Chemist" } ] }, { "name": "Green Team", "members": [ { "email": "", "phone": "862-281-2490", "name": "Clarke Iaduccelli", "role": "Environmental Tech" }, { "email": "", "phone": "355-390-3438", "name": "Angelica Jankiewicz", "role": "Junior Executive" }, { "email": "", "phone": "604-389-5099", "name": "Debee Pack", "role": "Account Executive" }, { "email": "", "phone": "993-456-9106", "name": "Kala Matura", "role": "GIS Technical Architect" }, { "email": "", "phone": "282-371-9596", "name": "Johnette Padrick", "role": "Internal Auditor" } ] }, { "name": "Orange Team", "members": [ { "email": "", "phone": "280-668-5317", "name": "Ephrayim Jouhan", "role": "Chemical Engineer" }, { "email": "", "phone": "299-880-0063", "name": "Hermione Blagbrough", "role": "VP Accounting" }, { "email": "", "phone": "631-123-6111", "name": "Kris VanBrugh", "role": "VP Marketing" }, { "email": "", "phone": "498-262-5636", "name": "Lowrance Dorian", "role": "Account Coordinator" }, { "email": "", "phone": "614-164-0036", "name": "Pearl Mews", "role": "Web Developer IV" } ] } ]
var picker = new FilePicker() picker.folders = false picker.multiple = false picker.types = [FileType.json]{ aURL = urlsArray[0] aURL.fetch(function(data){ resourceData = JSON.parse(data.toString()) resourceData.forEach((team)=>{ rsc = actual.rootResource.addMember() rsc.type = = team["name"] staff = team["members"] staff.forEach((staffer)=>{ teammate = rsc.addMember() teammate.type = ResourceType.staff = staffer["name"] = staffer["email"] teammate.note = staffer["role"] }) }) }) })

 01  Store an new instance of the FilePicker class in the variable: filepicker

 02-04  Set the properties of the file picker to accept a single JSON file as the selection.

 05  Use the show() method to display the file picker interface. The result of this command is a JavaScript promise.

 05-21  Append the then() function to the show() method to process the promise result of the file picker. The then() callback function will receive an array of URLs to the chosen items as its default parameter.

 06  The file URL to the chosen JSON file will be the only item in the passed array of URLs.

 07-20  Call the fetch() function on the file URL to extract its contents and pass the resulting data to the function.

 08  Use the JavaScript toString() function to convert the file data to text, and then call the parse() method of of the JSON class to convert the text into a JSON array of objects (in this case the “teams” of people).

 09-19  Iterate the JSON array of “team” objects.

 10  Create a new resource.

 11  Set the type of the new resource to group.

 12  Set the name of the new resource group to the name of the team.

 13  Extract the array of team member objects from the JSON team object

 14-18  Use the JavaScript forEach() function to process each of the team member JSON objects.

 15  Add a new resource to the group resource.

 16  Set the type of the new resource to be a staff resource.

 17  Assign the name of the new staff resource to the name of the team member.

 18  Assign the email of the new staff resource to the email of the team member.

 19  Assign the note of the new staff resource to the role of the team member.


This webpage is in the process of being developed. Any content may change and may not be accurate or complete at this time.