¿Cómo evitar la inserción de una fila de datos basada en un valor de columna dentro del mismo rango de fechas?
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
Debe actualizar la reduce
funció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 reduce
funció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 reduce
convierte 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. find
devuelve undefined
si falla, por lo que podemos actualizar nuestra reduce
condición para empujar solo de solo studentId != ""
a studentId != "" && !existingEntry
.
Debido a que cambiamos la forma de dstCurrentValues
para 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);
}