Microsoft 365 Excel: Multiple Cell Values, Update

Microsoft 365 Excel: Multiple Cells Value, Update

Microsoft 365 Excel: 複数セル値, 更新(個別指定)

Update multiple cells data at the specified position in a sheet.

Auto Step icon
Configs for this Auto Step
conf_OAuth2
C1: OAuth2 Setting *
conf_Url
C2: Target Book URL *
conf_Title
C3: Target Sheet Title *#{EL}
conf_Cell1
C4_1: Target Cell1 *#{EL}
conf_Value1
C5_1: Column Value of Update Cell1#{EL}
conf_Cell2
C4_2: Target Cell2#{EL}
conf_Value2
C5_2: Column Value of Update Cell2#{EL}
conf_Cell3
C4_3: Target Cell3#{EL}
conf_Value3
C5_3: Column Value of Update Cell3#{EL}
conf_Cell4
C4_4 Target Cell4#{EL}
conf_Value4
C5_4: Column Value of Update Cell4#{EL}
conf_Cell5
C4_5: Target Cell5#{EL}
conf_Value5
C5_5: Column Value of Update Cell5#{EL}
conf_Cell6
C4_6: Target Cell6#{EL}
conf_Value6
C5_6: Column Value of Update Cell6#{EL}
conf_Cell7
C4_7: Target Cell7#{EL}
conf_Value7
C5_7: Column Value of Update Cell7#{EL}
conf_Cell8
C4_8: Target Cell8#{EL}
conf_Value8
C5_8: Column Value of Update Cell8#{EL}
Script (click to open)

// OAuth2 config sample at [OAuth 2.0 Setting]
// - Authorization Endpoint URL: https://login.microsoftonline.com/common/oauth2/v2.0/authorize
// - Token Endpoint URL: https://login.microsoftonline.com/common/oauth2/v2.0/token
// - Scope: https://graph.microsoft.com/Files.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/";

main();
function main(){
  //// == Config Retrieving / 工程コンフィグの参照 ==
  const oauth2 = configs.get( "conf_OAuth2" );
  const bookUrl = retrieveBookUrl();
  const sheetName = configs.get( "conf_Title" );
  if(sheetName === "" || sheetName === null){
    throw "Sheet Title is empty.";
  }

/*
  const cell = configs.get( "conf_Cell" );
  let values = [];
  values[0] = configs.get( "conf_Value" ); //1セルのみ
*/

  //// == Calculating / 演算 ==
  // Access to the API 1st(Get Book Info)
  const bookInfo = getFileInfoByUrl( bookUrl, oauth2 );
  const worksheetId = getWorksheetId(bookInfo, sheetName, oauth2);

  // Access to the API 2nd(PATCH)
  //Loop 8 cells
  for (let i = 1; i <= 8; i++ ) {
    const cell = configs.get( "conf_Cell" + i );
    if (cell) {
      let values = [];
      values[0] = configs.get( "conf_Value" + i ); //Only 1 cell
      patchData( bookInfo, worksheetId, cell, values, oauth2);
    }
  }
}

/**
  * Read the book URL from the config, if empty it will throw an error
  * @return {String} Book URL
  */
function retrieveBookUrl() {
  const bookUrlDef = configs.getObject( "conf_Url" );
  let bookUrl;
  if ( bookUrlDef === null ) {
    bookUrl = configs.get( "conf_Url" )
  }else{
    bookUrl = engine.findData( bookUrlDef );
  }
  if ( bookUrl === "" || bookUrl === null){
    throw "Book URL is empty."
  }
  return bookUrl;
}

/**
  * Get the file information (drive ID and file ID) from the folder URL,
  * Return an object (if the URL is empty, an error occurs)
  * @param {String} fileUrl  Folder URL
  * @param {String} oauth2  OAuth2 Settings
  * @return {Object} fileInfo  File information {driveId, fileId}
  */
function getFileInfoByUrl( fileUrl, oauth2 ) {
  let fileInfo;
  if ( fileUrl !== "" && fileUrl !== null ) {
    // division and assignment
    const {
      id,
      parentReference: {
        driveId
      }
    } = getObjBySharingUrl( fileUrl, oauth2 );
    fileInfo = {driveId: `drives/${driveId}`, fileId: id};
  }
  return fileInfo;
}

/**
  * Retrieve OneDrive drive item (file, folder) metadata and return JSON object
  * API Specifications:https://docs.microsoft.com/ja-jp/onedrive/developer/rest-api/api/shares_get?view=odsp-graph-online
  * @param {String} sharingUrl  Shared URL for the file
  * @param {String} oauth2  OAuth2 Settings
  * @return {Object} responseObj  Drive item metadata JSON object
  */
function getObjBySharingUrl( sharingUrl, oauth2 ) {
  if (sharingUrl === "" || sharingUrl === null) {
    throw `Sharing URL is empty.`;
  }

  // encoding sharing URL
  const encodedSharingUrl = encodeSharingUrl(sharingUrl);

  // API Request
  const response = httpClient.begin()
    .authSetting( oauth2 )
    .get( `${GRAPH_URI}shares/${encodedSharingUrl}/driveItem` );

  const responseStr = logAndJudgeError(response, "GET");

  return JSON.parse( responseStr );
}

/**
  * Encode the shared URL into unpadded base64url format
  * @param {String} sharingUrl  Share URL
  * @return {String} encodedSharingUrl  Encoded Share URL
  */
function encodeSharingUrl( sharingUrl ) {
  let encodedSharingUrl = base64.encodeToUrlSafeString( sharingUrl );
  while ( encodedSharingUrl.slice(-1) === '=' ) {
    encodedSharingUrl = encodedSharingUrl.slice(0,-1);
  }
  return `u!${encodedSharingUrl}`;
}

/**
  * Get the ID of a worksheet
  * @param {Object} bookInfo
  * @param {String} bookInfo.driveId  Workbook Drive ID
  * @param {String} bookInfo.fileId  The file ID of the workbook.
  * @param {String} sheetName  Name of the sheet
  * @param {String} oauth2  OAuth2 Settings
  */
function getWorksheetId({driveId, fileId}, sheetName, oauth2) {
    const getWorksheetsUrl = `${GRAPH_URI}${driveId}/items/${fileId}/workbook/worksheets`;
    const response = httpClient.begin()
        .authSetting(oauth2)
        .get(getWorksheetsUrl);

    const responseStr = logAndJudgeError(response, "2nd GET");
    const jsonRes = JSON.parse(responseStr);
    const worksheet = jsonRes.value.find(worksheet => worksheet.name === sheetName);
    if (worksheet === undefined) {
        throw 'Worksheet not found.';
    }
    return worksheet.id;
}

/**
  * Update the data in the specified cell in the specified sheet
  * @param {Object} bookInfo
  * @param {String} bookInfo.driveId  Workbook Drive ID
  * @param {String} bookInfo.fileId  The file ID of the workbook.
  * @param {String} worksheetId  The ID of the sheet
  * @param {String} cell  Cell position to update
  * @param {Array} values  Data to be updated
  * @param {String} oauth2  OAuth2 Settings
  */
function patchData( {driveId, fileId}, worksheetId, cell, values, oauth2 ){
  const patchUri = `${GRAPH_URI}${driveId}/items/${fileId}/workbook/worksheets/${encodeURIComponent(worksheetId)}/range(address='${cell}')/`;
  const requestBody = makeRequestToAdd(values);

  const response = httpClient.begin()
    .authSetting( oauth2 )
    .body( JSON.stringify(requestBody), "application/json" )
    .patch( patchUri );
  
  logAndJudgeError(response, "PATCH");
}

/**
  * Convert the data to be updated into JSON format.
  * @param {Array} values  An array containing data
  * @return {JSON Object} The converted JSON object
  */
function makeRequestToAdd(values){
  let request = {
    values : [[]]
  };

    if(values[0] === "" || values[0] === null){
      request.values[0].push(null);
    } else {
      if(values[0].length > 32767){
        throw "Can't set text over 32,767 character.";
      }
      request.values[0].push(values[0]);
    }

  return request;
}

/**
  * Outputs logs and throws an error when an error occurs.
  * @param {HttpResponseWrapper} response  Response to a request
  * @param {String} requestType In what format did you make the request?("GET" or "POST" or "PATCH")
  * @return {String} responseStr Response String
  */
function logAndJudgeError(response, requestType){
  const responseStr = response.getResponseAsString();
  const status = response.getStatusCode();
  if(status >= 300){
    const accessLog = `---${requestType} request--- ${status}\n${responseStr}\n`;
    engine.log(accessLog);
    throw `Failed in ${requestType} request. status: ${status}`;
  }
  return responseStr;
}

Download

warning Freely modifiable JavaScript (ECMAScript) code. No warranty of any kind.
(Installing Addon Auto-Steps are available only on the Professional edition.)

Notes

Capture

See also

Scroll to Top

Discover more from Questetra Support

Subscribe now to keep reading and get access to the full archive.

Continue reading