Каким образом в объекте события для триггера onEdit этот диапазон определяется как реальный объект диапазона и идентификатор свойства одновременно? - PullRequest
2 голосов
/ 29 мая 2020

У меня есть небольшой образец кода, чтобы подчеркнуть разницу между созданным мной объектом и объектом триггерного события. В объекте триггерного события я могу использовать термин e.range вместе со стандартными функциями класса диапазона, и он отлично работает. Однако я действительно не знаю, как создать объект псевдо-события, чтобы термин диапазона был чем-то большим, чем просто имя свойства.

   function onEdit(e) {
      console.log(JSON.stringify(e));
      var sh=e.range.getSheet();//e.range is a real range object
      if(sh.getName()=='Sheet2' && e.range.columnStart>1) {
        sh.getRange(1,1).setValue(JSON.stringify(e)+ '\n' + e.range.getA1Notation());
        var rg=sh.getRange(e.range.getA1Notation());//e.range is a real range object
        var myObj={value:rg.getValue,range:{columnStart:e.range.columnStart,rowStart:e.range.rowStart,columnEnd:e.range.columnEnd,rowEnd:e.range.rowEnd}};
        console.log(JSON.stringify(myObj));
        try{
          sh.getRange(2,1).setValue(JSON.stringify(myObj)+ '\n' + myObj.range.getA1Notation());//myObj.range is not a real range object
        }
        catch(m) {
          console.log('Error: ' + m);
        }
        try{
          sh.getRange(3,1).setValue(e.range.getValue());
        }
        catch(n) {
          console.log('Error: ' + n);
        }
      }
    }

Если вы отредактируете Sheet2 соответствующим образом, вы получите следующие журналы драйверов стека:

Stackdriver logs

May 29, 2020, 1:21:30 PM    Debug   {"source":{},"value":"55","user":{"email":"","nickname":""},"range":{"columnEnd":5,"columnStart":5,"rowEnd":3,"rowStart":3},"authMode":"LIMITED"}
May 29, 2020, 1:21:30 PM    Debug   {"range":{"columnStart":5,"rowStart":3,"columnEnd":5,"rowEnd":3}}
May 29, 2020, 1:21:30 PM    Debug   Error: TypeError: myObj.range.getA1Notation is not a function

Обратите внимание: я не могу использовать myObj.range с getA1Notation () метод. (примечание: на самом деле я не ожидал, что это сработает ... Я хотел бы знать, как правильно построить объект, чтобы он работал, и я еще не нашел правильного объяснения.

Я хотел бы узнать, как создать объект псевдо-события, чтобы я мог использовать myObj.range так же, как e.range.

Мне очень плохо после того, как Танаике ушел так много проблем. Но моя настоящая цель - создать объект события точно так, как он создается сервером. Чтобы я мог протестировать onEdit () с помощью тестовой функции, вызывающей onEdit (e), а не требовать фактического правки. И, что более важно, я бы просто хотел знать, как построить такой объект.

Думаю, это говорит о том, для чего я снимаю. Я хочу знать, как создать объект события в точности таким, какой он есть предоставленный нам из триггера onEdit, включая то, что e.range должен быть объектом, эквивалентным Class Range и, таким образом, способным использовать любой из методов, найденных здесь . Надеюсь, что это возможно. Я извиняюсь за эти поздние добавления, но они были вызваны некоторыми вопросами Танаике. Мне, вероятно, придется еще раз рассмотреть вопрос и сделать его более ясным.

Это код, над которым я работаю, и он далек от завершения, но это то, что можно сделать, зная ответ на мой вопрос.

function onXditTest(row) {
  var row=row||2;
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName('OnEditTest');
  const v=sh.getRange(row,1,1,sh.getLastColumn()).getValues()[0];
  const xsh=ss.getSheetByName(v[5]);
  const xrg=xsh.getRange(v[0],v[2],v[1]-v[0]+1,v[3]-v[2]+1);
  const evobj={range:{rowStart:v[0],rowEnd:v[1],columnStart:v[2],columnEnd:v[3]},value:v[4],range:xrg,source:ss};
  onXdit(evobj);
}

Реальный вопрос в том, как сделать evobj так, чтобы evobj.range был объектом Class Range и в то же время имел доступные evobj.range.columnStart, evobj.range. rowStart, evobj.range.columnEnd и evobj.range.rowEnd, чтобы тестируемый код в onEdit (e) вел себя так же, как в onXdit (e)

function onXdit(e) {//changed name so edits dont trigger the function
  e.source.toast('Entry');
  console.log(JSON.stringify(e));
  const sh=e.range.getSheet();
  if(sh.getName()=="Sheet2" && e.range.columnStart==4 && e.value=="TRUE" ) {
    e.source.toast('Past Condition');
    e.range.setValue("FALSE");
  }
}

Ответы [ 2 ]

1 голос
/ 30 мая 2020

Первая функция здесь выполняется с помощью кнопки RunOnXdit на боковой панели, и она вызывала функцию onXdit (), передавая объект события триггера psuedo onEdit вместе со свойством режима, чтобы я мог различать guish между запуском в тестовый режим и запуск в режиме реального времени.

function onXditTest(row) {
  var row=row||2;
  console.log('row: ' + row);
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName('OnEditTest');
  const v=sh.getRange(row,1,1,sh.getLastColumn()).getValues()[0];
  const xsh=ss.getSheetByName(v[5]);
  const xrg=xsh.getRange(v[0],v[2],v[1]-v[0]+1,v[3]-v[2]+1);
  var evobj={value:v[4]?"TRUE":"FALSE",source:ss,mode:true};
  evobj.range=xrg;//assign Class Range Object
  evobj.range.rowStart=v[0];
  evobj.range.rowEnd=v[1];
  evobj.range.columnEnd=v[3];
  evobj.range.columnStart=v[2]
  onXdit(evobj);
}

Вторую функцию можно запустить из указанной выше функции или из триггера onEdit с тем же кодом. Вышеупомянутая функция генерирует объект события триггера psuedo onEdit. Я был полностью шокирован, осознав, насколько легко было его создать.

function onXdit(e) {
//function onEdit(e) {
  e.source.toast('Entry');
  console.log(JSON.stringify(e));
  const sh=e.range.getSheet();
  if(sh.getName()=="Sheet2" && e.range.columnStart==4 && e.range.rowStart!=5 && e.value=="TRUE") {
    e.source.toast('Section 2');
    sh.getRange(1,1).setValue(JSON.stringify(e));
    e.range.offset(0,1).setValue('CheckBoxIsOff')
    e.range.setValue("FALSE");
  }
  if(sh.getName()=="Sheet2" && e.range.columnStart==4 && e.range.rowStart==5  && e.value=="TRUE") {
    e.source.toast('Section 2');
    sh.getRange(2,4,4,1).setValue(e.mode?"TRUE":"FALSE");
    //sh.getRange(5,4,1,1).setValue("FALSE");
    sh.getRange(2,5,4,1).setValue("");
  }
}

Это Sheet2, который должен быть подключен к тестеру onEdit

enter image description here

Это Sheet2 после нажатия кнопки Run OnXdit

enter image description here

Он делает именно то, что я хотел бы от onEdit ( ) с тем же кодом. Думаю, моя большая проблема заключалась в том, что я слишком много думал об этом.

enter image description here

Изображение выше - это просто простая таблица для предоставления соответствующего объекта события для onXdit () функция.

Анимация:

enter image description here

1 голос
/ 30 мая 2020

Я считаю, что ваша цель следующая.

  • Вы хотите создать объект события, такой как объект события, возвращаемый с помощью триггера события OnEdit, с использованием скрипта Google Apps.

Для это, как насчет этого ответа?

Я думаю, что объект события из триггера события OnEdit возвращается с внутреннего сервера на стороне Google. Так что я не уверен насчет реального сценария для этого. Итак, в этом ответе я хотел бы предложить метод создания объекта псевдособытия, как вы говорите.

В этом ответе я использовал классы JavaScript, которые можно использовать с V8. Но я не уверен, что вы ожидаете этого направления.

Пример сценария:

Чтобы использовать этот сценарий, скопируйте и вставьте следующий сценарий в редактор сценариев и сохраните Это. Затем отредактируйте ячейку. Таким образом, onEdit запускается триггером события OnEdit.

const createEventObject = obj => {
  // Class for creating the range object.
  class createRangeObject {
    constructor(obj) {
      this.columnEnd = obj.columnEnd;
      this.columnStart = obj.columnStart;
      this.rowEnd = obj.rowEnd;
      this.rowStart = obj.rowStart;
    }

    getA1Notation() {
      return SpreadsheetApp
        .getActiveSheet()
        .getRange(this.rowStart, this.columnStart, this.rowEnd - this.rowStart + 1, this.columnEnd - this.columnStart + 1)
        .getA1Notation();
    }

    getSheet() {
      return SpreadsheetApp
        .getActiveSheet();
    }
  }

  // Main script of createEventObject.
  class main {
    constructor(obj) {
      this.obj = obj;
    }

    get range() {
      return new createRangeObject(this.obj);
    }
  }
  return new main(obj);
}

// This function is run by editing cells.
function onEdit(e) {
  // This is your object.
  var myObj={range:{columnStart:e.range.columnStart,rowStart:e.range.rowStart,columnEnd:e.range.columnEnd,rowEnd:e.range.rowEnd}};

  // Create the pseudo event object.
  const obj = createEventObject(myObj.range);

  console.log(obj.range)
  console.log(obj.range.getA1Notation())
  console.log(obj.range.getSheet().getSheetName())
}

Результат:

В приведенном выше примере скрипта, например, когда редактируются ячейки «B3: C5», будет получен следующий результат.

  • obj.range равно { columnEnd: 3, columnStart: 2, rowEnd: 5, rowStart: 3 }.
  • obj.range.getA1Notation() равно B3:C5.
  • obj.range.getSheet().getSheetName() равно Sheet1 который является активным листом.

Примечание:

  • Этот ответ, в котором используются классы JavaScript, является одной из методологий. Так что я думаю, что могут быть более простые методы.
  • Это простой сценарий для объяснения этого обходного пути. Поэтому, если вы хотите использовать это в своей реальной ситуации, пожалуйста, измените это.
  • Пожалуйста, используйте этот скрипт с V8.

Ссылка:

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