从具有指定字符串的电子表格返回行数据,而不循环遍历所有行

时间:2017-07-20 12:23:16

标签: google-apps-script google-sheets google-spreadsheet-api

我手边有一项任务,我需要返回包含用户定义字符串的整个行数据

实现它的一种方法是循环遍历所有行,但只有当您知道要搜索的列时,此才有效,如下面给出的代码所示。

var sheetData = SpreadsheetApp.getActiveSpreadsheet().getDataRange().getValues();
var searchString = "testSearch";

for(var i=0;i<sheetData.getLastRow();i++)
{
  //assuming we know that the search string is going to be in Column 2
  if(sheetData[i][1].search(searchString)!=-1)
  {
    var rowData = sheetData[i];
    return rowData;
  }
}

所以我的问题是,是否有我们可以实现的任何方式而不必逐个循环遍历所有行

为了使问题陈述更清晰,我希望实现类似'Find'功能的功能,如下图所示:

enter image description here

这样可以轻松浏览多个工作表/电子表格中的大量数据

注意:我正在使用 Google Apps脚本搜索此解决方案。

1 个答案:

答案 0 :(得分:1)

以下是从匹配行获取数据的代码。它可以是部分匹配。您不需要知道列数或行数。您无需知道要查看的列。

要使此代码生效,请将Put Sheet Tab Name Here替换为要使用的工作表标签的名称。 searchString可以传递给函数。如果没有传入任何内容,则代码使用硬编码值进行搜索。

function findRowOfSearchString(searchString) {
  var arrIndexOfAllMatches,dataAsStringWithBrackets,dataRange,i,
      isThereA_Match,j,ll,L,L2,matchOfAllInnerBrackets,numberOfColumns,numberOfRows,
      rowCutOff,rowsOfMatchedData,sh,sheetData,ss,thisIndex,thisMatchIndex,thisRow,thisRowData;

  ll = function(a,b) {
    Logger.log(a + ": " + b)
  }

  if (!searchString) {
    searchString = "testSe";
  }

  ss = SpreadsheetApp.getActiveSpreadsheet();
  sh = ss.getSheetByName('Put Sheet Tab Name Here');//

  dataRange = sh.getDataRange();

  numberOfColumns = dataRange.getNumColumns();
  numberOfRows = dataRange.getNumRows(); //changed 'getNumColumns' to 'getNumRows'

  sheetData = dataRange.getValues();//Get a 2D array of all sheet data

  dataAsStringWithBrackets = JSON.stringify(sheetData);
  //ll('dataAsStringWithBrackets: ',dataAsStringWithBrackets)

  isThereA_Match = dataAsStringWithBrackets.indexOf(searchString);
  //ll('isThereA_Match: ',isThereA_Match)

  if (isThereA_Match === -1) {return;}//There is no match - stop

  arrIndexOfAllMatches = [];

  L = dataAsStringWithBrackets.length;
  //ll('L',L)

  thisMatchIndex = 0;

  for (i=0;i<L;i++) {
    //ll('i',i)
    thisMatchIndex = dataAsStringWithBrackets.indexOf(searchString,thisMatchIndex + 1);

    //ll('thisMatchIndex',thisMatchIndex)

    if (thisMatchIndex === -1) {//No more matches were found
      //ll('No more matches found',thisMatchIndex)
      break;
    }

    arrIndexOfAllMatches.push(thisMatchIndex);
  }

  //ll('arrIndexOfAllMatches',arrIndexOfAllMatches)

  matchOfAllInnerBrackets = [];

  thisMatchIndex = 0;

  for (i=0;i<L;i++){
    thisMatchIndex = dataAsStringWithBrackets.indexOf("],[",thisMatchIndex + 1);

    //ll('thisMatchIndex',thisMatchIndex)

    if (thisMatchIndex === -1) {//No more matches were found
      //ll('No more matches found',thisMatchIndex)
      break;
    }

    matchOfAllInnerBrackets.push(thisMatchIndex);
  }

  ll('matchOfAllInnerBrackets',matchOfAllInnerBrackets)

  rowsOfMatchedData = [];
  L = arrIndexOfAllMatches.length;
  L2 = matchOfAllInnerBrackets.length;

  for (i=0;i<L;i++){
    thisIndex = arrIndexOfAllMatches[i];
    ll('thisIndex: ' ,thisIndex)

    for (j=0;j<L2;j++){
      rowCutOff = matchOfAllInnerBrackets[j];
      ll('rowCutOff: ',rowCutOff)

      if (rowCutOff > thisIndex) {
        ll('greater than: ' ,thisIndex > rowCutOff)
        thisRow = j+1;
        ll('thisRow: ', (thisRow))
        rowsOfMatchedData.push(thisRow)
        break;
      }
    }
  }

  ll('rowsOfMatchedData: ',rowsOfMatchedData)

  L = rowsOfMatchedData.length;

  for (i=0;i<L;i++){
    thisRowData = sh.getRange(rowsOfMatchedData[i], 1, 1, numberOfColumns).getValues();
    ll('thisRowData: ',thisRowData)
  }
}