Come evitare l'inserimento di una riga di dati in base al valore di una colonna all'interno dello stesso intervallo di date?
Sto inserendo dati in un foglio dagli input dell'utente. Prima di inserire voglio assicurarmi che ci sia già una riga con lo stesso indirizzo email (colonna 3, valore e + k3 nel codice) all'interno dell'intervallo di date indicato. Se è già presente, non inserirà quella riga ma elaborerà altri input. Come risolverlo? Grazie 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);
}

Risposte
È necessario aggiornare la reduce
funzione in modo da non generare una nuova riga quando il set di dati esistente ha già una riga con la data di input e l'ID studente.
Ciò richiede di spostarsi verso l'alto dove si ottengono i valori correnti al passaggio 2 ed espandere i valori che si recuperano per includere la colonna dell'email in modo da poter accedere a tali valori nella reduce
funzione. Inoltre, non possiamo utilizzare il .flat()
trucco ora poiché stiamo guardando più colonne, ma va bene perché lo abbiamo .find()
e .map()
funzionerà altrettanto bene.
Ora reduce
diventa il passaggio 3 e aggiungiamo il nostro requisito. Usiamo .find()
per cercare di ottenere un record esistente con la data specificata e l'email dello studente. find
restituisce undefined
se fallisce, quindi possiamo aggiornare la nostra reduce
condizione per eseguire il push solo da studentId != ""
a studentId != "" && !existingEntry
.
Poiché abbiamo modificato la forma di dstCurrentValues
per espanderla e ottenere i valori di posta elettronica, è necessario passare .flat()
a .map(row => row[0])
per ottenere la stessa forma per lastIndexOf
.
A vantaggio di tutti i lettori, i nomi delle variabili sono stati aggiornati dalla notazione "A1" ai nomi che riflettono i valori che contengono.
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);
}