본문 바로가기
GAS/[CAS_손코딩]

[GAS] 웹앱으로 입력된 날짜를 비교하여 값을 출력하기

by 일등미노왕국 2024. 5. 5.

 

 

이러한 자가 혈당체크를 해야 하는 웹앱이 있다고 가정을 할때, 본인같은 경우는 현재 오전(공복) 과 저녁(식후)  이렇게 하루 두번 혈당을 기록하고 있다.

 

당체크 할때마다 손꾸락이 너무아파 ㅜ.,ㅡ 

 

이렇게 입력된 데이터는 

 

이런식으로 기록이 되는데, 여기서 문제가 발행한다.

 

웹앱으로 입력된 날짜는 문자열 형식으로 들어오고, 스프레드 시트에 보이는 날짜는 yyyy-MM-dd 구조이지만 실제로 찍어보면 

 

날짜 형식이 영어 형식으로 나와서 날짜 비교자체가 되지 않는다..

 

더보기
function userClick(userInfo) {
  // const userInfo = { "chkdate":"2024-05-05", "bldsugar":200 };
  const ss = SpreadsheetApp.openById(shtId);
  let sht = ss.getSheets()[0];
  let range = sht.getRange("A2:C"); // 범위를 A2:C로 변경
  let values = range.getValues();

  // console.log(values);
  let dates = values.map(row => {
    const date = new Date(row[0]);
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
  });

  let chkdateIndex = dates.indexOf(userInfo.chkdate);
  let lastRow = values.filter(row => row[0] !== "").length + 2;

  if (chkdateIndex === -1) {
    sht.getRange(lastRow, 1, 1, 3).setValues([[userInfo.chkdate, userInfo.bldsugar, ""]]);
  } else {
    sht.getRange(lastRow - 1, 3, 1, 1).setValues([[userInfo.bldsugar]]);
  }
}

 

따라서 날짜 형식을 문자열로 변경하는 단계가 필요하다.

 

1.  range.getValues(): 이 메서드는 스프레드시트에서 지정된 범위의 데이터를 가져와서  2차원 배열로 반환하게 된다.

각 행은 스프레드시트의 행에 해당하고, 각 열은 해당 행의 셀 값에 해당한다.

 

2. values.map(row => { ... }): 배열의 map() 메서드를 사용하여 각 행의 데이터를 변환한다. 각 행을 나타내는 row 변수를 사용하여 각 행에 대한 작업을 수행하게 된다.

 

3. const date = new Date(row[0]);: 이 줄은 각 행의 첫 번째 열(인덱스 0)에 있는 값을 날짜 객체로 변환하게 되고, 이 값은 스프레드시트 셀에서 가져온 날짜 값이다.

 

4.  다음은 date에서 연도, 월, 일을 추출하게 된다.  getFullYear() 메서드는 해당 날짜의 연도를 반환하고,

getMonth() 메서드는 해당 날짜의 월을 0부터 시작하는 숫자로 반환하기에 반드시 1을 더해야지  정확한 월을 얻게 된다. 같은 의미로 getDate() 메서드는 해당 날짜의 일을 반환하게 된다.  그런 다음 String() 함수와 padStart() 메서드를 사용하여 월과 일을 두 자리 문자열로 만들게 된다. 

* padStart(2, '0') : 두자리수를 만드는데 한자리 숫자일 경우 앞에 0 값을 표기한다.

const year = date.getFullYear();

const month = String(date.getMonth() + 1).padStart(2, '0');

const day = String(date.getDate()).padStart(2, '0');

 

5. 이렇게 만들어진 값을  return ${year}-${month}-${day}  으로 리턴하여 최종적으로 날짜 형식이 "YYYY-MM-DD"인 문자열을 dates로 반환하게 된다.

 

 

날짜 값 변환이 끝났으면 혈당체크는 하루에 두번하기 때문에 날짜를 비교하여 신규 날짜가 입력되면 날짜와 공복 혈당을 적게 되고, 아니면 식후 식후 혈당으로 입력값이 들어가야 하는 코드를 만들어야 한다. 더 디테일하게 하려면 공복과 식후를 체크박스로 체크하여 입력값을 해당 위치에 넣으면 되겠지만, 이번 코드는 단순하게 날짜만 비교하여 값을 업데이트 하는 것으로 만들었다.

 

 

1.  chkdateIndex 변수를 사용하여 userInfo.chkdate가 날짜 배열 dates에서 어디에 위치하는지 하는지 indexOf() 메서드를 사용하여 userInfo.chkdate가 dates 배열에서 처음으로 발견되는 인덱스를 찾게 된다.

 

2.  lastRow 변수를 사용하여 새로운 데이터를 입력할 행을 결정한다. values 배열에서 비어 있지 않은 행의 개수를 세어 그 다음 행에 새로운 데이터를 입력하게 하는 원리이다.

 

3.  if 조건문을 사용하여 chkdateIndex를 확인한다. 만약 userInfo.chkdate가 dates 배열에 존재하지 않는다면 (chkdateIndex === -1), 새로운 날짜 데이터를 입력하게 된다. 이 경우에는 userInfo.chkdate, userInfo.bldsugar, 그리고 빈 문자열을 포함하는 새로운 행이 스프레드시트에 추가된다.

 

4.  그렇지 않으면 (즉, chkdateIndex !== -1), 기존 날짜에 대한 데이터가 이미 존재하는 것이므로 해당 행에 userInfo.bldsugar 값만을 업데이트하게 된다. 

 

모두 모두 건강한 혈당 생활하시길 바란다.

 

 

댓글