Google 脚本:仅当数字上升时才从不同的选项卡更新列

Google scripts: Updating a column from a different tab only when numbers go up

我正在尝试创建一个数据库来记录与 Black Desert Online 的 API 相关的商品的最高价格。第一列是商品的索引号,第二列是市场价格 post 通过此代码输入 MaxPrice Tab from the API Prices Tab:

function readSalesNum() {
var sheetFrom = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Prices");
var sheetTo = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("MaxPrice");

// Copy from 2nd row, 5th column, all rows for one column 
var index = sheetFrom.getRange(2, 2, sheetFrom.getLastRow(), 1).getValues();
var marketprice = sheetFrom.getRange(2, 5, sheetFrom.getLastRow(), 1).getValues();

//Item name overwrites itself
sheetTo.getRange(1,1,index.length,1).setValues(index);
sheetTo.getRange(1,2,index.length,1).setValues(marketprice);
}

我需要跟踪所有商品的最高售价。 API 每 30 分钟更新一次。在 BDO 中,开发人员强制执行的所有项目都有市值。这就是为什么最初脚本会 post 一个新列,每 2 小时更新一次价格,然后 =MAX 以查找该项目的当前最高价格。但是,如果将新项目添加到 API(按字母顺序),它会扭曲所有数据

我需要一个脚本来查看 MaxPrices 中的 A 列,找到价格中的匹配数字,然后 post 当前市场价格到 MaxPrices 中的 B 列。如果每个项目的价格选项卡中的当前市场价格上涨,则只会更新 MaxPrices 中的 B 列。

好的,所以我们需要创建一个现有的最高价格列表,compare/update它们到新价格,添加新项目。

function myFunction() {
  var sheetFrom = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Prices"); 
  var sheetTo = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("MaxPrice");

  //three steps

  //1. create dictionary of MaxPrices from MaxPrice sheet
  var data = sheetTo.getDataRange().getValues();
  var maxPriceData = {}
  for (var i=1; i<data.length;i++){maxPriceData[data[0]]=data[1]}

  //2. Compare current prices from column E of the Prices to the dictionary
  data = sheetFrom.getDataRange().getValues();
  for (var i=1; i<data.length;i++)
  {
    var itemId = data[i][1];//B
    var basePrice = data[i][4];//E
    if (itemId in maxPriceData ){
      if (basePrice > maxPriceData[itemId]) maxPriceData[itemId] = basePrice;//updates dictionary if new price higher
    }else{
      maxPriceData[itemId]=basePrice;//adds new item to the item list
    }
  }

  //3. Update MaxPrice spreadsheet
  var output = [];
  for (key in maxPriceData){
    var itemId = key;
    var price = maxPriceData[key];
    output.push([itemId,price]);
  }
  
  sheetTo.getRange(2, 1,output.length, output[0].length).setValues(output);

}

我没有根据实际数据对此进行测试,因此可能会出现一两个错字。

希望命令的文本足够清晰,可以阅读和理解。我在 getValues() 的末尾添加了 slice(1) 以省略 header 行。

  function myFunction() {
    var sheetTo = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("MaxPrice");
    var data = sheetTo.getDataRange().getValues().slice(1);
    var maxPrices = Object.fromEntries(data.map(([id, price]) => [id, price]));
    
    var sheetFrom = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Prices");
    data = sheetFrom.getDataRange().getValues().slice(1);
    
    data.forEach(row => {
      let id = row[1]; // column 2
      let price = row[4]; // column 5
      maxPrices[id] = maxPrices[id] === undefined ? price : Math.max( price, maxPrices[id])
    });
  
    var output = Object.entries(maxPrices).map(row => [...row]);
    sheetTo.getRange(2, 1, output.length, output[0].length).setValues(output);
  }