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