Я написал сценарий (ниже) пару лет назад (с тех пор не занимался кодированием - так что есть изрядное количество или ржавчина; D), где ResultSet теперь превышает 4000 записей, чего не ожидалось, когда сценарий был написан. Ошибка ниже:
{"type":"error.SuiteScriptError","name":"SSS_SEARCH_FOR_EACH_LIMIT_EXCEEDED","message":"No more than 4000 search results may be returned at one time from nlobjSearchResultSet.forEachResult(callback). Please revise your search criteria or modify the callback logic so that no more than 4000 results are returned."...
Наилучший способ исправить это - использовать другую технику (например, Map / Reduce - которую я должен был бы изучить сейчас), или есть способ отфильтровать поиск, чтобы из поиска возвращалось только определенное количество результатов и остальные записи возвращаются / обрабатываются при последующем выполнении?
Спасибо
//...
invoiceSearch.run().each(function(result) {
// ensure script usage okay
if (usageOkay()) {
entityID = result.getValue({
'name': 'internalid',
'join': 'customer',
'summary': search.Summary.GROUP
});
var maxAmountCustomerRecord = result.getValue({
'name': 'custentity_amount_maxorder_2years',
'join': 'customer',
'summary': search.Summary.GROUP
});
var maxAmountCalculated = result.getValue({
'name': 'formulacurrency',
'formula': 'CASE WHEN {closedate} >= ADD_MONTHS(SYSDATE, -(12 * 2)) THEN {amount} ELSE NULL END',
'summary': search.Summary.MAX
});
// in case the calculated amount is null then make it 0
maxAmountCalculated = maxAmountCalculated || 0.0;
// Only write to the customer record when a change is required
if (maxAmountCustomerRecord != maxAmountCalculated) {
updateRecord(entityID, maxAmountCalculated);
log.debug('Updating customer with entityID: ' + entityID + ', to maxAmount: ' +
maxAmountCalculated + ', from previous value of ' + maxAmountCustomerRecord);
}
return true;
}
else {
// If remaining script usage low, reschedule script
rescheduleScript(entityID);
}
});
//....


![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Моя рекомендация и, возможно, лучший способ массовой обработки в SuiteScript 2.0 - использовать Map / Reduce, а не Scheduled Script. С ними, безусловно, нужно научиться, но они чрезвычайно эффективны.
Быстрые подсказки будут:
getInputData может просто создать / загрузить все, что есть invoiceSearch в существующем скрипте, и вернуть его.reduce будет фактически внутренностями вашего утверждения if.Надеюсь, это должно быть довольно простое преобразование.
Хотя Эрик отвечает так, как я бы, наверное, пошел, иногда нужно делать запланированный сценарий. И, конечно же, в этом случае, если вы думаете, что проработаете все элементы за день запланированных запусков, то простое решение:
var count = 0;
invoiceSearch.run().each(function(result) {
count++;
if (count == 4000) return false;
if (usageOk(){
...
return true;
}else{
rescheduleScript(entityID);
return false; // end the each and you may never hit 4k anyway
}
});
Мне лично нравится генерировать полный поиск, а затем анализировать его оттуда:
Я использую эту функцию с любым поисковым объектом для компиляции результатов блоками по 1000:
function getAllResults(s) {
var results = s.run();
var searchResults = [];
var searchid = 0;
do {
var resultslice = results.getRange({start:searchid,end:searchid+1000});
resultslice.forEach(function(slice) {
searchResults.push(slice);
searchid++;
}
);
} while (resultslice.length >=1000);
return searchResults;
}
Затем, когда я захочу обработать любой поиск, например:
var mySearch = search.create({
type:'invoice',
columns: [
{name: 'tranid'},
{name: 'trandate'},
{name: 'entity', sort: (params.consolidated)?search.Sort.ASC:undefined },
{name: 'parent',join:'customer', sort: (!params.consolidated)?search.Sort.ASC:undefined},
{name: 'terms'},
{name: 'currency'},
{name: 'amount'},
{name: 'amountremaining'},
{name: 'fxamount'},
{name: 'fxamountremaining'},
],
filters: [
{name: 'mainline', operator:'is',values:['T']},
{name: 'trandate', operator:'onorbefore', values: [params.startDate] }
]
});
var myResults = getAllResults(mySearch );
myResults.forEach(function(result) {
//... do stuff with each result
});
Я использовал это с хорошими результатами для наборов данных, превышающих 20 000 записей.