
Microsoft Lists: Get List Item
This item gets values of a list item on Microsoft Lists.
Basic Configs
- Step Name
- Note
Configs for this Auto Step
- conf_OAuth2
- C1: OAuth2 Setting *
- conf_SiteUrl
- C2: SharePoint Site URL *
- conf_ListTitle
- C3: List Title *
- conf_ListItemId
- C4: List Item ID *
- conf_ColumnName1
- C-K1: Lists Field Name of Column 1
- conf_ColumnValue1
- C-V1: Data item to save value of Column 1
- conf_ColumnName2
- C-K2: Lists Field Name of Column 2
- conf_ColumnValue2
- C-V2: Data item to save value of Column 2
- conf_ColumnName3
- C-K3: Lists Field Name of Column 3
- conf_ColumnValue3
- C-V3: Data item to save value of Column 3
- conf_ColumnName4
- C-K4: Lists Field Name of Column 4
- conf_ColumnValue4
- C-V4: Data item to save value of Column 4
- conf_ColumnName5
- C-K5: Lists Field Name of Column 5
- conf_ColumnValue5
- C-V5: Data item to save value of Column 5
- conf_ColumnName6
- C-K6: Lists Field Name of Column 6
- conf_ColumnValue6
- C-V6: Data item to save value of Column 6
- conf_ColumnName7
- C-K7: Lists Field Name of Column 7
- conf_ColumnValue7
- C-V7: Data item to save value of Column 7
Notes
- The SharePoint Site URL is the part before
/Listsof the List URL- When the List is in My lists, it looks like
https://{sub-domain}-my.sharepoint.com/personal/{user-identifier}_{domain}_onmicrosoft_com - When the List is in a SharePoint site, it looks like
https://{sub-domain}.sharepoint.com/sites/{site-identifier}
- When the List is in My lists, it looks like
- There are some ways to get field names of the columns :
- When you export CSV with schema of the List, the field names are shown in
Nameproperty of each column’s schema - When you sort the the List by a column on WebUI, the field name of the column is included in the URL in the form of
sortField={fieldName}
- When you export CSV with schema of the List, the field names are shown in
- As to each data type on Questetra BPM Suite, the supported Microsoft Lists column types which can be saved are shown in the following table:
| Data type on Questetra BPM Suite | Supported column types on Microsoft Lists |
|---|---|
| String (multiple lines) | Single line of text, Multiple lines of text, Number, Yes/No, Date and time, Choice, Currency |
| String (single line) | Single line of text, Number, Yes/No, Date and time, Choice (when multiple selections are disabled), Currency |
| Numeric | Number, Currency |
| Select (Radio Button, Select Box, Search Select Box) | Yes/No, Choice (when multiple selections are disabled) * The value of the column will be saved as a choice whose choice ID is identical with it |
| Select (Check Box) | Choice (when multiple selections are enabled) * The values of the column will be saved as choices whose choice IDs are identical with them |
| Date, Datetime | Date and time * The date and time displayed on Microsoft Lists is based on the timezone setting of the SharePoint Site (which is different from the timezone setting of your Microsoft 365 account) * If the timezone setting of the SharePoint Site is different from that of Questetra BPM Suite, there will be a difference in the displayed date and time |
Capture

See Also
Script (click to open)
- An XML file that contains the code below is available to download
- microsoft-lists-listitem-get.xml (C) Questetra, Inc. (MIT License)
- If you are using Professional, you can modify the contents of this file and use it as your own add-on auto step
// OAuth2 config sample at [OAuth 2.0 Setting]
// - Authorization Endpoint URL: https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/authorize
// - Token Endpoint URL: https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
// - Scope: https://graph.microsoft.com/Sites.ReadWrite.All offline_access
// - Consumer Key: (Get by Microsoft Azure Active Directory)
// - Consumer Secret: (Get by Microsoft Azure Active Directory)
const GRAPH_URI = 'https://graph.microsoft.com/v1.0/';
const COLUMN_NUM = 7; // 扱える列の数
const main = () => {
//// == 工程コンフィグの参照 / Config Retrieving ==
const oauth2 = configs.getObject('conf_OAuth2');
const siteUrl = retrieveSiteUrl();
const listTitle = configs.get('conf_ListTitle');
const listItemId = retrieveListItemId();
const {columnNames, columnDefs} = retrieveColumnNamesAndDataDefs();
//// == 演算 / Calculating ==
const siteId = getSiteIdByUrl(oauth2, siteUrl);
checkColumns(oauth2, siteId, listTitle, columnNames, columnDefs);
const listItem = getListItem(oauth2, siteId, listTitle, listItemId, columnNames);
//// == ワークフローデータへの代入 / Data Updating ==
saveData(listItem, columnNames, columnDefs);
};
/**
* 工程コンフィグからサイトの URL を取得する
* @returns {String} サイトの URL
*/
const retrieveSiteUrl = () => {
let siteUrl = configs.get('conf_SiteUrl');
// 末尾にスラッシュがある場合、削除
if (siteUrl.endsWith('/')) {
siteUrl = siteUrl.slice(0, -1);
}
return siteUrl;
};
/**
* 工程コンフィグからリストアイテム ID を取得する
* @returns {String} リストアイテム ID
*/
const retrieveListItemId = () => {
const dataDef = configs.getObject('conf_ListItemId');
if (dataDef.matchDataType('SELECT_SINGLE')) { // 選択型データ項目の場合
const select = engine.findData(dataDef);
if (select === null || select.size() === 0) { // 未選択
throw new Error('List Item ID is not selected.');
}
return select.get(0).getValue();
}
// 文字型データ項目の場合
const value = engine.findData(dataDef);
if (value === null) {
throw new Error('List Item ID is blank.');
}
return value;
};
/**
* 工程コンフィグから列の名前、保存先データ項目を取得する
* 以下の場合はエラー
* - 名前、保存先データ項目の片方だけが指定されている列がある
* - 保存先データ項目がひとつも指定されていない
* - 値を保存するデータ項目が重複して設定されている
* @returns {Object} result
* @returns {Array<String>} result.columnNames 列の名前
* @returns {Array<ProcessDataDefinitionView>} result.columnDefs 列の値の保存先データ項目
*/
const retrieveColumnNamesAndDataDefs = () => {
const columnNames = [];
const columnDefs = [];
const dataItemNumSet = new Set(); // データ項目の重複確認用
for (let i = 0; i < COLUMN_NUM; i++) {
const columnName = configs.get(`conf_ColumnName${i + 1}`);
const columnDef = configs.getObject(`conf_ColumnValue${i + 1}`);
if (columnName === '' && columnDef === null) {
continue;
} else if (columnName !== '' && columnDef !== null) {
const dataItemNum = columnDef.getNumber();
if (dataItemNumSet.has(dataItemNum)) { // データ項目番号が重複していればエラー
throw new Error('The same data item is set multiple times.');
}
dataItemNumSet.add(dataItemNum); // データ項目の重複確認用
columnNames.push(columnName);
columnDefs.push(columnDef);
} else {
throw new Error(`Field name and data item for Column ${i + 1} must be specified at the same time.`);
}
}
if (columnDefs.length === 0) {
throw new Error('No data item to save the result.');
}
return {columnNames, columnDefs};
};
/**
* サイトのメタデータを取得し、siteId を返す
* APIの仕様: https://docs.microsoft.com/ja-jp/onedrive/developer/rest-api/api/shares_get?view=odsp-graph-online
* @param {AuthSettingWrapper} oauth2 OAuth2 設定情報
* @param {String} siteUrl SharePoint サイトの URL
* @returns {String} siteId
*/
const getSiteIdByUrl = (oauth2, siteUrl) => {
// encoding sharing URL
const encodedSharingUrl = encodeSharingUrl(siteUrl);
// preparing for API Request
const response = httpClient.begin()
.authSetting(oauth2)
.queryParam('select', 'id')
.get(`${GRAPH_URI}shares/${encodedSharingUrl}/site`);
const status = response.getStatusCode();
const responseStr = response.getResponseAsString();
if (status !== 200) {
engine.log(responseStr);
throw new Error(`Failed to get site info. status: ${status}`);
}
return JSON.parse(responseStr).id;
};
/**
* 共有URLを unpadded base64url 形式にエンコードする
* @param {String} sharingUrl 共有URL
* @returns {String} encodedSharingUrl エンコードされた共有URL
*/
const encodeSharingUrl = (sharingUrl) => {
let encodedSharingUrl = base64.encodeToUrlSafeString(sharingUrl);
while (encodedSharingUrl.slice(-1) === '=') {
encodedSharingUrl = encodedSharingUrl.slice(0, -1);
}
return `u!${encodedSharingUrl}`;
};
/**
* リストの列のメタデータを取得し、指定した名前の列の存在を確認する
* リストアイテム取得の API では値が空の列はプロパティ自体が返らないため、事前に列の存在を確認しておく
* @param {AuthSettingWrapper} oauth2 OAuth2 設定情報
* @param {String} siteId SharePoint サイトの ID
* @param {String} listTitle リストの名前
* @param {Array<String>} columnNames 列の名前
* @param {Array<ProcessDataDefinitionView>} columnDefs 列の値の保存先データ項目
*/
const checkColumns = (oauth2, siteId, listTitle, columnNames, columnDefs) => {
const url = `${GRAPH_URI}sites/${encodeURIComponent(siteId)}/lists/${encodeURIComponent(listTitle)}/columns`;
const response = httpClient.begin()
.authSetting(oauth2)
.queryParam('$select', 'name')
// $filter, $search, $top パラメータは効かない
.get(url);
const status = response.getStatusCode();
const responseStr = response.getResponseAsString();
if (status !== 200) {
engine.log(responseStr);
throw new Error(`Failed to get columns. status: ${status}`);
}
const columns = JSON.parse(responseStr).value;
columnNames.forEach(columnName => {
const column = columns.find((column) => column.name === columnName);
if (column === undefined) {
throw new Error(`Column '${columnName}' not found.`);
}
});
};
/**
* リストアイテムを取得し、JSONオブジェクトを返す
* @param {AuthSettingWrapper} oauth2 OAuth2 設定情報
* @param {String} siteId SharePoint サイトの ID
* @param {String} listTitle リストの名前
* @param {String} listItemId リストアイテム ID
* @param {Array<String>} columnNames 列の名前
* @returns {Object} 取得したリストアイテム
*/
const getListItem = (oauth2, siteId, listTitle, listItemId, columnNames) => {
const url = `${GRAPH_URI}sites/${encodeURIComponent(siteId)}/lists/${encodeURIComponent(listTitle)}/items/${encodeURIComponent(listItemId)}`;
const response = httpClient.begin()
.authSetting(oauth2)
.queryParam('$select', 'id') // 不要なプロパティを除外するために指定
.queryParam('$expand', `fields($select=${columnNames.join(',')})`)
.get(url);
const status = response.getStatusCode();
const responseStr = response.getResponseAsString();
if (status !== 200) {
engine.log(responseStr);
throw new Error(`Failed to get list item. status: ${status}`);
}
const listItem = JSON.parse(responseStr);
return listItem;
};
/**
* データ項目への保存
* @param {Object} listItem リストアイテム
* @param {Array<String>} columnNames 列の名前
* @param {Array<ProcessDataDefinitionView>} columnDefs 列の値の保存先データ項目
*/
const saveData = (listItem, columnNames, columnDefs) => {
columnNames.forEach((columnName, i) => {
convertAndSetData(columnDefs[i], listItem.fields[columnName], columnName);
});
};
/**
* データ項目の型にしたがってデータを変換し、データ項目に保存する
* 変換できない値の場合はエラーにする
* @param {ProcessDataDefinitionView} dataDef 保存先データ項目
* @param {Object} columnValue 列の値
* @param {String} columnName 列の名前(エラー出力用)
*/
function convertAndSetData(dataDef, columnValue, columnName) {
if (columnValue === undefined || columnValue === null) {
engine.setData(dataDef, null);
return;
}
// データ項目の型ごとに、列の値を変換して保存する
if (dataDef.matchDataType('STRING')) {
try {
// TEXTFIELD に改行を含む文字列を保存しようとした場合のエラーは、QBPMS のバリデーションに任せる
engine.setData(dataDef, stringifyColumnValue(columnValue));
} catch (e) { // 列の値が解釈できないオブジェクトの場合など
throw new Error(`Column '${columnName}' cannot be saved to Text type data item. ${e.message}`);
}
} else if (dataDef.matchDataType('DECIMAL')) {
const supportedValueTypes = ['string', 'number'];
if (!supportedValueTypes.includes(typeof columnValue)) {
throw new Error(`Column '${columnName}' cannot be saved to Numeric type data item. The returned value is neither a string nor a number.`);
}
try {
engine.setData(dataDef, new java.math.BigDecimal(columnValue));
} catch (e) {
throw new Error(`Column '${columnName}' cannot be saved to Numeric type data item. Failed to convert to BigDecimal.`);
}
} else if (dataDef.matchDataType('SELECT')) {
const items = new java.util.ArrayList();
try {
if (Array.isArray(columnValue)) { // 複数選択の場合
convertMultipleValuesToStringArray(columnValue).forEach((value) => {
items.add(value);
});
} else { // 単一選択の場合
items.add(convertSingleValueToString(columnValue));
}
// 一致する選択肢 ID がない場合、SELECT_SINGLE に複数選択を保存しようとした場合のエラーは、QBPMS のバリデーションに任せる
engine.setData(dataDef, items);
} catch (e) {
throw new Error(`Column '${columnName}' cannot be saved to Select type data item. ${e.message}`);
}
} else if (dataDef.matchDataType('DATETIME')) {
if (typeof columnValue !== 'string') {
throw new Error(`Column '${columnName}' cannot be saved to Datetime type data item. The returned value is not a string.`);
}
try {
engine.setData(dataDef, dateFormatter.parse("yyyy-MM-dd'T'HH:mm:ssX", columnValue));
} catch (e) {
throw new Error(`Column '${columnName}' cannot be saved to Datetime type data item. The returned value is not a datetime-format string.`);
}
} else if (dataDef.matchDataType('DATE')) {
if (typeof columnValue !== 'string') {
throw new Error(`Column '${columnName}' cannot be saved to Date type data item. The returned value is not a string.`);
}
try {
const millisec = dateFormatter.parse("yyyy-MM-dd'T'HH:mm:ssX", columnValue).getFirstTimeInDate().getTime();
engine.setData(dataDef, new com.questetra.bpms.util.AddableDate(millisec));
} catch (e) {
throw new Error(`Column '${columnName}' cannot be saved to Date type data item. The returned value is not a datetime-format string.`);
}
}
}
/**
* 列の値を文字列に変換する
* 列の値が配列の場合、改行区切りの文字列に変換する
* 文字列化に失敗した場合はエラー
* @param {Object} columnValue 列の値
* @returns {String} 文字列化した列の値
*/
const stringifyColumnValue = (columnValue) => {
if (Array.isArray(columnValue)) {
return convertMultipleValuesToStringArray(columnValue).join('\n');
}
return convertSingleValueToString(columnValue);
};
/**
* 列の値を、文字列の配列に変換する(値が配列の場合)
* 文字列化に失敗した場合はエラー
* @param {Array} array 列の値
* @returns {Array<String>} 文字列化した列の値
*/
const convertMultipleValuesToStringArray = (array) => {
return array.map(value => {
return convertSingleValueToString(value);
});
};
/**
* 列の値を、文字列に変換する(値が配列でない場合)
* 文字列化に失敗した場合はエラー
* @param {Object} value 列の値
* @returns {String} 文字列化した列の値
*/
const convertSingleValueToString = (value) => {
const supportedPrimitiveTypes = ['string', 'number', 'boolean'];
if (supportedPrimitiveTypes.includes(typeof value)) {
return value.toString();
}
// オブジェクトの場合など、解釈できない場合はエラー
throw new Error('Failed to convert an object to a string.');
};