#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 в оператор ifif (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