Как расширить или уменьшить формулы в зависимости от содержимого ячейки - PullRequest
1 голос
/ 13 июня 2019

У меня есть стол, состоящий из нескольких листов. Таблица должна обрабатываться ежедневно несколькими пользователями одновременно. Основное редактирование выполняется в Sheet1. Лист 2 состоит только из запроса и формул.

Пример листа 1:

  • Лист 1 состоит из 2500 строк и 17 столбцов.

Начиная со строки 12 (строка 11 является строкой заголовка. Вышеприведенные строки содержат ссылки на формулы), столбцы A, B заполняются пользователем. Столбцы C-H содержат различные формулы (например, запросы GoogleFinance). Столбцы G-M должны быть снова заполнены пользователем. Наконец, в столбцах N-Q снова есть формулы.

Цель: автоматическое расширение / удаление формул в столбцах CH и NQ в зависимости от того, был ли контент добавлен / удален в столбцах A и B. Процесс удаления должен выполняться построчно, чтобы также удалить оставшийся пользовательский контент в столбцах GM.

Лист также можно сортировать.

Пример листа 2:

  • Лист 2 состоит из 1500 строк и 11 столбцов.

Начиная со строки 9 (строка 9 также является строкой заголовка. Строки выше содержат ссылки на формулы), столбцы A-I заполняются результатами запроса (который находится в ячейке A9). Запрос получает определенное содержимое из листа 1 и является динамическим. Столбцы J-K содержат формулы.

Цель: автоматически расширять / удалять формулы в столбцах J-K в зависимости от того, был ли контент добавлен / удален в столбцах A-I (по запросу).

Для расширения, удаления и сортировки я использовал приведенные ниже примеры кода.

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

function fillDownFormulaTD(){

  Sheet = "sheet1";

  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(Sheet);
  var lr = ss.getLastRow();
  var Rng1 = ss.getRange(1, 2, lr-1);

  ss.getRange("").setFormula('');
  ss.getRange("").copyTo(Rng1);         
}

function removeEmptyRows(){    
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Ticker-Datenbank');
  var maxRows = sheet.getMaxRows(); 
  var lastRow = sheet.getLastRow();

  sheet.deleteRows(lastRow+1, maxRows-lastRow-20);            
}

function Sortieren(){

  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.getRange('A11:Q11')
  var currentCell = spreadsheet.getCurrentCell();
  spreadsheet.getSelection().getNextDataRange(SpreadsheetApp.Direction.DOWN).activate();
  currentCell.activateAsCurrentCell();
  spreadsheet.getActiveRange().sort({column: 3, ascending: true});
  spreadsheet.getRange('A11').activate();
 }

1 Ответ

1 голос
/ 23 июня 2019

Это быстрое решение для Sheet2 (ответ для Sheet # 1 находится в разработке).

Для Sheet2, вместо того, чтобы вручную заполнять каждую строку столбцов J и I формулой, используйте формулу массива, котораябудет автоматически расширяться / сокращаться в соответствии со строками с данными.

  1. Удалить ВСЕ формулы (пустые и непустые ячейки) для каждой строки> 9 в столбце J и столбце I.
  2. В ячейке J10 вставить эту формулу
    =arrayformula(IF($C10:$C="";"";HYPERLINK($J$1&$A10:$A&$J$2&$B10:$B;$J$3)))
  3. В ячейку I10 вставьте эту формулу
    =arrayformula(IFERROR(VLOOKUP($C10:$C;'Geprüfte Ticker'!$C:$P;14;FALSE);""))

Этот код относится к сценарию Лист1 .

Код технически точен и будет работать, но ОП может пожелать рассмотреть две другие проблемы.

  1. Электронная таблица "обрабатывается ежедневно несколькими пользователями одновременно».Существует риск того, что пустая ячейка, обнаруженная в столбце A или столбце B и являющаяся индикатором для удаления строки while, является только временной - пользователь может намереваться исправить орфографию или ввести новые данные.«Идеальным» основанием для удаления строки будет обнаружение пустой ячейки в столбце A ** и ** в столбце B, но это не всегда возможно.

  2. Даже только стестовые данные, время пересчета для электронной таблицы велико - @around 10+ секунд - время для активной электронной таблицы неизвестно.Неизвестно, как этот код повлияет на пересчет.


    function onEdit(e) {
      // setup spreadsheet and sheet
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var tsName = "onedittest";
      var targetsheet = ss.getSheetByName(tsName);

      // list event data
      // Logger.log(JSON.stringify(e)); //DEBUG

      //get the formukla ranges and formulas
      // set 1 = Column C-H
      // set 2 = Column N-P
      // Column Q = arrayformula - leave as is
      var rR1 = targetsheet.getRange("C12:H12");
      var fR1 = rR1.getFormulasR1C1();
      var rR2 = targetsheet.getRange("N12:P12");
      var fR2 = rR2.getFormulasR1C1();

      // collect event data
      var editR = e.range.getRow();
      var editRS = e.range.rowStart;
      var editRE = e.range.rowEnd;
      var editC = e.range.getColumn();
      var editCS = e.range.columnStart;
      var editCE = e.range.columnEnd;
      //Logger.log("DEBUG: edited rowstart = "+editRS+", rowend = "+editRE+", columnstart = "+editCS+", columnend = "+editCE);
      //Logger.log("DEBUG: edited row = "+editR+", edited column = "+editC);

      var editedsheet = e.range.getSheet().getSheetName();
      // Logger.log("DEBUG: sheet name = "+editedsheet);

      if (editedsheet === tsName  && editC>= 1 && editC<= 2 && editR>12) {

        // this range/cell is a trigger
        // Logger.log("DEBUG: match");
        var editCell = targetsheet.getRange(editRS, editCS);
        // Logger.log("DEBUG: the edited cell is "+editCell.getA1Notation());
        //Logger.log("DEBUG: the old value = "+e.oldValue+", and the new value = "+e.value);

        //now split Logic#1 and Logic#2
        // Logic#1 = AND there is data in the edited cell (that is, the edit did not make the cell blank), 
        // then copy (or recopy) the formulas from row 12 Columns C-H and N-Q onto the edited row.
        if (editCell.length !=0){
          // copy formulas
          // Logger.log("DEBUG: copy the formulas");
          var formulaset1 = targetsheet.getRange(editRS,3,1,6);
          formulaset1.setFormulasR1C1(fR1);  
          // Logger.log("DEBUG: set formulas for range 1")
          var formulaset2 = targetsheet.getRange(editRS,14,1,3);
          formulaset2.setFormulasR1C1(fR2);  
          // Logger.log("DEBUG: set formulas for range 2")

// Sort the data
      // get the number of rows of data
      var lastheaderRow = 11;
      var Avals = ss.getRange("A12:A").getValues();
      var Alast = Avals.filter(String).length;
      //Logger.log("DEBUG: Number of rows of data = "+Alast+", so last row = "+(Alast+lastheaderRow));

      // define the sort range
      var sortRange = targetsheet.getRange(lastheaderRow, 1, Alast+1, 17);
      // Logger.log("DEBUG: the range = "+range.getA1Notation());

      // sort by Column C, ascending
      sortRange.sort({column: 3, ascending: true});

          }
          else{
            // Logic#2 - delete the row
            // Logger.log("DEBUG: delete the row");
            targetsheet.deleteRow(editRS);
          }      
      }
      else
      {
        //not the right sheet, not the column, not the right row
        // Logger.log("DEBUG: do nothing - not matched");    
      }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...