https://www.youtube.com/watch?v=dX3krhu1PqM&list=PLxmyPu_Id2smCXbzw2IgsRpizPIaR8G-i&index=5
앱스 스크립트로 로또번호를 생성하는 코드이다.
기존에 본인이 했던 VBA로 만드는 코드에서는 Colection을 통해서 중복된 수가 나오면 중복된 수가 없을 때 까지 무한반복해서 로또 번호를 추출하곤 했다.
이 코드에서는 1부터 45까지 배열을 만든 후 이것을 복사하여 번호가 추출이 되면 그 번호를 빼곤 다시 추출하여 중복되는 수가 애초에 발생하지 않도록 하고 있다.
EXCEL AND VBA님은 이것을 위해 JSON.stringify로 배열을 String화 한 후 다시 JSON.parse를 통해 배열의 사본을 위해 복사하는 코드를 만들었지만,
let values = JSON.parse( JSON.stringify(machine)) ;
배열의 사본을 만드는 것은 이방법보다 더 쉬운 방법이 있다. 바로
let tmp = machine.slice();
이 한줄이다.
자그럼 복제를 안하면 어찌 될까?
splice 함수는 slice 함수와는 다르게 도마뱀 코리를 자르듯 배열에서 슬라이싱 된 만큼 기존 배열의 값도 변경하게 만든다.
그렇기에 횟수가 반복진행될 수록 45개의 숫자는 한번씩만 사용되고 더이상 재활용이 되지 않는다.
그렇기 때문에 배열을 복제해야 하는 것이다.
function Lotto() {
let sht = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0], // sht 시트선언
iCnt = sht.getRange("c2").getValue(), // 횟수 선언
rows=[], // 6개의 로또 번호를 담을 배열
row, // 하나의 로또 번호들을 담을 변수
machine = get_From_A_to_B(1,45); // 1부터 45번까지 차례로 담기 위한 변수
// 변수 선언하기 콤마(,)로 연결하면 쭉 이어서 선언할수 있음 / 단 마지막은 세미콜론(;)으로 마루리해야함
for(let i=1 ; i <= iCnt ; i++){
row = [];
let tmp = machine.slice(); // machine 배열의 사본(복제)
for(let c=1; c<= 6 ; c++){
row.push(tmp.splice(parseInt( Math.random()*tmp.length), 1)[0] );
// splice는 tmp 배열에서 무작위로 하나씩 row배열로 넣은 후 tmp 배열에서 삭제함
// 이렇기 때문에 중복수가 발생하지 않음.
}
rows.push(row); // 전체출력해할 배열에 담음
}
sht.getRange(6,2,100,6).clearContent(); // 기존 영역 삭제
sht.getRange(6,2, rows.length, rows[0].length).setValues(rows); // 완성된 로또 번호를 셀에 출력
}
function get_From_A_to_B(i,j) {
let result = [];
for (let m=i; m<=j ; m++){
result.push(m); // 1부터 45까지의 번호를 result 배열에
// 순서대로 담아라
}
return result;
}
아직은 눈에 많이 익숙하지 않아서 오타도 많고 갑자기 공부할 양도 많이 늘었지만, 결국 우리는 또 이녀석을 정복하게 될것이다. 늘 그랬듯
https://docs.google.com/spreadsheets/d/1UJEOae4DDJkcm0DcVxdn2aAXrJpTM0HKUFTEDJbavqE/edit?usp=sharing
'GAS' 카테고리의 다른 글
[GAS] cheerio를 이용한 Daum뉴스 크롤링 (0) | 2023.04.19 |
---|---|
[GAS] sheets데이터를 html 문서를 작성해보자 (0) | 2023.04.19 |
[GAS] 시트 통합 && 필터링 (0) | 2023.04.04 |
[GAS] 시트통합 매크로 (0) | 2023.04.03 |
[GAS] VBA 기초방 #9 [ 데이터 영역 선택하기 ] (0) | 2023.01.08 |
댓글