Google Sheets: Master Table, Simple Xlookup

Google Sheets: Master Table, Simple Xlookup
Google Sheets: Master Table, Simple Xlookup

Returns a value by referencing master data in Google Spreadsheets. Searches for the Lookup Value in array C, and if an exact match, returns the value in array D at the same index. C and D are defined in A1Notation. The length must be the same.

2020-02-06 (C) Questetra, Inc. (MIT License)
https://support.questetra.com/addons/google-sheets-master-table-simple-xlookup/

Configs
  • A: Select OAuth2 Config Name (at [OAuth 2.0 Setting]) *
  • B: Set Document-ID of Spreadsheet File (44 chars in File URI) * #{EL}
  • C: Set ValueRange for LookupArray (e.g. “Sheet1!C:C”) * #{EL}
  • D: Set ValueRange for ReturnArray (e.g. “Sheet1!D:D”) * #{EL}
  • E: Set Lookup Value (e.g. “JP”) * #{EL}
  • F: Select STRING DATA for Return Value (update) *
Script (click to open)

// (c) 2020, Questetra, Inc. (the MIT License)

//// == OAuth2 Setting example ==
// Authorization Endpoint URL:
//  "https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force"
// Token Endpoint URL:
//  "https://accounts.google.com/o/oauth2/token"
// Scope:
//  "https://www.googleapis.com/auth/spreadsheets.readonly"
// Client ID:
//  ( from https://console.developers.google.com/ )
// Consumer Secret:
//  ( from https://console.developers.google.com/ )
//  *Redirect URL of Webapp OAuth-Client-ID: "https://s.questetra.net/oauth2callback"

//// https://developers.google.com/sheets/api/guides/concepts#a1_notation
// Sheet1!A1:B2 refers to the first two cells in the top two rows of Sheet1.
// Sheet1!A:A refers to all the cells in the first column of Sheet1.
// Sheet1!1:2 refers to the all the cells in the first two rows of Sheet1.
// Sheet1!A5:A refers to all the cells of the first column of Sheet 1, from row 5 onward.
// A1:B2 refers to the first two cells in the top two rows of the first visible sheet.
// Sheet1 refers to all the cells in Sheet1.

// lookup_value,lookup_array,return_array

// Notes:
// C and D length must be the same. 
// The search is only performed vertically.
// The search is performed in order from the top and ends when a exact match.
// No problem if return array D is on the left side of search array C.
// 
// Notes(ja):
// 配列Cと配列Dの要素数は同数でなければなりません。
// 探索は縦方向にのみ実行されます。
// 探索は上から順に実行され完全一致した時点で終了します。
// リターン配列Dは探索配列Cの左側にあっても問題ありません。

//////// START "main()" /////////////////////////////////////////////////////////////////

main();
function main(){ 

//// == Config Retrieving / 工程コンフィグの参照 ==
const oauth2      = configs.get( "conf_OAuth2"  )     + ""; // required
const documentId  = configs.get( "conf_DocumentId" )  + ""; // required
const valueRangeC = configs.get( "conf_ValueRangeC" ) + ""; // required
const valueRangeD = configs.get( "conf_ValueRangeD" ) + ""; // required
const lookupValue = configs.get( "conf_LookupValue" ) + ""; // required
const dataIdF     = configs.get( "conf_DataIdF" )     + ""; // required

engine.log( " AutomatedTask Config: Document ID: "  + documentId );
engine.log( " AutomatedTask Config: LookupArrayC: " + valueRangeC );
engine.log( " AutomatedTask Config: ReturnArrayD: " + valueRangeD );
if( lookupValue === "" ){
  throw new Error( "\n AutomatedTask ConfigError:" +
                   " Config {LookupValue E} is empty \n" );
}


//// == Data Retrieving / ワークフローデータの参照 ==
// (nothing)


//// == Calculating / 演算 ==
/// obtain OAuth2 Access Token
const token   = httpClient.getOAuth2Token( oauth2 );

/// batch get two ranges of values via Google Sheets API v4
// https://developers.google.com/sheets/api/reference/rest
//  /v4/spreadsheets.values/batchGet
let apiRequest = httpClient.begin(); // HttpRequestWrapper
    apiRequest = apiRequest.bearer( token );
    apiRequest = apiRequest.queryParam( "ranges", valueRangeC ); 
    apiRequest = apiRequest.queryParam( "ranges", valueRangeD ); 
    apiRequest = apiRequest.queryParam( "majorDimension", "ROWS" ); 
    apiRequest = apiRequest.queryParam( "valueRenderOption", "FORMATTED_VALUE" ); 
                 // If formatted as currency, return "$1.23" not "1.23".
    apiRequest = apiRequest.queryParam( "dateTimeRenderOption", "FORMATTED_STRING" ); 
                 // Date as strings (the spreadsheet locale) not SERIAL_NUMBER
const apiUri = "https://sheets.googleapis.com/v4/spreadsheets/" +
                documentId + "/values:batchGet";
engine.log( " AutomatedTask Trying: GET " + apiUri );
const response = apiRequest.get( apiUri );
const responseCode = response.getStatusCode() + "";
engine.log( " AutomatedTask ApiResponse: Status " + responseCode );
if( responseCode !== "200"){
  throw new Error( "\n AutomatedTask UnexpectedResponseError: " +
         responseCode + "\n" + response.getResponseAsString() + "\n" );
}
const responseStr = response.getResponseAsString() + "";
const responseObj = JSON.parse( responseStr );
// engine.log( responseStr );

let strLookupArray = "";
  for( let j = 0; j < responseObj.valueRanges[0].values.length; j++ ){
    for( let k = 0; k < responseObj.valueRanges[0].values[j].length; k++ ){
      strLookupArray += responseObj.valueRanges[0].values[j][k];
      if( k != responseObj.valueRanges[0].values[j].length - 1 ){
        strLookupArray += " ";
      }
    }
    if( j != responseObj.valueRanges[0].values.length - 1 ){
      strLookupArray += "\n";
    }
  }
//engine.log( " AutomatedTask Response of ValueRangeC: \n " + strLookupArray );

let strReturnArray = "";
  for( let j = 0; j < responseObj.valueRanges[1].values.length; j++ ){
    for( let k = 0; k < responseObj.valueRanges[1].values[j].length; k++ ){
      strReturnArray += responseObj.valueRanges[1].values[j][k];
      if( k != responseObj.valueRanges[1].values[j].length - 1 ){
        strReturnArray += " ";
      }
    }
    if( j != responseObj.valueRanges[1].values.length - 1 ){
      strReturnArray += "\n";
    }
  }
//engine.log( " AutomatedTask Response of ValueRangeD: \n " + strReturnArray );

/// search value
let returnValue = "";
const arrLookup = strLookupArray.split("\n");
const arrReturn = strReturnArray.split("\n");
for( let i = 0; i < arrLookup.length; i++ ){
  if( lookupValue === arrLookup[i] ){
    returnValue = arrReturn[i];
    engine.log( " AutomatedTask Lookup: Match ID " + i );
    break;
  }
}
if( returnValue === "" ){
  engine.log( " AutomatedTask Lookup: No Match" );
}

//// == Data Updating / ワークフローデータへの代入 ==
engine.setDataByNumber( dataIdF, returnValue );

} //////// END "main()" /////////////////////////////////////////////////////////////////

Download

Capture

Returns a value by referencing master data in Google Spreadsheets. Searches for the Lookup Value in array C, and if an exact match, returns the value in array D at the same index. C and D are defined in A1Notation. The length must be the same.

Notes

  1. C and D length must be the same.
  2. The search is only performed vertically.
  3. The search is performed in order from the top and ends when a exact match.
  4. No problem if return array D is on the left side of search array C.
  5. Document ID is contained in the URL. https://docs.google.com/spreadsheets/d/SPREADSHEETID/edit#gid=0
  6. Even if a range is specified, columns and rows with no data are ignored.
  7. How to specify the range depends on Google API A1 notation.
    1. Sheet1!A1:B2 refers to the first two cells in the top two rows of Sheet1.
    2. Sheet1!A:A refers to all the cells in the first column of Sheet1.
    3. Sheet1!1:2 refers to the all the cells in the first two rows of Sheet1.
    4. Sheet1!A5:A refers to all the cells of the first column of Sheet 1, from row 5 onward.
    5. A1:B2 refers to the first two cells in the top two rows of the first visible sheet.
    6. Sheet1 refers to all the cells in Sheet1.
  8. If a multi-column range is specified in the array definition (eg “Sheet1!A:B”), the array element value will be the string joined with space. (“{FirstName} {SurName}”)

See also

2 thoughts on “Google Sheets: Master Table, Simple Xlookup”

  1. Pingback: Google Sheets: Spreadsheets, Add Sheet – Questetra Support

  2. Pingback: Google Sheets: Sheet Row, Update with Singleline TSV – Questetra Support

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top

Discover more from Questetra Support

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

Continue reading