Устранение ошибки в цикле, когда в столбце отсутствуют значения

#google-apps-script #google-sheets

Вопрос:

 function soccerway() {
  var sh = SpreadsheetApp.getActiveSpreadsheet();
  var ss = sh.getSheetByName("Soccerway");
  
  if (ss.getRange("A2").getValues()[0][0] ==  "ATIVO") {
    var range;
    range = ss.getRange('F2:F31');
    var loop = range.getValues().flat().filter(e => e);
    var column = ss.getRange('H2:H');
    var values = column.getValues();
    var ct = 0;
    while (values[ct] amp;amp; values[ct][0] != "") {
      ct  ;
    }
    var valueArr = [];
    if(ct > 0){
      for (var key of loop) {
      var data = [[key,]]
      var contentText = UrlFetchApp.fetch(key).getContentText();
      var $ = Cheerio.load(contentText);
      var ElementSelect = $('#page_match_1_block_match_info_5 > div > div > div.container.left > a.team-title');
      var ElementSelect2 = $('#page_match_1_block_match_info_5 > div > div > div.container.right > a.team-title');
      var data1 = ElementSelect.text().trim()   'amp;amp;amp;amp;amp;'   ElementSelect.attr('href');
      var data2 = ElementSelect2.text().trim()   'amp;amp;amp;amp;amp;'   ElementSelect2.attr('href');
      valueArr.push([key, data1, data2]);
      }
    }
    ss.getRange(ct 2, 8, valueArr.length, 3).setValues(valueArr);
  }
}
 

Дело в том , что при отсутствии значений Column H код выдаст ошибку, поскольку line 29 количество строк в диапазоне должно быть не менее 1, но при использовании:

 try {

} catch(e) {

}
 

Это сделало бы код очень большим и повторяющимся, потому что мне нужно было бы переписать все шаги внутри, чтобы catch(e) .

Есть ли другой более простой и быстрый способ, которым я могу воспользоваться?

Моя электронная таблица и сценарий:
https://docs.google.com/spreadsheets/d/1kXC-aQEViFmL0KC-UG0YEpjmJq69gpSeH3HbbSetI4M/edit?usp=sharing

Дополнительная информация:

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

Комментарии:

1. Хотя я не уверен, смогу ли я правильно понять вашу ситуацию, в вашем сценарии, как насчет включения s.getRange(ct 2, 8, valueArr.length, 3).setValues(valueArr); цикла after for в оператор if if (ct > 0){} ? Я думал , что когда ct > 0 есть false , valueArr то есть [] . Я подумал, что это может быть причиной вашей проблемы.

2. Привет @Tanaike я добавляю ссылку на электронную таблицу и скрипт

Ответ №1:

Я предполагаю, что в вашей электронной таблице каждая ячейка F2:F31 либо имеет URL-адрес, либо пуста. В ячейках H2:H у вас есть значение или нет, и на основе этого вы хотите запустить функцию для всех строк, в которых столбец H содержит значение.

Следующий код выводит следующее (из API)

  • Col H = url-адрес
  • Col I = команда 1 (отформатирована в соответствии с вашим кодом)
  • Col I = команда 1 (отформатирована в соответствии с вашим кодом)
  • Col K = статус (на основе текущего выполнения функции)

Вы можете упростить свой код,:

 function getTeams(){
  var sh = SpreadsheetApp.getActiveSpreadsheet();
  var ss = sh.getSheetByName("Soccerway");

  // stop the function here if A2 is not ATIVO
  if( ss.getRange("A2").getValue() !=  "ATIVO" ) return

  const sourceRange = ss.getRange("F2:F31")
  const sourceVals = sourceRange.getValues()
  let startRow = 2


  // Run through each existing row / link
  sourceVals.forEach( (row, index) => {

    // Url is in Column A
    const url = row[0]

    // Current row number to output to
    const rowNum = startRow index

    // Output will be in columns H:K
    const targetRange = ss.getRange( rowNum, 8, 1, 3)

    // Status will be ouput to column L
    const statusCell = ss.getRange(rowNum, 11)

    // skip if no url exists
    if( !url ) {
      statusCell.setValue("URL Missing")
      return 
    }

    // skip if values exist already
    let skip = false
    targetRange.getValues().forEach( row => {
      if( row[0] || row[1] ) skip = true
    })
   
    if( skip ){
      statusCell.setValue("Field skipped because values existed already")
      return
    } 

    // call the api
    const dataFromAPI = fetchDataForURL( url )
    
    // skip if no response from api
    if( !dataFromAPI || !dataFromAPI.url  || !dataFromAPI.data1 || !dataFromAPI.data2 ){
      statusCell.setValue("No Data from API")
      return
    } 
   
    // write response to sheet, after column H (I:J) 
    targetRange.setValues( [[dataFromAPI.url, dataFromAPI.data1, dataFromAPI.data2]] )
  });

  function fetchDataForURL( url ) {
    if( !url ) return

    var contentText = UrlFetchApp.fetch( url ).getContentText();
    var $ = Cheerio.load(contentText);
    var ElementSelect = $('#page_match_1_block_match_info_5 > div > div > div.container.left > a.team-title');
    var ElementSelect2 = $('#page_match_1_block_match_info_5 > div > div > div.container.right > a.team-title');
    var data1 = ElementSelect.text().trim()   'amp;amp;amp;amp;amp;'   ElementSelect.attr('href');
    var data2 = ElementSelect2.text().trim()   'amp;amp;amp;amp;amp;'   ElementSelect2.attr('href');
      
    return {
      url: url,
      data1: data1,
      data2: data2
    }
  }
}
// 
 

Комментарии:

1. Привет, приятель @NevenSubotic , прежде всего я хотел бы поблагодарить вас за ваше время и поддержку. Скрипт приложения Google имеет некоторые ограничения в использовании параметров своего кода, в его указании появились некоторые ошибки во время запуска, я добавил в вопрос ссылку на электронную таблицу и доступ к скрипту, чтобы облегчить тесты для тех, кто хочет попытаться решить проблему. В любом случае спасибо за информацию, и я постараюсь отредактировать то, что не сработало, чтобы понять, как мне следует действовать.

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

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

4. @Brondbyесли готово, я добавил чек. Это должно пропустить все строки, в которых есть значение в одной из двух ячеек целевого диапазона

5. Проверьте это сейчас, пожалуйста, я исправил if( !skip ) return , чтобы if( skip ) return