Разбей эту функцию скрипта Google Apps на несколько функций:

function updateAllStats() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('db'); // Получаем лист с названием 'db'
  const headerRow = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
  
  // Получаем индексы столбцов по названиям
  const columnIndices = {
    name: headerRow.indexOf('name') + 1,
    gameVer: headerRow.indexOf('gameVer') + 1,
    modrinthId: headerRow.indexOf('modrinthId') + 1,
    curseforgeId: headerRow.indexOf('curseforgeId') + 1,
    follows: headerRow.indexOf('follows') + 1,
    mrDownloads: headerRow.indexOf('mrDownloads') + 1,
    cfDownloads: headerRow.indexOf('cfDownloads') + 1,
    popularity: headerRow.indexOf('popularity') + 1,
    actualModVer: headerRow.indexOf('actualModVer') + 1
  };

  const lastRow = sheet.getLastRow();
  
  for (let row = 2; row <= lastRow; row++) {
    const name = sheet.getRange(row, columnIndices.name).getValue();
    const modrinthId = sheet.getRange(row, columnIndices.modrinthId).getValue();
    const curseforgeId = sheet.getRange(row, columnIndices.curseforgeId).getValue();
    const gameVer = sheet.getRange(row, columnIndices.gameVer).getValue();

    Logger.log(`Начинаю обработку строки ${row} с идентификатором Modrinth ${modrinthId}, идентификатором CurseForge ${curseforgeId} и версией игры ${gameVer}.`);

    if ((modrinthId === false || modrinthId === "FALSE") && (curseforgeId === false || curseforgeId === "FALSE")) {
      Logger.log(`Пропускаю строку ${row} мода «${name}», ибо оба идентификатора FALSE`);
      continue;
    }

    let follows = sheet.getRange(row, columnIndices.follows).getValue() || 0;
    let mrDownloads = sheet.getRange(row, columnIndices.mrDownloads).getValue() || 0;
    let cfDownloads = sheet.getRange(row, columnIndices.cfDownloads).getValue() || 0;
    let actualModVer = ''; // Инициализируем переменную для actualModVer

    let modrinthSuccess = false; // Флаг успешности получения данных с Modrinth

    // Попытка получить данные с Modrinth
    if (modrinthId && modrinthId !== false && modrinthId !== "FALSE") {
      const modrinthData = fetchModrinthStats(modrinthId, gameVer);
      if (modrinthData && modrinthData.latestVersion) {
        modrinthSuccess = true;
        if (modrinthData.followersCount > 0) {
          follows = modrinthData.followersCount;
        }
        if (modrinthData.downloadsCount > 0) {
          mrDownloads = modrinthData.downloadsCount;
        }
        if (modrinthData.latestVersion) {
          actualModVer = modrinthData.latestVersion;
        }
        Logger.log(`Данные «${name}» с Modrinth: ${modrinthData.followersCount} подписчиков, ${modrinthData.downloadsCount} скачиваний, последняя версия — «${modrinthData.latestVersion}».`);
      } else {
        Logger.log(`На Modrinth не найдено подходящей версии ««${name}» (${modrinthId}) для версии игры ${gameVer}.`);
      }
    }
    
    // Если данные с Modrinth не получены, пытаемся получить данные с CurseForge
    if (!modrinthSuccess && curseforgeId && curseforgeId !== false && curseforgeId !== "FALSE") {
      const cfData = fetchCurseForgeMod(curseforgeId, gameVer);
      Logger.log('cfData: ', cfData);
      if (cfData) {
        if (cfData.downloadCount > 0) {
          cfDownloads = cfData.downloadCount;
        }
        if (cfData.latestVersion) {
          actualModVer = cfData.latestVersion;
        }
        Logger.log(`CurseForge data for ID ${curseforgeId}: Downloads = ${cfData.downloadCount}, Latest Version = ${cfData.latestVersion}`);
      } else {
        Logger.log(`No suitable version found on CurseForge for mod ID ${curseforgeId} and game version ${gameVer}`);
      }
    }

    // Пример обновления логарифмической шкалы для скачиваний
    const logFollows = Math.log(follows + 1);    // +1 для избежания log(0)
    const logMrDownloads = Math.log(mrDownloads + 1);
    const logCfDownloads = Math.log(cfDownloads + 1);

    // Обновляем значения в таблице
    sheet.getRange(row, columnIndices.mrDownloads).setValue(mrDownloads);
    sheet.getRange(row, columnIndices.follows).setValue(follows); 
    sheet.getRange(row, columnIndices.cfDownloads).setValue(cfDownloads);
    sheet.getRange(row, columnIndices.actualModVer).setValue(actualModVer); // Устанавливаем actualModVer

    // Применение корректирующего множителя для скачиваний
    const cfWeight = cfDownloads >= 1000000 ? 1.5 : 1;  // Добавляем больший вес скачиваниям более 1 млн
    const mrWeight = mrDownloads >= 1000000 ? 1.5 : 1;  // То же самое для Modrinth скачиваний

    // Усреднённое значение с корректировкой
    let popularity = 0;
    if (follows > 0 || mrDownloads > 0 || cfDownloads > 0) {
      const values = [logFollows, logMrDownloads * mrWeight, logCfDownloads * cfWeight].filter(value => value > 0);
      popularity = values.reduce((acc, val) => acc + val, 0) / values.length;
    }
    
    Logger.log(`Calculated popularity for row ${row}: ${popularity}`);
    sheet.getRange(row, columnIndices.popularity).setValue(popularity);
  }

  sortByColumns(sheet, columnIndices.popularity, columnIndices.name);
}