Google Apps脚本-调用运行时确定的函数的最快处理方式

时间:2019-05-13 15:11:44

标签: javascript google-apps-script function-call

我有一个程序可以解析网站上的游戏数据,以帮助我更好地组织游戏中的角色。这些字符具有很多属性,尽管我很少改变,一旦我从网站上获取了它们的信息后就不需要去更新它们。

在该站点上,各种重要信息分散在许多不同的表中。当我测试特定表的逻辑时,我需要一种将变量传递到函数中的方法,因此我具有包装函数。

最终,我最终需要遍历URL,并将一些信息传递给专门读取页面并提取数据的函数。我正在缓存这些页面,以免每次都不得不阅读它们。

到目前为止,我有3种选择的方法...但是我本身并不喜欢它们中的任何一个:

1:将循环完全放在每个包装函数中:

var URLSheet = activeSpreadsheet.getSheetByName(URLSheetName);
var URLRowLength = lastRow - startRow + 1;
var URLRange = URLSheet.getRange(startRow,2,URLRowLength,1); 
var URLArray = URLRange.getValues();
var crewPackage = new CrewPointers(startRow, "placeholder", "Crew-List", startRow);

function readCrewTraits() {
  for(var i = 0; i < URLRowLength; i++) {
    var url = fixURL(URLArray[i][0]);
    crewPackage.URL = url;
    readCrewTraitsPage(crewPackage);
    crewPackage.Row++;
    crewPackage.iterateCache();
  }
}

function readCrewSkills() {
  for(var i = 0; i < URLRowLength; i++) {
    var url = fixURL(URLArray[i][0]);
    crewPackage.URL = url;
    readCrewSkillsPage(crewPackage);
    crewPackage.Row++;
    crewPackage.iterateCache();
  }
}

2:具有只将一个变量传递给另一个包装器函数的包装器函数,该包装器包含单个循环和一个开关盒,该开关盒根据传递给它的数据选择要调用的函数。

function readCrewTraits() {
  readURLArray("Trait");
}

function readCrewSkills() {
  readURLArray("Skill");
}

function readURLArray(readType) {
  var URLSheet = activeSpreadsheet.getSheetByName(URLSheetName);
  var URLRowLength = lastRow - startRow + 1;
  var URLRange = URLSheet.getRange(startRow,2,URLRowLength,1); 
  var URLArray = URLRange.getValues();
  var crewPackage = new CrewPointers(startRow, "placeholder", "Crew-List", startRow);
  for(var i = 0; i < URLRowLength; i++) {
    var url = fixURL(URLArray[i][0]);
    crewPackage.URL = url;
    switch(readType) {
      case "Skill":
        readCrewSkillsPage(crewPackage);
        break;
      case "Trait":
        readCrewTraitsPage(crewPackage);
        break;
      default:
        break;
    }
    crewPackage.Row++;
    crewPackage.iterateCache();
  }
}

3:使用eval,据我了解,我永远不应该这样做,并且它最终可能会变得更慢...

function readCrewTraits() {
  readURLArray("readCrewTraitsPage(crewPackage)");
}

function readCrewSkills() {
  readURLArray("readCrewSkillsPage(crewPackage)");
}

function readURLArray(readType) {
  var URLSheet = activeSpreadsheet.getSheetByName(URLSheetName);
  var URLRowLength = lastRow - startRow + 1;
  var URLRange = URLSheet.getRange(startRow,2,URLRowLength,1); 
  var URLArray = URLRange.getValues();
  var crewPackage = new CrewPointers(startRow, "placeholder", "Crew-List", startRow);
  for(var i = 0; i < URLRowLength; i++) {
    var url = fixURL(URLArray[i][0]);
    crewPackage.URL = url;
    eval(readType);
    crewPackage.Row++;
    crewPackage.iterateCache();
  }
}

我想就整体处理时间而言,#1是“最快的”(这件事足够慢,如果我尝试在整个URL数组上运行,它会在大约150行后死掉,因为Google不会运行任何东西那么长),但是还有什么其他方法可以将我的调用组合成一个函数,而这个函数可能比我在这里得到的更好?

我所有的代码(对于Tanaike。)

//Globals and initialize function, which must be called every time to ensure I have the sheets I need.
var traitsSheetName = "Crew_Traits";  
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var traitsSheet = activeSpreadsheet.getSheetByName(traitsSheetName);
var basicsSheetName = "Crew_Basics";
var basicsSheet = activeSpreadsheet.getSheetByName(basicsSheetName);
var URLSheetName = "Crew_URLs";
var URLSheet = activeSpreadsheet.getSheetByName(URLSheetName);
var f1SheetName = "1*";
var f2SheetName = "2*";
var f3SheetName = "3*";
var f4SheetName = "4*";
var f5SheetName = "5*";
var f1Sheet = activeSpreadsheet.getSheetByName(f1SheetName);
var f2Sheet = activeSpreadsheet.getSheetByName(f2SheetName);
var f3Sheet = activeSpreadsheet.getSheetByName(f3SheetName);
var f4Sheet = activeSpreadsheet.getSheetByName(f4SheetName);
var f5Sheet = activeSpreadsheet.getSheetByName(f5SheetName);
var traitArray = [[]];
var f1Array = [[,,,,,,]];
var f2Array = f1Array.slice(0);
var f3Array = f1Array.slice(0);
var f4Array = f1Array.slice(0);
var f5Array = f1Array.slice(0);
var basicsArray = [["","","","","","","","","","","","","",""]];
initialize();
var startRow = 2;
var lastRow  = 12;
//var lastRow = traitsSheet.getLastRow();
var startingTraitCol = 2;
var startingSkillCol = 4;
var startingBaseCol = 1; // 1 less than column number, as this is an array value
var startingProfCol = 2; // 1 less than column number, as this is an array value

function callEraseAllData() {
  eraseAllData(126,22,traitsSheet);
}

function initialize() {
  initializeSheet(traitsSheet,traitsSheetName);
  initializeSheet(URLSheet,URLSheetName);
  initializeSheet(basicsSheet,basicsSheetName);
  initializeSheet(f1Sheet,f1SheetName);
  initializeSheet(f2Sheet,f2SheetName);
  initializeSheet(f3Sheet,f3SheetName);
  initializeSheet(f4Sheet,f4SheetName);
  initializeSheet(f5Sheet,f5SheetName);
}

function initializeSheet(sheet,sheetName) {
  if(sheet == null) { 
    sheet = activeSpreadsheet.insertSheet();
    sheet.setName(sheetName);
    setHeaders(sheet,sheetName);
  }
}

function resizeAllColumns(sheet) {
  sheet.autoResizeColumns(1, sheet.getLastColumn());
  return;
}

function readCrewTraits() {
  fillTraitArray();
  readURLArray("Trait");
  fillPage(traitsSheet,traitArray,1);
}

function readCrewSkills() {
  fillCrewSkillArrayWrapper();
  readURLArray("Skill");
  fillPage(f1Sheet,f1Array);
  fillPage(f2Sheet,f2Array);
  fillPage(f3Sheet,f3Array);
  fillPage(f4Sheet,f4Array);
  fillPage(f5Sheet,f5Array);
  fillPage(basicsSheet,basicsArray);
}

function readURLArray(readType) {
  var URLRowLength = lastRow - startRow + 1;
  var URLRange = URLSheet.getRange(startRow,1,URLRowLength,2); 
  var URLArray = URLRange.getValues();
  var crewPackage = new CrewPointers(startRow, "placeholder", "placeholder", "Crew-List", startRow);
  for(var i = 0; i < URLRowLength; i++) {
    var url = fixURL(URLArray[i][1]);
    crewPackage.URL = url;
    crewPackage.name = URLArray[i][0];
    switch(readType) {
      case "Skill":
        readCrewSkillsPage(crewPackage);
        break;
      case "Trait":
        readCrewTraitsPage(crewPackage);
        break;
      case "Rarity":
        readCrewRaritiesPage(crewPackage);
        break;
      default:
        break;
    }
    crewPackage.Row++;
    crewPackage.iterateCache();
  }
}

function fillTraitArray() {
  var range = traitsSheet.getRange(1,1,traitsSheet.getLastRow(),traitsSheet.getLastColumn());
  traitArray = range.getValues();
  return;
}

function fillCrewSkillArrayWrapper() {
  f1Array = fillCrewSkillArray(f1Sheet);
  f2Array = fillCrewSkillArray(f2Sheet);
  f3Array = fillCrewSkillArray(f3Sheet);
  f4Array = fillCrewSkillArray(f4Sheet);
  f5Array = fillCrewSkillArray(f5Sheet);
  basicsArray = fillCrewSkillArray(basicsSheet);
  return;
}

function fillCrewSkillArray(sheet) {
  var range = sheet.getRange(2,1,sheet.getLastRow(),sheet.getLastColumn());
  return range.getValues();             
}

function searchRows(arrayToSearchWithin, arrayToFind, findType, startingRow) {
  var arrayEnd = arrayToSearchWithin.length;
  var stringToFind = "";
  if (!startingRow) { startingRow = 0 };
  findType = findType.toLowerCase();
  if (findType == "add") { 
    stringToFind = arrayToFind[0];
    while(arrayToFind.length < arrayToSearchWithin[0].length) {
      arrayToFind.push("");
    }
  } else {
    stringToFind = arrayToFind;
  }
  for(var rowCounter = startingRow; rowCounter < arrayEnd; rowCounter++) {
    if (arrayToSearchWithin[rowCounter][0] == stringToFind) {
      if (findType == "add") { 
        arrayToSearchWithin.splice(rowCounter, 1, arrayToFind);
        return rowCounter; 
      }
      return arrayToSearchWithin[rowCounter];
    }
    else if ((!arrayToSearchWithin[rowCounter][0]) || (stringToFind < arrayToSearchWithin[rowCounter][0])) {
      if (findType == "add") {
        arrayToSearchWithin.splice(rowCounter, 0, arrayToFind);
        return rowCounter;
      }
      return arrayToSearchWithin[rowCounter];
    }
  }
  if (findType == "add") {
    arrayToSearchWithin.push(arrayToFind);
    return arrayToSearchWithin.length - 1;
  }
  return -1;
}

function searchColumns(arrayToSearchWithin, stringToFind, findType,
                       findCount, startingColumn) {
  findType = findType.toLowerCase();
  if ((!findCount) || (findType == "add")) { findCount = 1 };
  if (!startingColumn) { startingColumn = 0 };
  if (startingColumn >= arrayToSearchWithin[0].length) { return -1 };
  var rowLength = 1;
  var returnArray = [];
  if (findType == "anywhere") { rowLength = arrayToSearchWithin.length; }
  for(var colCounterOuter = 0; colCounterOuter < rowLength; colCounterOuter++) {
    foundInRowAlready:
    for(var colCounterInner = startingColumn; colCounterInner < arrayToSearchWithin[colCounterOuter].length; colCounterInner++) {
      if (arrayToSearchWithin[colCounterOuter][colCounterInner] == stringToFind) {
        if (findType == "anywhere") { 
          if (findCount < 2) {  //We're only finding once 
            return [colCounterOuter, colCounterInner];  //if we're finding anywhere, 
                            //we need to know what row and what column
          }
          returnArray.push([colCounterOuter,colCounterInner]); // build returnArray
          break foundInRowAlready; // get out of the i loop.
        }
        return colCounterInner;  //if we find the string, we just want to return the column.
      }
      else if ((stringToFind < arrayToSearchWithin[colCounterOuter][colCounterInner]) || 
               (!arrayToSearchWithin[colCounterOuter][colCounterInner])) {
        if (findType == "add") { 
          var arrayEnd = arrayToSearchWithin.length;
          for(var iterateOverAllRows = 1; iterateOverAllRows < arrayEnd; iterateOverAllRows++) {
            arrayToSearchWithin[iterateOverAllRows].splice(colCounterInner, 0, "");
          }
          arrayToSearchWithin[0].splice(colCounterInner, 0, stringToFind);
          return colCounterInner;
        }
      }
    }
    if (findCount < 2) {
      if (findType != "add") { return -1; }
      var arrayEnd = arrayToSearchWithin.length;
      for(var iterateOverAllRows = 1; iterateOverAllRows < arrayEnd; iterateOverAllRows++) {
        arrayToSearchWithin[iterateOverAllRows].push("");
      }
      return arrayToSearchWithin[0].push(stringToFind) - 1;
    }
  }
  return returnArray; 
}

function readCrewTraitsPage(crewPackage) {
  var content = getCacheData(crewPackage.URL, crewPackage.CompleteCacheName);

  var wholePagefromText = 'Traits';
  var wholePagetoText = 'Collections';
  var scraped = Parser
                    .data(content)
                    .from(wholePagefromText)
                    .to(wholePagetoText)
                    .build();

  var fromText = '"Category:';
  var toText = '"';
  var crewTraits = Parser
                     .data(scraped)
                     .from(fromText)
                     .to(toText)
                     .iterate();
  crewTraits.sort();

  var columnIndex = 1;
  var arrayToInsertLater = [crewPackage.name];
  for(var i = 0; i < crewTraits.length; i++) {
    var skillToAdd = fixText(crewTraits[i]);
    columnIndex = searchColumns(traitArray, skillToAdd, 
                  "add", 1, columnIndex);
    for(var j = arrayToInsertLater.length; j < columnIndex; j++) {
      arrayToInsertLater.push("");
    }
    arrayToInsertLater[columnIndex] = skillToAdd;
  }
  var r = searchRows(traitArray, arrayToInsertLater, "add", 1);
}

function readCrewSkillsPage(crewPackage) {
  var content = getCacheData(crewPackage.URL, crewPackage.CompleteCacheName);

  var wholePagefromText = '<td class="ATSLeft';
  var wholePagetoText = '</tr>';
  var scraped = Parser
                    .data(content)
                    .from(wholePagefromText)
                    .to(wholePagetoText)
                    .build();

  var fromText = '"><a href="';
  var toText = '<td class=';
  var skillHeaders = Parser
                     .data(scraped)
                     .from(fromText)
                     .to(toText)
                     //.setLog()
                     .iterate();
  var rarity = skillHeaders.length;
  if (rarity == 1) { skillHeaders[0] = scraped; }

  var fromText = '" title="';
  var toText = '">';
  var crewSkills = Parser
                     .data(skillHeaders[0])
                     .from(fromText)
                     .to(toText)
                     .iterate();
  var skillCount = crewSkills.length;

  var wholePagefromText = '<td class="ATSLeft';
  var wholePagetoText = '</table>';
  var wholeTable = Parser
                    .data(content)
                    .from(wholePagefromText)
                    .to(wholePagetoText)
                    .build();

  var fromText = '<tr style="text-align:center;">';
  var toText = '</tbody>';
  var skillBody = Parser
                     .data(wholeTable)
                     .from(fromText)
                     .to(toText)
                     .setDirection("to")
                     .build();

  var skillArray = skillBody.split('<td class="ATSLeft">');
  var pattern = new RegExp(">([0-9]{1,4})(?=<br)|\\(([0-9]{1,4})|([0-9]{1,4})(?=\\))", "g");
  var writeSheet = traitsSheet;
  var writeArray;
  for (var h = 1; h < skillArray.length; h++) {
    var skillMatch = [[], [], []];
    var i = 0;
    var k = 0;
    while((result = pattern.exec(skillArray[h])) !== null) {
      result.reverse();
      safeLabel:
      for(var j = 0; j < result.length; j++){
        if (result[j]) {
          skillMatch[k][i] = result[j];
          break safeLabel;
        }
      }
      i++;
      if (i===3) {
        i = 0;
        k++;
      }
    }
    switch(h) {
      case 1:
        writeSheet = f1Sheet;
        assignBaseSkills(crewSkills,f1Array,skillMatch,crewPackage.name);
        assignProfSkills(crewSkills,basicsArray,skillMatch,crewPackage,rarity);
        break;
      case 2:
        writeSheet = f2Sheet;
        assignBaseSkills(crewSkills,f2Array,skillMatch,crewPackage.name);
        break;
      case 3:
        writeSheet = f3Sheet;
        assignBaseSkills(crewSkills,f3Array,skillMatch,crewPackage.name);
        break;
      case 4:
        writeSheet = f4Sheet;
        assignBaseSkills(crewSkills,f4Array,skillMatch,crewPackage.name);
        break;
      case 5:
        writeSheet = f5Sheet;
        assignBaseSkills(crewSkills,f5Array,skillMatch,crewPackage.name);
        break;
    }
  }
  return;
}

function fillPage(sheet,dataArray,startingRow) {
  if (!startingRow) { startingRow = 2; }
  eraseAllData(startingRow,1,sheet);
  try {
    rgMyRange = sheet.getRange(startingRow,1,dataArray.length,dataArray[0].length);
    rgMyRange.setValues(dataArray);
  } catch(e) {
    Logger.log("error: " + e);
  }
  resizeAllColumns(sheet);
}

function assignProfSkills(skillNames,targetArray,skillsArray,crewPackage,rarity) {
  var arrayToAdd = ["","","","","","","","","","","","","",""];
  var rangeStart = startingProfCol;
  for(var y = 0; y < skillNames.length; y++) {
    switch(skillNames[y].toLowerCase()) {
      case "command":
        rangeStart = startingProfCol;
        break;
      case "diplomacy":
        rangeStart = startingProfCol + 2;
        break;
      case "engineering":
        rangeStart = startingProfCol + 4;
        break;
      case "security":
        rangeStart = startingProfCol + 6;
        break;
      case "science":
        rangeStart = startingProfCol + 8;
        break;
      case "medicine":
        rangeStart = startingProfCol + 10;
        break;
      default:
        Logger.log("Somehow entered the default path for switch crewSkills: " + skillNames[y]);
        break;
    }
    arrayToAdd[0] = crewPackage.name;
    arrayToAdd[1] = rarity;
    for(var x = 1; x < 3; x++){
      arrayToAdd[rangeStart + x - 1] = skillsArray[y][x];
    }
  }
  var r = searchRows(targetArray,arrayToAdd,"add");
}

function assignBaseSkills(skillNames,targetArray,skillsArray,name) {
  var arrayToAdd = ["","","","","","",""];
  var rangeStart = startingBaseCol;
  for(var z = 0; z < skillNames.length; z++) {
    switch(skillNames[z].toLowerCase()) {
      case "command":
        rangeStart = startingBaseCol;
        break;
      case "diplomacy":
        rangeStart = startingBaseCol + 1;
        break;
      case "engineering":
        rangeStart = startingBaseCol + 2;
        break;
      case "security":
        rangeStart = startingBaseCol + 3;
        break;
      case "science":
        rangeStart = startingBaseCol + 4;
        break;
      case "medicine":
        rangeStart = startingBaseCol + 5;
        break;
      default:
        Logger.log("Somehow entered the default path for switch crewSkills: " + skillNames[z]);
        break;
    }
    arrayToAdd[0] = name;
    arrayToAdd[rangeStart] = skillsArray[z][0];
  }
  var r = searchRows(targetArray,arrayToAdd,"add");
}

function CrewPointers(row, name, url, cacheName, cacheIteration) {  
  const shortCacheName = cacheName;
  this.Row = row;
  this.CacheIteration = cacheIteration;
  this.Name = name;
  this.URL = fixURL(url);

  this.updateCacheName = function () {
    this.CompleteCacheName = shortCacheName + "-Page-" + this.CacheIteration;
  }
  this.updateCacheName();

  this.iterateCache = function() {
    this.CacheIteration += 1;
    this.updateCacheName();
  }
}

function readCrewURLs() {
  var crewURLPackage = new CrewPointers(2, "name", "https://stt.wiki/wiki/Category:Crew", "Category-Crew-List", 1);
  while (readCrewURLPage(crewURLPackage)) {};
}

function readCrewURLPage(crewURLPackage) {
    var content = getCacheData(crewURLPackage.URL, crewURLPackage.CompleteCacheName);

    var wholePagefromText = 'next page';
    var wholePagetoText = '</div></div></div>';
    var scraped = Parser
                    .data(content)
                    .from(wholePagefromText)
                    .to(wholePagetoText)
                    .build();

    var fromText = 'href="';
    var toText = '"';
    var crewURLs = Parser
                     .data(scraped)
                     .from(fromText)
                     .to(toText)
                     .iterate();

    var fromText = 'title="';
    var toText = '">';
    var crewNames = Parser
                     .data(scraped)
                     .from(fromText)
                     .to(toText)
                     .iterate();

    try {
      var values = crewNames.map(function(e, i) {return [fixText(e), crewURLs[i]]});
      rgMyRange = traitsSheet.getRange(crewURLPackage.Row, 1, values.length, values[0].length);
      rgMyRange.setValues(values);
      crewURLPackage.Row = crewURLPackage.Row + values.length;
    } catch(e) { Logger.log(e.toString()) };

    var nextPagefromText = 'previous page';
    var nextPagetoText = 'next page';
    var nextPageScraped = Parser
                    .data(content)
                    .from(nextPagefromText)
                    .to(nextPagetoText)
                    .build();
    var fromText = 'href="';
    var toText = '"';
    var nextPageURL = Parser
                     .data(nextPageScraped)
                     .from(fromText)
                     .to(toText)
                     .build();

    if (nextPageURL.search("/w") !== -1) {
      crewURLPackage.URL = fixURL(nextPageURL);
      crewURLPackage.iterateCache();
      return true;
    }
    return false;
}

function fixText(e) {
  var decode = new XML('<d>' + e + '</d>');
  var strDecoded = decode.toString();
  if (strDecoded.charAt(0) === "'") {
    strDecoded = "'" + strDecoded;
  }
  return strDecoded;
}

function fixURL(address) {
  var URL = fixText(address);
  if (URL.search("http") == -1) {
    URL = "https://stt.wiki" + URL;
  } 
  return URL;
}

function getCacheData(targetURL, targetCacheName) {
    const crusher = new cUseful.CrusherPluginCacheService().init ({
      store:CacheService.getUserCache()
    });
    //Logger.log("targetURL: " + targetURL);
    //Logger.log("targetCacheName: " + targetCacheName);
    var cached = crusher.get (targetCacheName);
    if (cached != null) {
      return cached;
    }
    // This fetch takes 20 seconds:
    var result = UrlFetchApp.fetch(targetURL);
    var contents = result.getContentText();
    crusher.put (targetCacheName, contents);
    return contents;
}

function removeCaches() {
  const crusher = new cUseful.CrusherPluginCacheService().init ({
    store:CacheService.getUserCache()
  });
  var lastRow = traitsSheet.getLastRow();
  for (var i = 0; i < lastRow; i++) {
    crusher.remove ("Crew-List-Page-" + i);
    crusher.remove ("Category-Crew-List-Page-" + i);
  }
}

function eraseAllData(startRow,startCol,sheet) {
  if(!startRow) { startRow = 2; }
  if(!startCol) { startCol = 1; }
  var lastRow = sheet.getLastRow();
  var lastColumn = sheet.getLastColumn();
  if((lastRow - 1) <= startRow) {return;}
  var eraseRange = sheet.getRange(startRow,startCol,lastRow - 1, lastColumn);
  eraseRange.clear();
}  

function setFusionHeaders(sheet) { 

}

function setHeaders(sheet,sheetName) {
  switch(sheetName) {
    case f1SheetName:
    case f2SheetName:
    case f3SheetName:
    case f4SheetName:
    case f5SheetName:
      var headerArray = [['Name','CMD Base','DIP Base','ENG Base',
                          'SEC Base','SCI Base','MED Base']];
      break;
    case traitsSheetName:
      var headerArray = [['Name','Advocate','Aenar','Ambassador',
                          'Andorian','Android','Angosian',
                          'Artist','Astronomer','Astrophysicist',
                          'Athlete','Augment','Automated Unit',
                          'Ba\'ku','Bajoran','Bartender',
                          'Benzite','Betazoid','Boomer','Borg',
                          'Botanist','Breen','Brunali','Brutal',
                          'Bynar','Cardassian','Caregiver',
                          'Casual','Cetacean Biologist','Chameloid',
                          'Chancellor','Changeling','Chef',
                          'Civilian','Clone','Communicator',
                          'Constable','Costumed','Counselor',
                          'Courier','Crafty','Criminal',
                          'Cultural Figure','Cursed','Cyberneticist',
                          'Dahar Master','Deltan','Denobulan',
                          'Desperate','Diplomat','Dominion','Dosi',
                          'Duelist','Edosian','Efrosian','El-Aurian',
                          'Elaysian','Empath','Empress','Engineered',
                          'Evolved','Excalbian','Exoarchaeology',
                          'Exobiology','Exomycologist','Explorer',
                          'Federation','Ferengi','Gambler','Gardener',
                          'Geneticist','Geologist','Gorn','Hero',
                          'High Command','Hirogen','Hologram',
                          'Human','Hunter','Imperial Guard',
                          'Innovator','Inspiring','Interrogator',
                          'Investigator','Jemhadar','Jury Rigger',
                          'Kaelon','Kai','Kalandan','Kazon','Kelpien',
                          'Klingon','Klingon-Cardassian Alliance',
                          'Krenim','Ktarian','Linguist','Loque\'eque',
                          'Lord','Lurian','M-113 Creature','MACO',
                          'Malon','Maquis','Marksman','Maverick',
                          'Merchant','Mintakan','Mirror Universe',
                          'Mugato','Musician','Mylean','Na\'kuhl',
                          'Nacene','Neurologist','Nurse',
                          'Obsidian Order','Ocampa','Orion',
                          'Physician','Pilot','Presage','President',
                          'Primal','Prisoner','Probe','Prodigy',
                          'Prophet','Quantum Mechanics','Reman',
                          'Resourceful','Rich','Romantic','Romulan',
                          'Royalty','Saboteur','Scoundrel',
                          'Section 31','Senator','Shapeshifter',
                          'Silicon Lifeform','Smuggler','Son\'a',
                          'Special Envoy','Species 8472','Spiritual',
                          'Spy','Starfleet','Suliban','Survivalist',
                          'Tactician','Tailor','Tal Shiar','Talaxian',
                          'Talosian','Tamarian','Taresian',
                          'Telekinetic','Telepath','Temporal Agent',
                          'Terran Empire','Terran Rebellion',
                          'Terrellian','Theoretical Engineer',
                          'Thief','Tholian','Tkon','Torchbearer',
                          'Tosk','Trill','Undercover Operative',
                          'Vedek','Veteran','Vidiian','Villain',
                          'Vorta','Voth','Vulcan','Warp Theorist',
                          'Warrior','Writer','Xenoanthropology',
                          'Xindi','Zhian\'tara']];
      break;
    case URLSheetName:
      var headerArray = [['Name','URL']];
      break;
    case basicsSheetName:
      var headerArray = [['Name','Rarity',
                          'CMD Low','CMD High',
                          'DIP Low','DIP High',
                          'ENG Low','ENG High',
                          'SEC Low','SEC High',
                          'SCI Low','SCI High',
                          'MED Low','MED High']];
      break;
    default:
      var headerArray = [['Error writing header']];
      break;
  }     
  sheet.getRange(1,1,1,headerArray[0].length).setValues(headerArray);
}

0 个答案:

没有答案