Есть ли метод google-script, такой как Application.Intersect (Target, Range) в Excel? - PullRequest
0 голосов
/ 08 января 2019

Теперь я понимаю, что вопрос глубже и связан с отслеживанием событий.

В Excel я использую этот код:

If Not Intersect(Target, Sh.Range("$A$1:$A$300")) Is Nothing sub_do_something()

Здесь, Target - адрес выбранной ячейки, Пересечь определяет, принадлежит ли ячейка к указанному диапазону.

Я использую его в системе для заполнения и расчета стоимости проекта.

Пользователь щелкает строку в определенном разделе шаблона расчета. Сценарий определяет адрес выбранной ячейки и переключает пользователя на конкретный лист каталога. Далее пользователь нажимает на нужную строку каталога, скрипт копирует определенный диапазон ячеек в строке и возвращает пользователя обратно в расчет. Когда это происходит, скопированные данные вставляются в диапазон ячеек, начиная с выбранной.

Таким образом, создание расчета, в котором может быть более 100 позиций, значительно упрощается.

В Excel все работает отлично, но вскоре я планирую перенести этот проект в облачный сервис, и Google Sheets - лучший вариант.

Увы, только некоторые события могут отслеживаться в GAS, например, с помощью триггеров onOpen или onEdit. В Excel гораздо больше отслеживается событий .

После поиска в StackOverflow я обнаружил несколько похожих проблем, связанных с трассировкой событий, например, Как найти курсор пользователя в сценарии с привязкой к документу , Можем ли мы реализовать некоторый код что срабатывает при выборе чего-либо в документе Google? , Выбранные диапазоны электронных таблиц монитора приложений Google .

Из ответов на эти вопросы ясно, что в GAS нет такого простого решения, как Intersect (Target, Range) в Excel. В последнем примере используется боковое меню, запускается из него скрипт, который запрашивает лист 5 раз в секунду и отображает адрес активной ячейки в поле «data».

К сожалению, этот код не работает для меня. В отладчике функция getActiveRange () работает нормально, но этот код не работает:

$(document).ready(() => {
   setInterval(()=>{
   google.script.run.withSuccessHandler(log).getActiveRange();
   },200)    
  })       
  log(e) => {
    $('#data').val(e)
  }

Вопрос.

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

Ответы [ 2 ]

0 голосов
/ 09 января 2019

пересечение двух рядов

Вы можете использовать это для расчета пересечения двух диапазонов. Требуется объект в виде: {rg1:'A1Notation String',rg2:'A1Notation String'}

function calculateIntersection1(rgObj) {
  var iObj={};
  var ss=SpreadsheetApp.getActive();
  var sh=ss.getActiveSheet();
  var rg1=sh.getRange(rgObj.rg1);
  var rg2=sh.getRange(rgObj.rg2);
  var iObj={rg1colst:rg1.getColumn(),rg1colen:rg1.getColumn()+rg1.getWidth()-1,rg1rowst:rg1.getRow(),rg1rowen:rg1.getRow()+rg1.getHeight()-1,rg2colst:rg2.getColumn(),rg2colen:rg2.getColumn()+rg2.getWidth()-1,rg2rowst:rg2.getRow(),rg2rowen:rg2.getRow()+rg2.getHeight()-1};
  if(iObj.rg1colst>iObj.rg2colen || iObj.rg1colen<iObj.rg2colst || iObj.rg1rowst>iObj.rg2rowen || iObj.rg1rowen<iObj.rg2rowst || iObj.rg2colst>iObj.rg1colen || iObj.rg2colen<iObj.rg1colst || iObj.rg2rowst>iObj.rg1rowen || iObj.rg2rowen<iObj.rg1rowst) {
    return '<h1>No intersecting cells</h1>';
  }else{
    var vA1=rg1.getValues();
    var v1=[];
    var vA2=rg2.getValues();
    var v2=[];
    for(var i=0;i<vA1.length;i++){
      for(var j=0;j<vA1[i].length;j++){
        var s=Utilities.formatString('(%s,%s)', iObj.rg1rowst+i,iObj.rg1colst+j);
        v1.push(s);
      }
    }
    for(var i=0;i<vA2.length;i++){
      for(var j=0;j<vA2[i].length;j++){
        var s=Utilities.formatString('(%s,%s)', iObj.rg2rowst+i,iObj.rg2colst+j);
        v2.push(s);
      }
    }
    var oA=[];
    for(var i=0;i<v1.length;i++){
      var idx=v2.indexOf(v1[i]);
      if(idx>-1){
        oA.push(v2[idx]);
      }
    }
    return Utilities.formatString('Intersecting Cells: %s', oA.join(', '));
  }
}

Возвращается либо строка «Нет пересекающихся ячеек», либо строка, идентифицирующая пересекающиеся ячейки в формате (row, column).

0 голосов
/ 09 января 2019

Вот идея. Я не могу заставить его работать, хотя.

Может быть, кто-то другой может дать лучший ответ.

Кроме того, функции, работающие в режиме 24/7, невозможны с GAS, я думаю, поскольку существуют ограничения на общее время выполнения. Возможно, вы захотите добавить средство защиты кода, которое выходит из сценария, если время последнего обновления превышает 10 минут назад или что-то в этом роде.

function checkSelection() {

    var spreadsheet = SpreadsheetApp.getActive();
    var targetRange = spreadsheet.getRange('activate');
    // Change your named ranged name here

    var tCol = targetRange.getColumn();
    var tLastCol = targetRange.getLastColumn();
    var tRow = targetRange.getRow();
    var tLastRow = targetRange.getLastRow();

    var num = 0;

    for (num; num < 115; ++num) {
    // Repeats the code below 100 times

        var range = spreadsheet.getActiveRange();
        var row = range.getRow();
        var col = range.getColumn();

        if (col >= tCol && col <= tLastCol && row >= tRow && row <= tLastRow) {
            range.setBackground('#000000');
            // Change the code in this block to your code.
        }

        SpreadsheetApp.flush();
        Utilities.sleep(500);
        // Waits half a second before repeating
    }
}

115 повторений * Кажется, что ожидание 500 мс длится почти минуту, затем триггер снова запустит всю функцию.

Screenshot of executions

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