Как мне сделать этот офисный скрипт быстрее?

Как я могу сделать этот рекурсивный скрипт быстрее? RNumber в этом коде вычисляется в электронной таблице по формуле и проверяется после каждой итерации.

Обычно я выполняю итерацию от чисел> 50000, и сценарий выполняется очень-очень медленно. В результате я добавил шаг переменной итерации, но он не идеален и по-прежнему не работает быстро.

Был бы очень признателен за помощь!



async function findMaxDrawdown(context: Excel.RequestContext, currentMonth: number ) {
  var maxAvailableMonth;
  var monthsCount;
  var monthsRange; 
  var dscrThreshold = context.workbook.worksheets.getItem("DDSHEET1").getRange("B14");
  await context.sync();
  const end = 0;
  var finalTestVariable = context.workbook.worksheets.getItem("DDSHEET2").getRange("B16")
  var precisionFactor = context.workbook.worksheets.getItem("DDSHEET1").getRange("B18");
  numberMonths = context.workbook.worksheets.getItem("DDSHEET1").getRange("B17")
  months.load("values");
  precisionFactor.load("values");
  finalTestVariable.load("values");
  dscrThreshold.load("values");
  numberMonths.load("values");
  await context.sync();
  maxAvailableMonth = months.values[0][currentMonth - 1];
  monthsCount = context.workbook.worksheets.getItem("DDSHEET1").getRange("B17");
  monthsCount.load("values");
  await context.sync();
  console.log(currentMonth)
  for (let i = maxAvailableMonth; i > -1; i-= precisionFactor.values[0][0]) {
    if (currentMonth < numberMonths.values[0][0]-1) {
      if( i < precisionFactor.values[0][0]){
        i = 0
      } 
    }
    
    context.workbook.worksheets.getItem("DDSHEET2").getRange("D2").getOffsetRange(1, currentMonth).values = [
      [i]
    ];
    await context.sync();
    var currentMonthRNumber = context.workbook.worksheets.getItem("DDSHEET2").getRange("D2").getOffsetRange(2, currentMonth);
    currentMonthRNumber.load("values");
    await context.sync();
    if (currentMonthRNumber.values[0][0] >= rNumberThreshold.values[0][0]) {
      if (currentMonth == monthsCount.values) 
      {
        return; 
      } 
      else 
      {
        await findMaxDrawdown(context, currentMonth + 1);
        var finalTest = context.workbook.worksheets.getItem("DDSHEET2").getRange("D2").getOffsetRange(1, currentMonth + 1); 
        finalTest.load("values");
        await context.sync();
        finalTestVariable.load("values")
        await context.sync();
        if (finalTest.values[0][0] == finalTestVariable.values[0][0]){
          continue
        } else{
          if (finalTest.values[0][0] > finalTestVariable.values[0][0]) {
            return;
          }
          else {
          }
        }
        break 
        }
    } 
    else 
    {
      continue;
    }
    
  }
}

1 ответ

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

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

б. Вы читаете внутри цикла и выполняете целую кучуcontext.sync(). Каждый раз, когда вы это делаете, это будет приводить к обмену данными с сервером Excel и вызывать много задержек. Вы должны попытаться прочитать все, что хотите, заранее и выполнять обработку данных только внутри цикла. В конце цикла вы можете делать обновления иcontext.sync() чтобы сохранить обновления.

Если вам нужна дополнительная помощь, отправьте нам отзыв с помощью ссылки "помогите улучшить офис" в нижней части веб-страницы Excel и укажите свой адрес электронной почты. Или опубликуйте упрощенную версию сценария, которую легче читать / понимать.

Другие вопросы по тегам