【问题标题】:Add row between specific rows in google app script在谷歌应用脚​​本中的特定行之间添加行
【发布时间】:2021-05-25 22:17:59
【问题描述】:

我将数据从一个数据表复制到另一个数据表。目前我正在将目标工作表中的每个新行插入到最后插入的行上方

datasheet.insertRowAfter(1);

每一行都有一个时间戳,格式如下:

25.05.2021 23:30:00

复制数据时会自动设置时间戳,并舍入到最后的 0.30 时间。 如果我有时忘记复制数据,就会产生间隙。因此我想手动复制丢失的数据。 我在 Sourcesheet 中创建了一个布尔值和一个时间 https://i.imgur.com/l1031QI.png

现在我想将我的数据复制到现有时间戳之间的目标表。例如,我上面截图中的 8.30 时间戳必须在此行中设置: https://i.imgur.com/HY9cYMQ.png

我想“循环”通过 Timestamp 列并找到手动时间的正确行并在那里创建一个新行并复制我的数据。 创建行和复制数据不是我的问题,只是在两个日期之间找到正确的行。 对我来说,将日期和时间都考虑在内很重要。

我不知道如何解决这个问题,也没有在网上找到任何东西。有人可以帮忙吗?

编辑: 当前代码从工作表复制到工作表

function Parsetracking() {
  var spa=SpreadsheetApp.getActiveSpreadsheet();
  var inputsheet = spa.getSheetByName("Parse Output");
  var datasheet= spa.getSheetByName("Tracker");
  var parsesheet = spa.getSheetByName("Parse Input");

  var nowdate = new Date();
  var nowdateeurope = convertTZ(nowdate, "Europe/Berlin");
  var lastdate = datasheet.getRange("L2").getDisplayValues();
  var lasttime = datasheet.getRange("N2").getDisplayValues();
  
  var checkdate = joinDateAndTime(lastdate,lasttime)
  var diff = nowdateeurope - checkdate;
  if (parsesheet.getRange("j2").isChecked() === true) {
    //SpreadsheetApp.getUi().alert('Under Construction.');

    if (parsesheet.getRange("i2").getValue() < datasheet.getRange("k2").getValue()) {
      Logger.log('smaller')
    }
    else {
      Logger.log('bigger');
    }
    return;
  } 
  else {
    if(diff >= 3600001){
      datasheet.insertRowAfter(1);
      datasheet.clear;
      var datecell = datasheet.getRange("L2");
      var timecell = datasheet.getRange("M2");
      var roundedtimecell = datasheet.getRange("n2");
      inputsheet.getRange("A2:J2").copyTo(datasheet.getRange("A2:J2"),{contentsOnly:true});
      inputsheet.getRange("A3:J3").copyTo(datasheet.getRange("o2:W2"),{contentsOnly:true});
      datecell.setValue(nowdate).setNumberFormat("dd:mm:yyyy");;
      timecell.setValue(nowdate).setNumberFormat("hh:mm:ss");

      var gmt = new Date();
      gmt.setHours(nowdate.getUTCHours()+2);
      var hours = gmt.getHours();
      var minutes = nowdate.getUTCMinutes();
      var newtime = hours + ':' + minutes;
      console.log(newtime);
      var roundedtime = RoundTimestamp(newtime);
      console.log(roundedtime);
      roundedtimecell.setValue(roundedtime);
      datasheet.getRange('K3').autoFill(datasheet.getRange('K2:K3'),SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES)

    }
  }
}

【问题讨论】:

  • 你说I want to "loop" through the Timestamp column and find the correct row for the manual time and create a new row there and copy my data.如何确定正确的行?
  • 您有正在处理的代码吗?请考虑提供您正在处理的电子表格的副本,以便更清楚地了解您的问题。
  • @Cooper 这基本上是我的问题。如何在一个特定列中找到正确的行?忘记日期和时间,用数值可能更容易理解。如果我的列具有以下值 5 4 2 1 0 并且我想在 2 和 4 之间插入一个 3。我怎样才能在列中找到正确的位置?
  • @Iamblichus 我提供了我当前的代码,但我怀疑它是否有助于理解我的问题 :) 感谢四位您的努力
  • 所以你有一个源时间戳和一列中的一系列时间戳,你想找到源时间戳所属的行索引(比上一行晚,比下一行早一)。是这样吗?我假设您已经知道如何比较这些时间戳,对吧?

标签: google-apps-script google-sheets google-sheets-api spreadsheet


【解决方案1】:

如果您的时间戳已排序并具有相同的格式,则可以通过以下方式完成:

const timestamps = [
    "25.05.2021 23:20:00",
    "25.05.2021 23:30:00",
    "25.05.2021 23:40:00",
    "25.05.2021 23:50:00"
];

const missed_timestamp = "25.05.2021 23:35:00";

function DMY_to_YMD(dd_mm_yyyy) {
    return dd_mm_yyyy.replace(/(\d+).(\d+).(\d+)/, "$3$2$1");
}

const missed_YMD = DMY_to_YMD(missed_timestamp);

var index = 0

for (var time of timestamps) {
    if (missed_YMD < DMY_to_YMD(time)) break;
    index++;
}

timestamps.splice(index, 0, missed_timestamp);

console.log(timestamps);

输出:

[
  "25.05.2021 23:20:00",
  "25.05.2021 23:30:00",
  "25.05.2021 23:35:00", <-- here is the missed timestamp
  "25.05.2021 23:40:00",
  "25.05.2021 23:50:00"
]

如果您有一个非常庞大的时间戳列表,那么尝试实现二进制搜索是有意义的。

简单地将二维数组转换为一维数组,反之亦然:

console.log([ [1], [2], [3] ].map(x => x[0])) // [ 1, 2, 3 ]

console.log([ 1, 2, 3 ].map(x => [x])) // [ [1], [2], [3] ]

更新

对于小型数组,它可以做得更简单:

const timestamps = [
    "25.05.2021 23:20:00",
    "25.05.2021 23:30:00",
    "25.05.2021 23:40:00",
    "25.05.2021 23:50:00"
];

const missed_timestamp = "25.05.2021 23:35:00";

const DMY_to_YMD = (dd_mm_yyyy) => 
    dd_mm_yyyy.replace(/(\d+).(\d+).(\d+)/, "$3$2$1");

const t     = DMY_to_YMD(missed_timestamp);
const arr   = timestamps.map(x => DMY_to_YMD(x));
const index = arr.concat([t]).sort().indexOf(t);

timestamps.splice(index, 0, missed_timestamp);

console.log(timestamps); // the same output as above

【讨论】:

  • 时间戳列表大约有 1000-2000 行。谢谢你的建议,我稍后会尝试实现这样的东西:)
  • 如果你碰巧喜欢花哨的神秘功能风格,你可以删除循环并通过这种方式获得indexconst index = timestamps.map(t =&gt; DMY_to_YMD(t)).filter(t =&gt; t &lt; missed_YMD).length;
  • 工作至今,谢谢!我只有替换函数抛出错误的问题。 (替换不是函数)但我想我可以处理那个。
  • 如果值不是字符串,可能会发生错误。作为一种解决方法,您可以尝试将值转换为字符串:dd_mm_yyyy.toString().replace(/(\d+).(\d+).(\d+)/, "$3$2$1");
  • 如果您的二维数组只有一列,则可以通过flat() 方法将其转换为一维数组。这样:const timestamps = [ datasheet.getRange("K2:K").getValues().flat() ]; 它这样做:[ [1], [2], [3] ] --> [ 1, 2, 3 ]。并且可以向后操作two_D_array = [1,2,3].map(x =&gt; [x])
猜你喜欢
  • 1970-01-01
  • 2022-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多