#google-apps-script #google-sheets #web-applications
Вопрос:
Кто — нибудь знает, как я могу изменить приведенный ниже код для поиска в 2 отдельных книгах Google? В настоящее время это работает только для поиска с 1 листа Google в 1 книге.
Оба этих листа имеют одинаковые заголовки.
Когда пользователь ищет определенный текст, он должен отображать соответствующие строки из обеих книг.
Code.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 resu<
}
//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;
}
Index.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 amp;amp; dataArray !== undefined amp;amp; 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 = resu<
}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>
Комментарии:
1. Повторите строки
var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRage).values;
с помощью другогоspreadsheetId
. Пожалуйста, укажите конкретный формат вывода, который вы хотите.2. Привет, выходной код соответствует этому. bpwebs.com/create-web-forms-to-get-data-from-google-sheets/… Я хотел бы, чтобы выходные данные для обеих книг отображались при поиске пользователем определенного текста. Должны появиться все совпадающие строки. 🙂 Ему не нужно определять, из какой книги он взят.
Ответ №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
index:
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
.
В качестве альтернативы используйте команду уменьшить:
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;
}
Ссылка:
Комментарии:
1. Спасибо, это работает, но поиск занимает очень много времени, около 20 секунд для загрузки. Есть ли в любом случае способ ускорить это? На 1 листе около 8000 строк, на другом-около 800.
2. @Vanny Привет, я добавил альтернативный код, используя
reduce
filter
иincludes
. Я не уверен, насколько, если таковые имеются, это ускорит код. Я не думаю, что это займет так много времени в любом случае, даже с исходным кодом.