본문 바로가기
VBA/365 FUNCTION

[365 함수리뷰] 서랍님 달력리뷰(feat. to_do List)

by 일등미노왕국 2023. 10. 29.

 

몇일전 수식한줄의 달력을 포스팅 한적이 있다.

https://1stminokingdom.tistory.com/330

 

[365 함수리뷰] 달력만들기

365 함수로 달력만들기이다. 본인은 이런 비슷한 달력들을 많이 만들어보았다.. 의뢰에도 이런 비슷한 문의가 들어왔기 때문에 지저분한 코드에 비해서 어렵지않게 만들어 왔던거 같다.. 하지만

1stminokingdom.tistory.com

 

이녀석이 애들 장난이었다면, 어마무시한 코드를 서랍님이 공개했다.

 

 

 

 

서랍님이 올린 코드를 한번 리뷰해보도록 하겠다.

=LAMBDA([month], [range_todo], [rows_todo],
    LET(
        →STEP1, 과거10년전부터 향후 10년까지 일정 추가 가능,
        _month, IF(ISOMITTED(month), 0, month),
        
        →STEP2, 할일 날짜,
        _rng, range_todo,
        
        →STEP3, 할일의 크기설정_삭제가능,
        _n, IF(ISOMITTED(rows_todo), MAX(BYROW(--(CHOOSECOLS(range_todo, 1) = TRANSPOSE(CHOOSECOLS(range_todo, 1))), LAMBDA(x, SUM(x)))), rows_todo),
        
        →STEP4, 선택한 날짜의 시작일,
        _d1, EOMONTH(TODAY(), -1 + _month) + 1,
        
        →STEP5, 해당월만 변수에 저장,
        _list, LET(a, SEQUENCE(, 7 * 6, -WEEKDAY(_d1) + _d1) + 1, IF(MONTH(a) = MONTH(_d1), a, "")),
        
        →STEP6, 함수영역,
        _f, LAMBDA(x,
            LET(
            
                →STEP6_1, 해당월의 주차별필터링,
                t, FILTER(_list, QUOTIENT(SEQUENCE(, 42) - 1, 7) + 1 = x),
                
                →STEP6_2, 할일 크기에 맞게 크기를 수정,
                IFERROR(VSTACK(TEXT(t, "d"), TAKE(EXPAND(DROP(REDUCE("", t, LAMBDA(a, b, HSTACK(a, FILTER(CHOOSECOLS(_rng, 2), CHOOSECOLS(_rng, 1) = b, "")))), , 1), 20, , ""), _n)), "")
            )
        ),
        →STEP7, 주차별출력,
        _td, IFERROR(TEXT(VSTACK(_f(1), _f(2), _f(3), _f(4), _f(5), _f(6)), "0;-0;;@"), ""),
        
        →STEP8, 헤더만들기_2행7열,
        _th, VSTACK(EXPAND(HSTACK(YEAR(_d1) & "년", MONTH(_d1) & "월"), , 7, ""), {"일", "월", "화", "수", "목", "금", "토"}),
        
        →STEP9, 헤더와 내용 출력하기,
        _o, VSTACK(_th, _td),
        _o
    )
)($I$2 - 120, OFFSET(Monthly!$M$3, , , COUNTA($M:$M) - 1, 2), $K$2)

이코드는 STEP6 에 있듯이 사용자함수처럼 _f 로 FUNTION 역할을 수행하도록 하였다.

STEP7에서 잘보여주듯이 _f 함수의 인자를 1주차부터 6주차까지를 순차적으로 넣으면서 VSTACK으로 6주차의 데이터를 쌓게 된다. 

 

STEP6에서 주차를 x변수로 받게 되어, 주차별 할일을 to-do 와 비교하여 값을 가져오게 되는데,

→STEP6_1, 해당월의 주차별필터링,


t, FILTER(_list, QUOTIENT(SEQUENCE(, 42) - 1, 7) + 1 = x),

이게 그 역할을 하게 된다. 6주( 7 X 6 = 42)를 QUOTIENT함수로 각 날짜를 7로 나누면 몫으로 주차가 나오게 되는데 그 주차가 인자로 들어오는 x 값과 비교하여 필터링 된 값을 t 에 담게 된다.

 

 

주차가 분리 되었다면

 

→STEP6_2, 할일 크기에 맞게 크기를 수정,


IFERROR(VSTACK(

날짜 영역: TEXT(t, "d"), 

to-do List : TAKE(EXPAND(DROP(
             REDUCE("", t, LAMBDA(a, b, 
             HSTACK(a, FILTER(CHOOSECOLS(_rng, 2), CHOOSECOLS(_rng, 1) = b, ""))))
             , , 1), 20, , ""), _n)), "")

EXPAND로 행의길이 최대 20행과 열의 길의는 기존배열의 크기를 가져오게 되는데 20행중에서 실제로는 TACK함수의 인자에 따라 실제 출력되는 영역이 정해진다.

 

각 주차의 날짜들과 TO-DO LIST의 날짜를 비교한 뒤 필터를 통해 할일을 가져오게 된다.

 

→STEP7, 주차별출력,
_td, IFERROR(TEXT(VSTACK(_f(1), _f(2), _f(3), _f(4), _f(5), _f(6)), "0;-0;;@"), ""),

→STEP8, 헤더만들기_2행7열,
_th, VSTACK(EXPAND(HSTACK(YEAR(_d1) & "년", MONTH(_d1) & "월"), , 7, ""), {"일", "월", "화", "수", "목", "금", "토"}),

→STEP9, 헤더와 내용 출력하기,
_o, VSTACK(_th, _td),
_o

 

STEP7 이후로는 결과물을 출력하는 부분이기 때문에 생략하도록 하겠다.

 

함수안에 FUNCTION을 넣는것은 365에서는 처음 다루는 거라, 본인 또한 깊이없이 나열한거 같아, 비슷한 문제로 감각을 키워 보도록 하겠다.

 

 

리뷰가 맘에 들지 않는다.

 

미안,,지금 이글을 보고 있는 당신께

 

반응형달력by서랍.xlsx
0.03MB

댓글