Строка всегда возвращает 1 – Google Scripts

Я пытаюсь отобразить HTML-страницу со значениями из электронной таблицы. Я нажимаю на ссылку «Создать HTML-страницу», и она перенаправляет на созданную мной HTML-страницу. Он отображается правильно, за исключением того, что скрипт всегда получает значения из первой строки. У меня сложилось впечатление, что функция doGet() не принимает строки? Что бы это могло быть?

Код.gs

function fetchSpreadsheetValues(row) {
  var values = SpreadsheetApp.getActiveSheet().getRange(row, 1, row, 51).getValues(); // Get values from the specified range; original: row, 1, row, 51
  var rec = values[0];
  
  var candidate = {
    row: row, // always returning 1 (first row)
    r1: rec[0],
    r2: rec[1],
    r3: rec[2], 
    broker: rec[5], // Broker/Agent column
  };
  
  return candidate;
}
function doGet() { // must return HtmlOutput
  var cell = SpreadsheetApp.getActiveSheet().getCurrentCell(); // Get selected cell in the sheet
  var row = cell.getRow(); // Get selected cell's rows; always returning 1.
  
  var candidate = fetchSpreadsheetValues(row);
  
  var templ = HtmlService.createTemplateFromFile('agent-listing'); // Load HTML for the email; returns HtmlTemplate
  templ.candidate = candidate; // Assign candidate object to a variable in the template

  return templ.evaluate();
}

function onOpen() { // Add menu inside the spreadsheet
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Process').addItem('Send Email', 'showConfirmation').addItem('Generate HTML page', 'generateHTML').addToUi();
}

function generateHTML() {
  SpreadsheetApp.getUi()
  .showModalDialog(HtmlService.createHtmlOutputFromFile('openUrl').setHeight(50),"Generating HTML... Please wait.")
}

Агент-listing.html

<!DOCTYPE html>
<html lang = "en">
<head>
    <base target = "_top">
    <meta charset = "UTF-8">
    <title>Test</title>
    <meta name = "viewport" content = "width=device-width, initial-scale=1">
    <meta http-equiv = "X-UA-Compatible" content = "ie=edge">
    <script>
      window.onload=function(){
        google.script.run.doGet();
      }
    </script>
</head>
<body>
  <div style = "margin-left: 3%;">
    <!-- just to see the values -->
    <p>row <?= candidate.row ?>,</p>
    <p>R1 <?= candidate.r1 ?>,</p>
    <p>R2 <?= candidate.r2 ?>,</p>
    <p>R3 <?= candidate.r3 ?>,</p>
    <p>Hi <?= candidate.broker ?>,</p>
    <p>Test test</p>
  </div>
</body>
</html>

OpenUrl.html

<!DOCTYPE html>
<html>
  <head>
   <base target = "_blank">
    <script>
     var url1 ='https://script.google.com/macros/s/AKfycbxU3VzpwPsBPEnfkPtMmCzo0YACc9UXPUlIcd6cm5Q/dev';
     var winRef = window.open(url1);
     winRef ? google.script.host.close() : window.alert('Allow popup to redirect you to '+url1) ;
     window.onload=function(){
       document.getElementById('url').href = url1;
     }
    </script>
  </head>
  <body>
    Kindly allow pop ups<br />or <a id='url'>click here</a> to continue!!!
  </body>
</html>

Что делает этот сторонний скрипт: https://script.google.com/macros/s/AKfycbxU3VzpwPsBPEnfkPtMm‌​Czo0YACc9UXPUlIcd6cm‌​5Q/dev? Это скрипт, который показывает оцененный шаблон agent-listing в виде диалога?

CMB 18.12.2020 22:01

Вы всегда получаете строку 1, потому что она не открывает тот же экземпляр электронной таблицы, который открыл пользователь, и автоматически переходит к SpreadsheetApp.getActive().getSheets()[0], а активная ячейка по умолчанию равна A1.

Cooper 18.12.2020 22:59

@CarlosM да, это он.

Norseback 19.12.2020 05:25
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Раскрытие чувствительных данных
Раскрытие чувствительных данных
Все внешние компоненты, рассмотренные здесь до сих пор, взаимодействуют с клиентской стороной. Однако, если они подвергаются атаке, они не...
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Руководство ChatGPT по продаже мини JS-файлов
Руководство ChatGPT по продаже мини JS-файлов
JS-файл - это файл, содержащий код JavaScript. JavaScript - это язык программирования, который в основном используется для добавления интерактивности...
0
3
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот как я получил две работы, чтобы подобрать текущую строку и лист электронной таблицы. Когда я запускаю диалоговое окно, я использую getScriptUrl(), чтобы получить текущий scriptApp.getService().getUrl(), и к этому я также добавляю имя строки и листа в качестве параметров запроса к URL-адресу. Я планировал использовать их в doGet(), но в этой версии я решил использовать cacheservice для их хранения в течение примерно 30 секунд, что более чем достаточно для запуска ah3, похожего на список вашего агента, и функция dg() использует их. получить активный лист и текущую строку.

Я только что попробовал это с doGet (e) и dg (e), используя e.parameter.name и e.parameter.row для передачи имени строки и листа, чтобы можно было отображать правильные данные, это также сводит на нет необходимость вызывать Google. script.run.dg() в файле ah2.html, который похож на ваш agent-listing.html.

Мой ah3.html похож на ваш openURL.html.

<!DOCTYPE html>
<html>
<head>
    <base target = "_blank">
    <script>
     window.onload=function(){
       google.script.run
       .withSuccessHandler(function(obj){
         var winRef = window.open(obj.url);
         winRef ? google.script.host.close() : window.alert('Allow popup to redirect you to '+ obj.url) ;
         document.getElementById('url').href = obj.url;
       })
       .getScriptUrl();
     }
    </script>
</head>

<body>
    Kindly allow pop ups<br />or <a id='url'>click here</a> to continue!!!
</body>

</html>

Мой «ah3.html» похож на ваш «agent-list.html».

<!DOCTYPE html>
<html lang = "en">
<head>
    <base target = "_top">
    <meta charset = "UTF-8">
    <title>Test</title>
    <meta name = "viewport" content = "width=device-width, initial-scale=1">
    <meta http-equiv = "X-UA-Compatible" content = "ie=edge">
    <script>
      window.onload=function(){
        google.script.run.dg();//remove this if you use the query string in doGet(e)
      }
    </script>
</head>
<body>
  <div style = "margin-left: 3%;">
    <!-- just to see the values -->
    <p>row <?= candidate.row ?>,</p>
    <p>R1 <?= candidate.r1 ?>,</p>
    <p>R2 <?= candidate.r2 ?>,</p>
    <p>R3 <?= candidate.r3 ?>,</p>
    <p>Hi <?= candidate.broker ?>,</p>
    <p>Sheet Name <?= sheet ?>,</p>
    
    <p>Test test</p>
  </div>
</body>
</html>

Мой ag3.gs похож на ваш код скрипта Google

function fetchSpreadsheetValues(row) {//this needs to be getting an obj with bow row and sheetname values  so if you decided to use cache service like I did then you'll need to modify this also.
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getActiveSheet();
  const values=sh.getRange(row, 1, sh.getLastRow()-row+1, 51).getValues(); 
  const rec=values[0];
  var candidate = {row: row,r1:rec[0],r2:rec[1],r3:rec[2],broker:rec[5]};
  return candidate;
}
function doGet(e) {
  return dg(e);
}

function launchDialog() {
  SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah3'),"Generating HTML... Please wait.");
}

function dg(e) {
  const ss=SpreadsheetApp.getActive();
  const cs=CacheService.getScriptCache();
  const sh=ss.getSheetByName(cs.get('name'));//use e.parameter.name here with querystring if you use them you can avoid the use of the cacheservice.
  var row=Number(cs.get('row'));//use e.parameter.row here with querystring
  var candidate=fetchSpreadsheetValues(row);
  var templ=HtmlService.createTemplateFromFile('ah2');
  templ.candidate=candidate;
  templ.sheet=sh.getName();
  return templ.evaluate();
}

function getScriptUrl() {
  const cs=CacheService.getScriptCache();
  const obj=getCurrentPosition();
  cs.put('row', obj.row, 30);
  cs.put('name', obj.name, 30);
  let robj = {url:ScriptApp.getService().getUrl() + '?&row=' + obj.row + '&name=' + obj.name,row:obj.row,name:obj.name};
  Logger.log(JSON.stringify(robj));
  return robj;
}

function activesheettest() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getActiveSheet();
  ss.toast(ss.getSheets()[0].getName());
}

function getCurrentPosition() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getActiveSheet();
  const cell=sh.getActiveRange();
  const row=cell.getRow();
  const robj = {row:row,name:sh.getName()};
  Logger.log(JSON.stringify(robj));
  return robj;
}

Это версия, в которой используется строка запроса веб-приложения с именем и строкой, добавляемой к URL-адресу.

Ag3.gs:

function fetchSpreadsheetValues(obj) {
  const sheetname=obj.name;
  const row=obj.row;
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName(sheetname);
  const values=sh.getRange(row, 1, sh.getLastRow()-row+1, 51).getValues(); 
  const rec=values[0];
  var candidate = {row: row,r1:rec[0],r2:rec[1],r3:rec[2],broker:rec[5]};
  return candidate;
}
function doGet(e) {
  return dg(e);
}

function launchDialog() {
  SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah3'),"Generating HTML... Please wait.");
}

function dg(e) {
  const ss=SpreadsheetApp.getActive();
  const cs=CacheService.getScriptCache();
  const sh=ss.getSheetByName(e.parameter.name);
  var row=Number(e.parameter.row);
  var candidate=fetchSpreadsheetValues({row:e.parameter.row,name:e.parameter.name});
  var templ=HtmlService.createTemplateFromFile('ah2');
  templ.candidate=candidate;
  templ.sheet=sh.getName();
  return templ.evaluate();
}

function getScriptUrl() {
  const cs=CacheService.getScriptCache();
  const obj=getCurrentPosition();
  cs.put('row', obj.row, 30);
  cs.put('name', obj.name, 30);
  let robj = {url:ScriptApp.getService().getUrl() + '?&row=' + obj.row + '&name=' + obj.name,row:obj.row,name:obj.name};
  Logger.log(JSON.stringify(robj));
  return robj;
}

function activesheettest() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getActiveSheet();
  ss.toast(ss.getSheets()[0].getName());
}

function getCurrentPosition() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getActiveSheet();
  const cell=sh.getActiveRange();
  const row=cell.getRow();
  const robj = {row:row,name:sh.getName()};
  Logger.log(JSON.stringify(robj));
  return robj;
}

Ah2.html:

<!DOCTYPE html>
<html lang = "en">
<head>
    <base target = "_top">
    <meta charset = "UTF-8">
    <title>Test</title>
    <meta name = "viewport" content = "width=device-width, initial-scale=1">
    <meta http-equiv = "X-UA-Compatible" content = "ie=edge">
    <script>
      window.onload=function(){
        //google.script.run.dg();
      }
    </script>
</head>
<body>
  <div style = "margin-left: 3%;">
    <!-- just to see the values -->
    <p>row <?= candidate.row ?>,</p>
    <p>R1 <?= candidate.r1 ?>,</p>
    <p>R2 <?= candidate.r2 ?>,</p>
    <p>R3 <?= candidate.r3 ?>,</p>
    <p>Hi <?= candidate.broker ?>,</p>
    <p>Sheet Name <?= sheet ?>,</p>
    
    <p>Test test</p>
  </div>
</body>
</html>

Ah3.html:

<!DOCTYPE html>
<html>
<head>
    <base target = "_blank">
    <script>
     window.onload=function(){
       google.script.run
       .withSuccessHandler(function(obj){
         var winRef = window.open(obj.url);
         winRef ? google.script.host.close() : window.alert('Allow popup to redirect you to '+ obj.url) ;
         document.getElementById('url').href = obj.url;
       })
       .getScriptUrl();
     }
    </script>
</head>

<body>
    Kindly allow pop ups<br />or <a id='url'>click here</a> to continue!!!
</body>

</html>

И я только что протестировал эту версию, и теперь она правильно получает данные, когда я изменил функцию fetchSpreadsheetValues(). Версия выше, вероятно, все еще неверна, потому что я не изменил эту функцию там.

Это интересный способ вызвать веб-приложение, сначала запустив диалоговое окно. Проблема в том, что как только вы теряете фокус на электронной таблице, текущая ячейка и текущая страница теряют связь с листом, открытым пользователем.

Cooper 19.12.2020 00:39

Итак, после перенаправления скрипт не получает электронную таблицу. Странный.

Norseback 19.12.2020 05:41

Он больше не обращается к тому же экземпляру, который открыл пользователь, поэтому активным листом всегда является SpreadsheetApp.getActive().getSheets()[0], а выбранный диапазон всегда A1. Когда фокус находится в диалоговом окне, по-прежнему осуществляется доступ к тому же экземпляру, что и пользователь, но не после открытия окна веб-приложения. Это не то, что я знаю, а скорее наблюдал.

Cooper 19.12.2020 06:40

Но вы можете передать имя листа и строку через URL-адрес веб-приложения, или я также использовал службу кэширования. Я думаю, что предпочел бы запускать скрипт с боковой панели и вообще не использовать веб-приложение. Почему вы хотите использовать веб-приложение?

Cooper 19.12.2020 06:46

Я хочу отобразить определенную информацию об агенте и свойстве из данных электронной таблицы в формате HTML

Norseback 21.12.2020 16:45

В последний раз я думал об этом вопросе два дня назад. Если вы хотите предоставить обновление, вам придется предоставить немного больше контекста.

Cooper 21.12.2020 20:49

Я забыл обновить. Виноват. Это фактически решило мою проблему. Спасибо!

Norseback 24.12.2020 15:17

Другие вопросы по теме