【问题标题】:Google sheet + Web app search multiple google workbook and return all matching rows谷歌工作表+网络应用搜索多个谷歌工作簿并返回所有匹配的行
【发布时间】:2021-08-03 06:02:07
【问题描述】:

任何人都知道如何修改下面的代码以从 2 个单独的谷歌工作簿中搜索?目前,这仅适用于从 1 个工作簿中的 1 个 google sheet 进行搜索。

这两张表的标题完全相同。

当用户搜索特定文本时,它应该显示两个工作簿中的匹配行。

代码.gs:

function doGet() {
  return HtmlService.createTemplateFromFile('Index')
  .evaluate()
  .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}


/* PROCESS FORM */
function processForm(formObject){  
  var result = "";
  if(formObject.searchtext){//Execute if form passes search text
      result = search(formObject.searchtext);
  }
  return result;
}

//SEARCH FOR MATCHED CONTENTS 
function search(searchtext){
  var spreadsheetId   = '1443X5UzzRfpYachZZLFrmYFq821ioioqwFAnASY'; //** CHANGE !!!
  var dataRage        = 'TEST!A2:F';                                    //** CHANGE !!!
  var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRage).values;
  var ar = [];
  
  data.forEach(function(f) {
    if (~f.indexOf(searchtext)) {
      ar.push(f);
    }
  });
  return ar;
}

索引.html

<!DOCTYPE html>
<html>
    <head>
        <base target="_top">
        <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" integrity="sha384-xrRywqdh3PHs8keKZN+8zzc5TX0GRTLCcmivcbNJWm2rs5C8PRhcEn3czEjhAO9o" crossorigin="anonymous"></script>
        
        <!--##JAVASCRIPT FUNCTIONS ---------------------------------------------------- -->
        <script>
          //PREVENT FORMS FROM SUBMITTING / PREVENT DEFAULT BEHAVIOUR
          function preventFormSubmit() {
            var forms = document.querySelectorAll('form');
            for (var i = 0; i < forms.length; i++) {
              forms[i].addEventListener('submit', function(event) {
              event.preventDefault();
              });
            }
          }
          window.addEventListener("load", preventFormSubmit, true); 
             
          
          //HANDLE FORM SUBMISSION
          function handleFormSubmit(formObject) {
            google.script.run.withSuccessHandler(createTable).processForm(formObject);
            document.getElementById("search-form").reset();
          }
        
          //CREATE THE DATA TABLE
          function createTable(dataArray) {
            if(dataArray && dataArray !== undefined && dataArray.length != 0){
              var result = "<table class='table table-sm table-striped' id='dtable' style='font-size:0.8em'>"+
                           "<thead style='white-space: nowrap'>"+
                             "<tr>"+                               //Change table headings to match witht he Google Sheet
                              "<th scope='col'>Group</th>"+
                              "<th scope='col'>QO Number</th>"+
                              "<th scope='col'>Patient NRIC</th>"+
                              "<th scope='col'>Swab Date</th>"+
                              "<th scope='col'>Lab ID</th>"+
                              "<th scope='col'>SERO Lab ID</th>"+
                            "</tr>"+
                          "</thead>";
              for(var i=0; i<dataArray.length; i++) {
                  result += "<tr>";
                  for(var j=0; j<dataArray[i].length; j++){
                      result += "<td>"+dataArray[i][j]+"</td>";
                  }
                  result += "</tr>";
              }
              result += "</table>";
              var div = document.getElementById('search-results');
              div.innerHTML = result;
            }else{
              var div = document.getElementById('search-results');
              //div.empty()
              div.innerHTML = "Data not found!";
            }
          }
        </script>
        <!--##JAVASCRIPT FUNCTIONS ~ END ---------------------------------------------------- -->
        
    </head>
    <body>
        <div class="container">
            <br>
            <div class="row">
              <div class="col">
            
                  <!-- ## SEARCH FORM ------------------------------------------------ -->
                  <form id="search-form" class="form-inline" onsubmit="handleFormSubmit(this)">
                    <div class="form-group mb-2">
                      <label for="searchtext">Swab Search</label>
                    </div>
                    <div class="form-group mx-sm-3 mb-2">
                      <input type="text" class="form-control" id="searchtext" name="searchtext" placeholder="QO or NRIC (last 4 digits)">
                    </div>
                    <button type="submit" class="btn btn-primary mb-2">Search</button>
                  </form>
                  <!-- ## SEARCH FORM ~ END ------------------------------------------- -->
              
              </div>    
            </div>
            <div class="row">
              <div class="col">
            
                <!-- ## TABLE OF SEARCH RESULTS ------------------------------------------------ -->
                <div id="search-results" class="table-responsive">
                  <!-- The Data Table is inserted here by JavaScript -->
                </div>
                <!-- ## TABLE OF SEARCH RESULTS ~ END ------------------------------------------------ -->
                  
              </div>
            </div>
        </div>
    </body>
</html>

【问题讨论】:

  • 使用不同的spreadsheetId 迭代来自var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRage).values; 的行。请具体说明您想要的输出格式。
  • 嗨,输出代码是这样的。 bpwebs.com/create-web-forms-to-get-data-from-google-sheets/… 我希望在用户搜索特定文本时显示两个工作簿的输出。所有匹配的行都应该出现。 :) 它不需要识别它来自哪个工作簿。

标签: google-apps-script google-sheets web-applications


【解决方案1】:

拥有一个包含您要从中检索数据的不同电子表格的ID 的数组,并对其进行迭代:

function search(searchtext){
  var spreadsheetIds = ['1443X5UzzRfpYachZZLFrmYFq821ioioqwFAnASY'];
  var dataRage = 'TEST!A2:F';
  var ar = [];
  spreadsheetIds.forEach(spreadsheetId => {
    var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRage).values;        
    data.forEach(function(f) {
      if (~f.indexOf(searchtext)) {
        ar.push(f);
      }
    });
  });
  return ar;
}

如果不同电子表格的范围符号也应该改变,那么也有一个包含这些范围的数组,并使用 forEach 索引参数访问数组中的每个元素:

function search(searchtext){
  var spreadsheetIds = ['SPREADSHEET_ID_1', 'SPREADSHEET_ID_2'];
  var dataRages = ['RANGE_1', 'RANGE_2'];
  var ar = [];
  spreadsheetIds.forEach((spreadsheetId, i) => {
    var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRages[i]).values;        
    data.forEach(function(f) {
      if (~f.indexOf(searchtext)) {
        ar.push(f);
      }
    });
  });
  return ar;
}

不确定是否要检索比行索引更多的信息,但如果是这种情况,只需将该信息推送到ar,而不仅仅是f

或者,使用 reduce:

function search(searchtext) {
  const spreadsheetIds = ['SPREADSHEET_ID_1', 'SPREADSHEET_ID_2'];
  const dataRages = ['RANGE_1', 'RANGE_2'];
  const ar = spreadsheetIds.reduce((acc, spreadsheetId, i) => {
    const data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRages[i]).values;
    return acc.concat(data.filter(f => f.includes(searchText)));
  }, []);
  return ar;
}

参考:

【讨论】:

  • 谢谢你这个作品,但搜索需要很长时间,大约 20 秒才能加载。有没有办法加快速度?一张纸大约有 8000 行,另一张大约有 800 行。
  • @Vanny 嗨,我添加了一个替代代码,使用 reducefilterincludes。我不确定这会加速代码多少(如果有的话)。我不认为它应该花那么长时间,即使使用原始代码。
猜你喜欢
  • 1970-01-01
  • 2021-12-28
  • 2023-02-02
  • 1970-01-01
  • 2017-05-25
  • 1970-01-01
  • 2021-12-30
  • 2021-10-07
  • 1970-01-01
相关资源
最近更新 更多