Microsoft 365 Excel: テーブル行追加 (項目数可変)

Microsoft 365 Excel: テーブル行追加 (項目数可変)

Microsoft 365 Excel: Table Row Create (Flexible)

Excelのテーブルの末尾に1行追加し、その各セルにデータを入力します。

Auto Step icon
Configs for this Auto Step
conf_OAuth2
C1: OAuth2 設定 *
conf_Url
C2: 入力先のブックの URL *
conf_TableName
C3: 入力先のテーブル名 of テーブルID *#{EL}
conf_Columns
C4: 追加したいカラムのフィールド名(カンマ区切り) *
conf_IndexNum
C5: 追加したインデックス番号の値を保存するデータ項目 (更新)
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 tabelName = configs.get( "conf_TableName" ) + "";
//  const tabelName = encodeURIComponent(configs.get( "conf_TableName" ) + "");
  if(tabelName === "" || tabelName === null){
    throw "Table Name is empty.";
  }

  let values = [];
  retrieveValues( values );

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

  // Access to the API 2nd(POST)
  postData( bookInfo, tabelName, values, oauth2);
}

/**
  * config からブックの URL を読み出す、空ならエラー
  * @return {String} ブックの 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;
}

/**
  * 追加データを準備
  * @param {Array} values  追加データの配列
  */
function retrieveValues( values ) {

  const columns = configs.get( "conf_Columns" ) + "";
  let arrayColumnNames = columns.split(",");
  for ( let i = 0; i < arrayColumnNames.length; i++) {
    let columnName = arrayColumnNames[i];
    //指定なしカラムは空文字を入れる
    if (columnName == "") {
      values.push( "" );
      continue;
    }

    const columnDefinition = engine.findDataDefinitionByVarName( columnName );
    const columnObject = engine.findDataByVarName( columnName );
    let columnValue = '';

    //データ型によって値の取得方法が変わる(テーブル型・掲示板型は考慮外)
    if ( columnDefinition.matchDataType( "SELECT" ) ) {
      if ( columnObject ) {
        for ( let i = 0; i < columnObject.size(); i++ ){
          const select = columnObject.get(i);
          if ( columnValue != '' ) {
            columnValue += ',';
          }
          columnValue += select.getValue() + ":" + select.getDisplay();
        }
      }

    } else if ( columnDefinition.matchDataType( "QUSER" ) ) {
      if ( columnObject ) {
        columnValue = columnObject.getName() + '<' + columnObject.getEmail() + '>';
      }

    } else if ( columnDefinition.matchDataType( "QGROUP" ) ) {
      if ( columnObject ) {
        columnValue = columnObject.getName();
      }

    } else if ( columnDefinition.matchDataType( "FILE" ) ) {
      if ( columnObject ) {
        for ( let i = 0; i < columnObject.size(); i++ ) {
          const file = columnObject.get(i);
          if ( columnValue != '' ) {
            columnValue += ',';
          }
          columnValue += file.getName();
        }
      }

    } else if ( columnDefinition.matchDataType( "LIST" ) ) {
      //スキップ

    } else if ( columnDefinition.matchDataType( "DISCUSSION" ) ) {
      //スキップ

    } else {
      if ( columnObject ) {
        columnValue = columnObject.toString();
      }
    }

    values.push( columnValue );
  }

}

/**
  * フォルダの URL からファイル情報(ドライブ ID とファイル ID)を取得し、
  * オブジェクトで返す(URL が空の場合はエラーとする)
  * @param {String} fileUrl  フォルダの URL
  * @param {String} oauth2  OAuth2 設定
  * @return {Object} fileInfo  ファイル情報 {driveId, fileId}
  */
function getFileInfoByUrl( fileUrl, oauth2 ) {
  let fileInfo;
  if ( fileUrl !== "" && fileUrl !== null ) {
    // 分割代入
    const {
      id,
      parentReference: {
        driveId
      }
    } = getObjBySharingUrl( fileUrl, oauth2 );
    fileInfo = {driveId: `drives/${driveId}`, fileId: id};
  }
  return fileInfo;
}

/**
  * OneDrive のドライブアイテム(ファイル、フォルダ)のメタデータを取得し、JSON オブジェクトを返す
  * API の仕様:https://docs.microsoft.com/ja-jp/onedrive/developer/rest-api/api/shares_get?view=odsp-graph-online
  * @param {String} sharingUrl  ファイルの共有 URL
  * @param {String} oauth2  OAuth2 設定
  * @return {Object} responseObj  ドライブアイテムのメタデータの JSON オブジェクト
  */
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 );
}

/**
  * 共有URLをunpadded base64url 形式にエンコードする
  * @param {String} sharingUrl  共有 URL
  * @return {String} encodedSharingUrl  エンコードされた共有 URL
  */
function encodeSharingUrl( sharingUrl ) {
  let encodedSharingUrl = base64.encodeToUrlSafeString( sharingUrl );
  while ( encodedSharingUrl.slice(-1) === '=' ) {
    encodedSharingUrl = encodedSharingUrl.slice(0,-1);
  }
  return `u!${encodedSharingUrl}`;
}

/**
  * 指定シートの指定行にデータを入力する
  * @param {Object} bookInfo
  * @param {String} bookInfo.driveId  ワークブックのドライブ ID
  * @param {String} bookInfo.fileId  ワークブックのファイル ID
  * @param {String} tableName  挿入先シートの名前
  * @param {Array} values  挿入するデータの配列
  * @param {String} oauth2  OAuth2 設定
  */
function postData( {driveId, fileId}, tableName, values, oauth2 ){

  const postUri = `${GRAPH_URI}${driveId}/items/${fileId}/workbook/tables/${tableName}/rows`;
//  const postUri = `${GRAPH_URI}me/drive/items/${fileId}/workbook/tables/${tableName}/rows`;
  const requestBody = makeRequestToAdd(values);
//engine.log("json:" + JSON.stringify(requestBody) + "")

  const response = httpClient.begin()
    .authSetting( oauth2 )
    .body( JSON.stringify(requestBody), "application/json" )
    .post( postUri );
  
  logAndJudgeError(response, "POST");

  const dataId = configs.get( "conf_IndexNum" );
  if ( dataId ){
    const jsonObj = JSON.parse( response.getResponseAsString() );
    const index = jsonObj.index + "";
    engine.setDataByNumber( dataId, index + "" );
  }

}

/**
  * 新しい行に追加するデータを、JSON 形式に変換する
  * @param {Array} values  データの入った配列
  * @return {JSON Object} 変換した JSON オブジェクト
  */
function makeRequestToAdd(values){
  let request = {
    values : [[]]
  };
  for(let i = 0; i < values.length; i++){
    if(values[i] === "" || values[i] === null){
      request.values[0].push(null);
    }else{
      if(values[i].length > 32767){
        throw "Can't set text over 32,767 character.";
      }
      request.values[0].push(values[i]);
    }
  }
  return request;
}

/**
  * ログの出力と、エラー発生時のスローを行う
  * @param {HttpResponseWrapper} response  リクエストの応答
  * @param {String} requestType リクエストをどの形式で行ったか("GET" or "POST" or "PATCH")
  * @return {String} responseStr レスポンスの文字列
  */
function logAndJudgeError(response, requestType){
  const responseStr = response.getResponseAsString();
//engine.log("response:" + responseStr);
  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 自由改変可能な JavaScript (ECMAScript) コードです。いかなる保証もありません。
(アドオン自動工程のインストールは Professional editionでのみ可能です)

Notes

  • Microsoft365 系のサービスとの連携設定について
  • Excel側に「テーブル」の設定が必要になります。こちらのページを参考にしてください。
  • シート名にカッコ等の記号が入っている場合にはエラーになることがあります。エラーとなった場合にはシート名の変更を検討してください。

Capture

Appendix

このアドオンXMLは、テーブルを利用しているので、「Microsoft 365 Excel: 行追加」よりも競合に強い作りとなっています。
※「Microsoft 365 Excel: 行追加」の内部処理としては、値または書式設定が割り当たっているセル範囲から末尾行を判定(内部的に usedRange() を利用)し、行追加を行います。 そのため、複数のプロセスから同時に実行された場合、競合により処理が正常に完了しない可能性があります。

また、「追加したいカラムのフィールド名」により追加したい列を多数指定することができ、「Microsoft 365 Excel: テーブル行追加」よりも一度に多くの列に値を入力することができます。

See Also

上部へスクロール

Questetra Supportをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む