Как искать и фильтровать Google Sheet по двум параметрам в двух разных столбцах - PullRequest
2 голосов
/ 18 октября 2019

У меня есть лист с 46 столбцами и сколько будет неопределенное количество строк. Я ищу способ создания веб-приложения с простым пользовательским интерфейсом, который позволяет выполнять поиск по двум критериям и отфильтровывать все результаты, которые не соответствуют этому критерию. Первый - поиск по названию / emp #, который попадает в столбцы 3 и 4 соответственно. Другой поиск даты. Идея состоит в том, что я могу искать все экземпляры имен или номеров этих людей, которые попадают в эту дату, и возвращать их в виде таблицы html или некоторой аналогичной и разумно разнесенной презентации.

Ниже приведен код, который яв настоящее время экспериментировал с. Мои знания довольно ограничены, и я хочу понять, как это работает, поэтому держать его как можно более простым было бы идеально. Мне удалось создать поиск в одном окне с помощью TextFinder, но я слышал, что это может быть медленным, и этот лист, как потенциал, может быть большим. Я также не могу понять, как отфильтровать его во второй раз с другой категорией. Я попытался взять результаты первого текстового поиска и запустить их через другой текстовый инструмент, но это не сработало.

code.gs

function doGet() {
  return HtmlService.createTemplateFromFile('index').evaluate();
}

function getValuesFromSS(search) {
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
  var lastRow = ss.getLastRow();
  var range = ss.getRange(1,3,lastRow,2); //define range for column D
  var ranges = range.createTextFinder(search).findAll();
  var names = '';
  var nums = '';
  var dates = '';
  var urls = '';

  //loop through each range
  for (i = 0; i < ranges.length; i++) {

    var row = ranges[i].getRow();
    var lastCol = ss.getLastColumn();
    var values = ss.getRange(row, 1, 1, lastCol).getDisplayValues(); //get all values for the row
    var empname = values[0][2]; //column C
    var empnum = values[0][3];  //column D
    var date = values[0][4];  //column E
    var url = values[0][46];

    names+=Utilities.formatString("<td>" + empname + "</td>");
    nums+=Utilities.formatString("<td>" + empnum + "</td>");
    dates+=Utilities.formatString("<td>" + date + "</td>");
    urls+=Utilities.formatString("<td>" + "<a href='https://drive.google.com/uc?export=view&id='" + url + "'>DVIR</a>" + "</td>");
}

return {
  first: names,
  second: nums,
  third: dates,
  fourth: urls
}
}

index.html

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script type="text/javascript">

    function setPageValues () {
    var search = document.getElementsByName('searchtext')[0].value;
      google.script.run.withSuccessHandler(disp).getValuesFromSS(search);
    }

    function disp(values){
      document.getElementById("results1").innerHTML = values.first;
      document.getElementById("results2").innerHTML = values.second;
      document.getElementById("results3").innerHTML = values.third;
      document.getElementById("results4").innerHTML = values.fourth;
    }
  </script>
</head>
<style>
table {
    border-collapse: collapse;
    }
tr { 
  display: block; 
  float: left; 
  }
td {
    border: 1px solid Black;
    display: block; 
    }
</style>
<body>
<input type="text" name="searchtext">
<input type="button" value="Search" onclick="setPageValues();">
<br>
<div name="resultbox">
<table>
<tr id="results1">
</tr>
<tr id="results2">
</tr>
<tr id="results3">
</tr>
<tr id="results4">
</tr>
</table>
</div>
</body>
<script>
</script>
</html>

Вот пример ссылки на электронную таблицу: https://docs.google.com/spreadsheets/d/1scFOr4nUXwm7brvlMPHFJhyLei3TI-uvoOVugsx-TeA/edit?usp=sharing

Как я уже говорил, я хочу найти имя -или- № в одном поле и дату в другом и отфильтровать только те результаты, которыесопоставьте оба, чтобы отобразить в HTML. Спасибо!

Ответы [ 2 ]

1 голос
/ 18 октября 2019
  • Вы хотите искать не только «Имя драйвера» и «Номер драйвера», но также «Дата» в вашей электронной таблице.
    • В этом случае бывают случаи, когда вводится только «Имя драйвера» или «Номер драйвера». И есть случаи, когда вводится только «Дата».
  • Вы хотите добиться этого с помощью веб-приложений со скриптом Google Apps.

Если я понимаюправильно, как насчет этого ответа? Пожалуйста, подумайте об этом как об одном из нескольких ответов.

Точки изменения:

  • В этой модификации тег ввода даты был добавлен на стороне HTML.
  • Когда были введены «Имя драйвера» / «Номер драйвера» и «Дата», эти значения отправляются на сторону скрипта Служб Google в виде объекта.
  • В скрипте Служб Google эти значения ищутся с использованием TextFinder.
    • Стоимость процесса TextFinder ниже, чем при поиске в каждой строке. Поэтому я использовал для поиска «Имя драйвера» / «Номер драйвера» и «Дата».

Модифицированный скрипт:

Когда ваш скрипт модифицирован,измените его следующим образом.

Сторона HTML: index.html

С:
function setPageValues () {
  var search = document.getElementsByName('searchtext')[0].value;
  google.script.run.withSuccessHandler(disp).getValuesFromSS(search);
}
К:
function setPageValues () {
  var search = document.getElementsByName('searchtext')[0].value;
  var date = document.getElementsByName('date')[0].value;
  var obj = {};
  if (!search && !date) alert("No search values.");
  if (search) {
    obj.name = search;
  }
  if (date) {
    obj.date = date;
  }
  google.script.run.withSuccessHandler(disp).getValuesFromSS(obj);
}

И

С:
<input type="text" name="searchtext">
<input type="button" value="Search" onclick="setPageValues();">
К:
<input type="text" name="searchtext">
<input type="date" name="date">
<input type="button" value="Search" onclick="setPageValues();">

Сторона скрипта Google Apps: code.gs

From:
var range = ss.getRange(1,3,lastRow,2); //define range for column D
var ranges = range.createTextFinder(search).findAll();
To:
var ranges = [];
if ("name" in search && search.name != "") {
  ranges = ss.getRange(1, 3, lastRow, 2).createTextFinder(search.name).findAll();
}
if ("date" in search && search.date != "") {
  var dateRanges = ss.getRange(1, 5, lastRow, 1).createTextFinder(search.date).findAll();
  if (ranges.length > 0) {
    ranges = ranges.filter(function(r1) {return dateRanges.some(function(r2) {return r1.getRow() == r2.getRow()})});
  } else {
    ranges = dateRanges;
  }
}
  • В этом случае при запуске Web Apps вы можете видеть 2 тега ввода.
    • Когда вы вводите только «Имя водителя» / «Номер водителя», отображаются значения, полученные с помощью поиска «Имя водителя» / «Номер водителя».
    • Когда вы вводите только «Дата»отображаются значения, полученные с помощью поиска «Дата».
    • Когда вы вводите «Имя драйвера» / «Номер драйвера» и «Дата», значения, полученные с помощью поиска «Имя драйвера» / «Номер драйвера» иОтображается «Дата».

Примечание:

  • В этом измененном сценарии используется ваша общая электронная таблица. Пожалуйста, будьте осторожны.
  • Для вывода были использованы ваш текущий скрипт и формат.

Ссылка:

Если я неправильно понял ваш вопрос, и это не то направление, в котором вы хотите, прошу прощения.

0 голосов
/ 20 октября 2019

Используйте функцию запроса для динамического отображения результатов при изменении.

Используйте имена range1 и named range2 для направляющих фильтров для запуска выбора запросов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...