¿Cómo evitar la inserción de una fila de datos basada en un valor de columna dentro del mismo rango de fechas?

Aug 21 2020

Estoy insertando datos en una hoja desde las entradas del usuario. Antes de insertar, quiero asegurarme de que ya haya una fila con la misma dirección de correo electrónico (columna 3, valor e + k3 en el código) dentro del rango de fechas dado. Si ya está allí, no insertará esa fila pero procesará otras entradas. ¿Cómo resolverlo? Gracias a Tanaike.

function onePeriodm(){
  
  const srcSheetName = "Dashboard";
  
  // 1. Retrieve values from the source sheet.
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const srcSheet = ss.getSheetByName(srcSheetName);
  const [[,,,,,k3],,[f5,g5,...h5i5j5k5]] = srcSheet.getRange("F3:K5").getDisplayValues();
  
  // 2. Convert the values for putting to the destination sheet.
  const dstValues = h5i5j5k5.reduce((ar, e) => {
    if (e != "") ar.push([g5, Number(e), e + k3, , , f5]);
    return ar;
  }, []);
  
  // 3. Put the converted values to the destination sheet.
  const dstSheet = ss.getSheetByName(f5);
  const dstCurrentValues = dstSheet.getRange(`A2:A${dstSheet.getLastRow()}`).getDisplayValues().flat();
  const index = dstCurrentValues.lastIndexOf(dstValues[0][0]) + 2;
  dstSheet.insertRowsAfter(index, dstValues.length);
  dstSheet.getRange(index + 1, 1, dstValues.length, dstValues[0].length).setValues(dstValues);
}

Respuestas

1 dwmorrin Aug 21 2020 at 16:18

Debe actualizar la reducefunción para no generar una nueva fila cuando el conjunto de datos existente ya tiene una fila con la fecha de entrada y la identificación del estudiante.

Esto requiere que cambie hacia arriba donde obtiene los valores actuales al paso n. ° 2 y expanda los valores que recupera para incluir la columna de correo electrónico para que pueda acceder a esos valores en la reducefunción. Tampoco podemos usar el .flat()truco ahora ya que estamos viendo múltiples columnas, pero está bien porque lo hemos hecho .find()y .map()eso funcionará igual de bien.

Ahora se reduceconvierte en el paso n. ° 3 y agregamos nuestro requisito. Usamos .find()para intentar obtener un registro existente con la fecha y el correo electrónico del estudiante. finddevuelve undefinedsi falla, por lo que podemos actualizar nuestra reducecondición para empujar solo de solo studentId != ""a studentId != "" && !existingEntry.

Debido a que cambiamos la forma de dstCurrentValuespara expandirlo y obtener valores de correo electrónico, debemos cambiar .flat()a .map(row => row[0])para lograr la misma forma para lastIndexOf.

Para beneficio de todos los lectores, los nombres de las variables se han actualizado de la notación "A1" a nombres que reflejan los valores que contienen.

function onePeriodm() {
  const srcSheetName = "Dashboard";

  // 1. Retrieve values from the source sheet.
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const srcSheet = ss.getSheetByName(srcSheetName);
  const [
    [, , , , , emailPattern],
    ,
    [courseCatalogId, dateString, ...studentIds],
  ] = srcSheet.getRange("F3:K5").getDisplayValues();

  // 2. Retrieve current values
  const dstSheet = ss.getSheetByName(courseCatalogId);
  const dstCurrentValues = dstSheet
    .getRange(`A2:C${dstSheet.getLastRow()}`) // expanded to include email column
    .getDisplayValues(); // not flattening since we have multiple columns now

  // 3. Convert the values for putting to the destination sheet.
  //    Do not include if there is already an email for this date in current values
  const dstValues = studentIds.reduce((array, studentId) => {
    const existingEntry = dstCurrentValues.find(
      (row) => row[0] === dateString && row[2] === studentId + emailPattern
    );
    if (studentId != "" && !existingEntry)
      array.push([
        dateString,
        Number(studentId),
        studentId + emailPattern,
        ,
        ,
        courseCatalogId,
      ]);
    return array;
  }, []);

  // 4. Put the converted values to the destination sheet.
  const index = dstCurrentValues.map((row) => row[0]).lastIndexOf(dateString);
  const row = index + 2;
  dstSheet.insertRowsAfter(row, dstValues.length);
  dstSheet
    .getRange(row + 1, 1, dstValues.length, dstValues[0].length)
    .setValues(dstValues);
}