Обновление Dynami c Spreadsheet 'database' из листов со значениями Dynami c - PullRequest
0 голосов
/ 17 июня 2020

У меня два вопроса:

1) Это самый эффективный способ делать то, что я хочу. Думаю, если будет много переменных, это займет много времени? Я не смогу изменить порядок столбцов в целевых данных с течением времени и порядок строк в исходных данных. Исходные данные будут поступать из разных электронных таблиц, и каждая из них будет генерировать / ссылаться на данные в строке в целевых данных.

2) Скрипт работает так, как предполагалось, за исключением одной маленькой детали. Если идентификатор не найден в целевых данных - я не хочу, чтобы отсутствующий идентификатор (и соответствующие данные в строке) добавлялся в целевые данные. И я просто не могу понять, как это сделать.

Я привел ссылки ниже для примера базы данных целевых данных и некоторых примеров исходных данных, включая тот, где идентификатор еще не создан в базе данных.

function toSaesonMulti() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = ss.getSheetByName('Origin Data');

  var dataRange = s.getDataRange().getValues();

  var ssSeason = SpreadsheetApp.openById('1oHR2Iz0cRayVaNISgzw7LA2rcFzuicDjH0C9ZO-QPK0');
  var s1 = ssSeason.getSheetByName('Target Data');
  var lastColumn = s1.getLastColumn();
  var lastRow = s1.getLastRow();

  var dataRangeSeason = s1.getDataRange().getValues();  

   for(var r = 0; r < dataRange.length; r++){
     var header = dataRangeSeason[0].indexOf(dataRange[r][0]);

     //If a column header is missing append insert the header at the end of the sheet
     if(header === -1){
       s1.getRange(1, lastColumn+1).setValue(dataRange[r][0]);
       //Update the variables to include the newly created header
       var lastColumn = s1.getLastColumn();
       var dataRangeSeason = s1.getDataRange().getValues();
     }

     //Define the id to look for
     if(dataRange[r][0] === 'Id'){
       var id = dataRange[r][1];
     }

     //Look for the Id column
     for(var c = 0; c < lastColumn; c++){
       if (dataRangeSeason[0][c] === 'Id'){

         //Look for the row to update
         for (var x = 0 ; x < lastRow ; x++){
           if(dataRangeSeason[x][c] === id){

             for (var y = 0 ; y < lastColumn ; y++){

               //Update the the data in the row matching the same header
               if(dataRange[r][0] === dataRangeSeason[0][y]){
                 s1.getRange(x+1, y+1).setValue(dataRange[r][1]);

               }
             }             
           }
         }
       }               
     }    
   }
}

База данных - Целевые данные

Данные - Исходные данные

Данные - Исходные данные3

Данные - исходные данные2

Данные - исходные данные отсутствуют в базе данных

Ответы [ 2 ]

0 голосов
/ 18 июня 2020

Я видел, что вам удалось решить вашу проблему с добавлением строки.

Прежде всего, использование электронных таблиц в качестве базы данных - не лучшая идея, есть несколько сервисов, которые подходят лучше. Даже в экосистеме Google:

Но говоря что вы по какой-то причине хотите придерживаться электронных таблиц. Вам следует попытаться иметь более модульный код, поскольку сейчас все выглядит очень запутанным, и наличие трех вложенных for-l oop также не помогает с эффективностью.

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

Это позволило бы избавиться от 1 для l oop, но, конечно, есть хороший шанс, что два других также можно пропустить, используя TextFinder, так как это своего рода работа.

Это изменение ускорит ваш код и, что более важно, упростит его понимание и понимание. Вы также можете сделать каждый l oop функцией, например, checkingForId(), checkingForRow(), updateCell(), et c.


Также кажется, что вы объявляете переменные более одного раза . Я не уверен, что это вызовет какие-то ошибки, но точно сбивает с толку. Попробуйте объявить переменные только один раз. Например:

    if(rowIndex < 0){
      s1.getRange(lastRow+1, headerIdColumn+1).setValue(idValue)
      var dataRangeSeason = s1.getDataRange().getValues();
      var lastRow = s1.getLastRow();
    }

Здесь вам не нужно использовать ключевое слово var, поскольку две переменные (dataRangeSeason и lastRow) уже были объявлены ранее. Добавление var просто приведет в замешательство других людей (или даже вас в будущем), смотрящих на этот код.

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


Хотя я пытался дать вам несколько подсказок, учтите, что переполнение стека - не место для публикации вашего кода за то, что он "проверил" или улучшил. Для этой цели существует еще одна страница стека под названием Code Review .

0 голосов
/ 17 июня 2020

Я нашел решение, которое делает свою работу. Но я не уверен, что это лучший и быстрый способ. Если у вас есть предложения, как его оптимизировать, я все слышу. Сейчас создание / обновление новой строки занимает 2,5 секунды.

function toSaesonMulti2() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = ss.getSheetByName('Origin Data');

  var dataRange = s.getDataRange().getValues();

  var ssSeason = SpreadsheetApp.openById('1oHR2Iz0cRayVaNISgzw7LA2rcFzuicDjH0C9ZO-QPK0');
  var s1 = ssSeason.getSheetByName('Target Data');
  var lastColumn = s1.getLastColumn();
  var lastRow = s1.getLastRow();

  var dataRangeSeason = s1.getDataRange().getValues();

  //Find the column of Id
  var headerIdColumn = dataRangeSeason[0].indexOf("Id");
  var ids = s1.getRange(1, headerIdColumn+1, lastRow,1).getValues().toString();

  for(var i = 0; i < s.getDataRange().getLastRow(); i++){
    if(dataRange[i][0] === "Id"){
      var idRow = i;
      var idValue = s.getRange(idRow+1,2).getValue();
    }
  }


  //Find the row in the target, if it's not there create it
  var rowIndex = ids.indexOf(idValue)  

    if(rowIndex < 0){
      s1.getRange(lastRow+1, headerIdColumn+1).setValue(idValue)
      var dataRangeSeason = s1.getDataRange().getValues();
      var lastRow = s1.getLastRow();
    }

    for(var r = 0; r < dataRange.length; r++){
      var header = dataRangeSeason[0].indexOf(dataRange[r][0]);

      //If a column header is missing append insert the header at the end of the sheet
      if(header === -1){
        s1.getRange(1, lastColumn+1).setValue(dataRange[r][0]);
        //Update the variables to include the newly created header
        var lastColumn = s1.getLastColumn();
        var dataRangeSeason = s1.getDataRange().getValues();
      }

      //Look for the row to update
      for (var x = 0 ; x < lastRow ; x++){
        if(dataRangeSeason[x][headerIdColumn] === idValue){

          for (var y = 0 ; y < lastColumn ; y++){

            if(dataRange[r][0] === dataRangeSeason[0][y]){
              s1.getRange(x+1, y+1).setValue(dataRange[r][1]);
            }
          }
        }
      }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...