Come evitare l'inserimento di una riga di dati in base al valore di una colonna all'interno dello stesso intervallo di date?

Aug 21 2020

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

1 dwmorrin Aug 21 2020 at 16:18

È necessario aggiornare la reducefunzione 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 reducefunzione. 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 reducediventa 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. findrestituisce undefinedse fallisce, quindi possiamo aggiornare la nostra reducecondizione per eseguire il push solo da studentId != ""a studentId != "" && !existingEntry.

Poiché abbiamo modificato la forma di dstCurrentValuesper 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);
}