동일한 날짜 범위 내의 열 값을 기반으로 데이터 행 삽입을 방지하는 방법은 무엇입니까?

Aug 21 2020

사용자 입력에서 시트에 데이터를 삽입하고 있습니다. 삽입하기 전에 주어진 날짜 범위 내에 동일한 이메일 주소 (코드의 3 열, 값 e + k3)를 가진 행이 이미 있는지 확인하고 싶습니다. 이미있는 경우 해당 행을 삽입하지 않고 다른 입력을 처리합니다. 그것을 해결하는 방법? 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);
}

답변

1 dwmorrin Aug 21 2020 at 16:18

reduce기존 데이터 세트에 입력 날짜 및 학생 ID가있는 행이 이미있는 경우 새 행을 생성하지 않도록 함수 를 업데이트해야합니다 .

이를 위해서는 현재 값을 2 단계로 이동하고 검색하는 값을 확장하여 reduce함수 에서 해당 값에 액세스 할 수 있도록 이메일 열을 포함해야 합니다. 또한 .flat()여러 열을보고 있기 때문에 지금 트릭을 사용할 수 없습니다 .하지만 우리가 가지고 .find()있고 .map()잘 작동 하기 때문에 괜찮 습니다.

이제 reduce단계 # 3이되고 요구 사항을 추가합니다. 우리 .find()는 주어진 날짜와 학생 이메일로 기존 기록을 얻기 위해 사용 합니다. 실패하면 find반환 undefined하므로 reduce조건을 업데이트 studentId != ""하여에서 studentId != "" && !existingEntry.

우리의 모양 변경하기 때문에 dstCurrentValues그것을 확장하여 이메일 값을 얻는을, 우리는 변경해야 .flat()하기 .map(row => row[0])에 같은 모양을 달성하기 위해 lastIndexOf.

모든 독자의 이익을 위해 변수 이름이 "A1"표기법에서 포함 된 값을 반영하는 이름으로 업데이트되었습니다.

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