【问题标题】:copy data matches from one sheet to another within a specific row range Google apps script在特定行范围内将数据匹配项从一张表复制到另一张表 Google Apps 脚本
【发布时间】:2021-06-29 00:12:18
【问题描述】:

这就是我想做的:

我有一个名为“BD Visitas”的源表。 此工作表包含一些数据,这些数据稍后将是我要复制到另一个工作表的数据。

我有一个名为“Ficha mascota”的目标表。 此工作表包含一系列行,我想将源工作表“BD Visitas”中的数据粘贴到这些行中。

问题如下:

在目标表的“D18”单元格中,写着宠物的名字。

获取此单元格的值,在源工作表“BD Visitas”的 B 列中执行搜索并查找名称匹配项。

找到匹配的行后,获取最后 15 个匹配项。即从最后一行到第一行(从下到上)。

当你得到最后 15 个匹配的行时,然后复制 C、G、H、I 列(源表)并将第 39 到 53 行范围内的值粘贴到 C、D、G 列中, 目标表“Ficha mascota”的 M。

但是,它必须以相反的顺序复制,即源工作表的最后一个匹配项必须复制到目标工作表的第 39 行。源工作表的倒数第二个匹配项必须复制到目标工作表的第 40 行。等等。因此,在目标工作表的第 53 行中,将粘贴 15 个匹配项范围内的第一个匹配项。

我所做的工作如下:

function get15lastRowsBDvisitasToFichaMascota() {

  const libro = SpreadsheetApp.getActiveSpreadsheet();
  const hojaOrigen = libro.getSheetByName('BD visitas');
  const hojaDestino = libro.getSheetByName('Ficha mascota');

  // Rango destino

  var rowsDestino = hojaDestino.getRange("C39:U53");
  var rowsDestinoR = rowsDestino.getNumRows();
  var rowsDestinoUF = rowsDestino.getLastRow();

  // Coincidencia nombre mascota

  var nombreVisor = hojaDestino.getRange('D18').getValue();
  var tablaDeBusquedaNombre = hojaOrigen.getRange('B7:J').getValues();
  var listaDeBusquedaNombre = tablaDeBusquedaNombre.map(function(row){return row[0]});
  var busquedaNombre = listaDeBusquedaNombre.indexOf(nombreVisor);

  var coincidenciaNombre = tablaDeBusquedaNombre[busquedaNombre][0];
  var fechaVisita = tablaDeBusquedaNombre[busquedaNombre][1];
  var motivoVisita = tablaDeBusquedaNombre[busquedaNombre][5];
  var sintomasVisita = tablaDeBusquedaNombre[busquedaNombre][6];
  var observacionesVisita = tablaDeBusquedaNombre[busquedaNombre][7];

  // Rangos copia y pega

  var obj = [
    { src: fechaVisita, dst: "C" + rowsDestinoUF }, // Fecha
    { src: motivoVisita, dst: "D" + rowsDestinoUF }, // Motivo
    { src: sintomasVisita, dst: "G" + rowsDestinoUF }, // Sintomas
    { src: observacionesVisita, dst: "M" + rowsDestinoUF }, // Observaciones
  ];
  Logger.log(obj);

  obj.forEach(({src, dst}) => hojaOrigen.getRange(src).copyTo(hojaDestino.getRange(dst), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false));  

}

但我被困住了。我不知道如何调用将源工作表的固定部分粘贴到目标工作表的行范围内。

我也不知道如何让行以相反的顺序粘贴到目标工作表上。

我是使用谷歌应用程序脚本和 javascript 编码的新手。这几天我学到了很多东西,也做了很多事情,但是我的能力仍然有限,错过了很多。

非常感谢任何帮助。非常感谢。 对不起我的英语不好。

【问题讨论】:

  • 如果下面的答案不能回答您的问题,那么可以在您的问题中包含一些示例数据,以及预期的输出,以便我们提供替代方案。
  • mshcruz 给我的答案非常有效。除了找不到匹配项时出现错误。我已经在你的回答中回答了。所有的帮助都是宝贵的。谢谢你。 @iansedano

标签: google-apps-script google-sheets


【解决方案1】:

您似乎正在尝试使用 indexOf() 搜索宠物名称,但这只会带来第一个匹配项,据我了解,您最多需要 15 个匹配项。

一种方法是:

  1. 遍历源工作表的行并检查 B 列中的名称是否与目标工作表中单元格 D18 指定的名称匹配。由于您希望以相反的顺序获取它们,因此您可以从最后一行开始向上直到达到所需的数字 (15) 或直到检查所有值。
  2. 当有匹配时,您可以从您想要的列中获取值并将它们存储在一个数组中。
  3. 接下来,将值写入目标电子表格。由于您的目标列并非都是连续的,并且假设您不想删除范围中间的任何现有数据,因此在这种情况下使用 setValues() 可能无济于事。一种替代方法是使用setValue() 逐一写入值,但使用isn't very efficient。也许更好的方法是逐列写入值,因为行是连续的。

上面可以这样实现:

function get15lastRowsBDvisitasToFichaMascota() {

  const libro = SpreadsheetApp.getActiveSpreadsheet();
  const hojaOrigen = libro.getSheetByName('BD visitas');
  const hojaDestino = libro.getSheetByName('Ficha mascota');

  // Rango destino

  var rowsDestino = hojaDestino.getRange("C39:U53");
  var rowsDestinoR = rowsDestino.getNumRows();
  var rowsDestinoUF = rowsDestino.getLastRow();

  // Coincidencia nombre mascota

  var nombreVisor = hojaDestino.getRange('D18').getValue();
  var tablaDeBusquedaNombre = hojaOrigen.getRange('B7:J' + hojaOrigen.getLastRow()).getValues();

  var maxMascotas = 15;
  var dadosMascotas = [];
  for (var i = tablaDeBusquedaNombre.length - 1; dadosMascotas.length <= maxMascotas && i >= 0; i--) {
    if (tablaDeBusquedaNombre[i][0] === nombreVisor) {
      var fechaVisita = tablaDeBusquedaNombre[i][1];
      var motivoVisita = tablaDeBusquedaNombre[i][5];
      var sintomasVisita = tablaDeBusquedaNombre[i][6];
      var observacionesVisita = tablaDeBusquedaNombre[i][7];
      dadosMascotas.push([fechaVisita, motivoVisita, sintomasVisita, observacionesVisita]);
    }
  }

  if (dadosMascotas.length === 0) {
    return;
  }

  var hojaDestinoCols = ['C', 'D', 'G', 'M'];
  var primeraRowDestino = rowsDestino.getRow()
  for (var i = 0; i < hojaDestinoCols.length; i++) {
    // Get the values per column
    var colValues = dadosMascotas.map(function (row) { return [row[i]] });

    // Write the column values starting from the first row of the destination range
    hojaDestino.getRange(
      hojaDestinoCols[i] + primeraRowDestino +
      ':' +
      hojaDestinoCols[i] + (primeraRowDestino + dadosMascotas.length - 1))
      .setValues(colValues);
  }
}

【讨论】:

  • 这很完美,我学到了新东西!谢谢!但是,当它找不到匹配项时出现错误。错误是这样的:```异常:数据中的行数与范围内的行数不匹配。数据有 0 但范围有 2。 ``` 有没有办法告诉它,如果找不到匹配项,就什么也不做?我试图包含 ``` if (tablaDeBusquedaNombre[i][0] !== nombreVisor) { } ``` 但没有成功。 @mshcruz
  • 处理这种情况的一种方法是在未找到匹配项时返回。我已经更新了答案以包含它。如果您仍然想在函数中执行其他操作而不返回,那么您只需在 IF 中包含检查是否匹配的内容: if (dadosMascotas.length > 0) { ... }
猜你喜欢
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2018-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多