Bagaimana cara menghindari penyisipan baris data berdasarkan nilai kolom dalam rentang tanggal yang sama?

Aug 21 2020

Saya memasukkan data ke lembar dari input pengguna. Sebelum memasukkan saya ingin memastikan bahwa sudah ada baris yang memiliki alamat email yang sama (kolom 3, nilai e + k3 dalam kode) dalam rentang tanggal yang diberikan. Jika sudah ada, itu tidak akan menyisipkan baris itu tetapi akan memproses masukan lainnya. Bagaimana cara mengatasinya? Terima kasih untuk 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);
}

Jawaban

1 dwmorrin Aug 21 2020 at 16:18

Anda perlu mengupdate reducefungsinya agar tidak menghasilkan baris baru ketika kumpulan data yang ada sudah memiliki baris dengan tanggal input dan ID mahasiswa.

Ini mengharuskan Anda menggeser ke atas di mana Anda mendapatkan nilai saat ini ke langkah # 2 dan memperluas nilai apa yang Anda ambil untuk menyertakan kolom email sehingga Anda dapat mengakses nilai tersebut dalam reducefungsi. Kami juga tidak dapat menggunakan .flat()trik ini sekarang karena kami melihat pada banyak kolom, tetapi tidak apa-apa karena kami memiliki .find()dan .map()itu akan berfungsi dengan baik.

Sekarang reducemenjadi langkah # 3, dan kami menambahkan persyaratan kami. Kami menggunakan .find()untuk mencoba dan mendapatkan catatan yang ada dengan tanggal yang diberikan dan email siswa. findmengembalikan undefinedjika gagal, sehingga kami dapat memperbarui reducekondisi kami menjadi hanya push dari saja studentId != ""ke studentId != "" && !existingEntry.

Karena kita mengubah bentuk dstCurrentValuesuntuk mengembangkannya dan mendapatkan nilai email, kita perlu mengubahnya .flat()menjadi .map(row => row[0])untuk mendapatkan bentuk yang sama lastIndexOf.

Untuk kepentingan semua pembaca, nama variabel telah diperbarui dari notasi "A1" menjadi nama yang mencerminkan nilai yang dikandungnya.

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);
}