Range class의 createTextFinder()
2. Range 클래스에서 createTextFinder 사용하기
1. 요약
이 포스트에서는 createTextFinder() 메소드를 사용하여 Range 클래스에서 특정 텍스트를 찾는 방법과 textFinder에서 제공하는 메소드를 소개합니다. createTextFinder()를 처음 접해보신 분이라면 이전의 포스트를 먼저 읽어보시길 권합니다.
Spreadsheet class의 createTextFinder()
Sheet class의 createTextFinder()
2. Range 클래스에서 createTextFinder 사용하기
지난 포스트에서 살펴보았듯이 구글 앱스 스크립트의 ‘createTextFinder()’ 는 구글 스프레드시트에서 텍스트를 검색할 때 사용할 수 있는 메소드로, 스프레드시트 범위에서 텍스트를 찾는 기능을 수행합니다. Range 클래스의 createTextFinder()는 한 시트 내의 특정한 범위를 대상으로 텍스트를 검색합니다.
기본 사용 방법
1 2 3 4 5 |
function searchByRange() { const SS = SpreadsheetApp.getActiveSpreadsheet(); const range = SS.getSheetByName('시트 이름').getRange('범위'); const finder = range.createTextFinder('텍스트 또는 변수'); } |
위 코드는 createTextFinder를 특정 시트 안의 특정 범위로 지정합니다. 미리 지정한 시트의 범위 안에서 createTextFinder지정된 텍스트 또는 변수를 검색하는 TextFinder 객체를 생성합니다. 코드는 다음과 같습니다.
1 2 3 4 5 |
function searchByActiveRange() { const SS = SpreadsheetApp.getActiveSpreadsheet(); const range = SS.getActiveRange(); // 현재 활성화된 범위 가져오기 const finder = range.createTextFinder('텍스트 또는 변수'); } |
구글에서 제공하는 공식 레퍼런스는 다음 웹사이트를 참고해주세요.
활용 예시
다음의 스프레드시트는 신규 고객의 정보를 입력하는 시트와 데이터가 저장되는 시트가 동일합니다. 신규 고객의 가입일과 이름, 연락처와 지역을 설정한 뒤에 ‘입력하기’ 버튼을 누르면, 하단에 데이터가 기입이 된다고 예를 들어보겠습니다.
흔한 구조는 아니지만, 스프레드시트가 입력되는 시트와 저장되는 시트가 동일한 탭이면 Spreadsheet 클래스나 Sheet 클래스에서 createTextFinder를 사용하면 어떤 문제가 발생할까요? 고객의 정보를 입력하는 부분에서부터 중복 데이터가 발생할 수 밖에 없습니다. 따라서 아래의 시트에서 Range 클래스를 사용하여 고객 정보를 저장하는 목록의 범위를 지정하고, 데이터를 추가하는 기능을 구현해보겠습니다.
‘신규 고객 추가’ 시트에 있는 ‘입력하기’ 버튼에 할당된 스크립트는 아래와 같습니다. 먼저 getRange() 메소드를 사용해보겠습니다.
코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
function setNewCustomerByRange() { const SS = SpreadsheetApp.getActiveSpreadsheet(); const ADD_CUSTOMER = SS.getSheetByName(‘신규 고객 추가’); const LAST_ROW = ADD_CUSTOMER.getLastRow(); const RANGE = ADD_CUSTOMER.getRange(‘A14:D’ + LAST_ROW); // 입력 데이터를 배열로 가져오기 let [joinDate, name, hp, location] = ADD_CUSTOMER.getRange(‘C3:C6’).getValues().map(row => row[0]); // 중복 데이터 검사 const hpFinder = RANGE.createTextFinder(hp).matchEntireCell(true).findAll(); if (hpFinder.length > 0) { hpFinder.forEach(occurrence => { let sheetName = occurrence.getSheet().getName(); let row = occurrence.getRow(); Logger.log( 이미 가입된 회원입니다: ${sheetName}' 시트의 ${row}행을 참조하세요.) SpreadsheetApp.getUi().alert(‘이미 가입된 회원입니다: \\” + sheetName + ‘\\’ 시트의 ‘ + row + ‘행을 참조하세요.‘); }); } else { const lastRow = RANGE.getLastRow(); // 마지막 행 가져오기 Logger.log(lastRow); RANGE.getSheet().getRange(lastRow +1, 1, 1, 4).setValues([[joinDate, name, hp, location]]); SpreadsheetApp.getUi().alert(‘신규 고객 정보가 추가되었습니다.‘); } } |
코드 설명
getSheetByName('신규 고객 추가')
메소드를 사용하여 ‘신규 고객 추가‘라는 이름의 시트를 가져옵니다.getLastRow()
를 통해 ‘신규 고객 추가‘ 시트에서 데이터가 있는 마지막 행의 번호를 가져옵니다.getRange('A14:D' + LAST_ROW)
‘신규 고객 추가‘ 시트에서 데이터가 입력되어 있는 범위(A14부터 데이터가 존재하는 마지막 행까지)를 정의하였습니다. 데이터가 존재하는 마지막 행의 위치가 담긴 LASW_ROW를 사용하지 않으면 데이터가 존재하지 않는 셀까지 모두 검색하므로 데이터가 존재하는 행까지 범위를 축소하기 위해 LAST_ROW 변수를 사용하였습니다.- 고객 정보를 가져오기 위해
getRange('C3:C6').getValues().map(row => row[0])
를 사용합니다. 이는 ‘신규 고객 추가‘ 시트에서 C3부터 C6까지의 범위에 있는 데이터를 가져와서 배열로 변환합니다. - 지정된 범위에서
createTextFinder
메소드를 사용하여 중복된 전화번호를 찾습니다. 만약 중복된 연락처가 있을 경우, 해당 위치를 로그로 남기고, 알림창을 표시합니다.forEach
문을 사용하여 각 중복되는 값들의 위치 정보를 추출하는 작업을 수행합니다. - 중복된 연락처가 없을 경우, 고객 정보를 ‘신규 고객 추가’ 시트의 목록 범위 마지막 행에 추가합니다.
getLastRow()
는 데이터가 있는 마지막 행을 가져오기 때문에 데이터가 덮어쓰여지는 것을 방지하기 위해 1을 더해주었습니다. - 고객 정보가 추가되었다는 알림창을 표시합니다.
앞서 살펴보았던 Spreadsheet, Sheet 클래스에서 사용될 때와 비슷하지만, 다른 점은 getRange()
를 통해서 범위를 지정한다는 것입니다. 이렇게 getRange()
를 사용하면 같은 시트 내에서도 원하는 범위 안에서만 중복된 데이터를 검색하는 것이 가능합니다.
이제 스크립트를 할당하고 실행해보겠습니다.
이제 한번 실행해볼까요?
고객 정보가 추가되었다는 알림창이 정상적으로 출력되었습니다. 지정된 범위에 데이터가 잘 추가되었네요.
이제 검색 조건인 연락처를 제외한 가입일, 이름, 지역을 바꾼 채로 다시 ‘입력하기’ 버튼을 클릭해보겠습니다. 연락처가 중복이 된다면 데이터의 삽입이 이루어져서는 안되며, 중복된 셀의 위치를 알림창을 통해 전달받아야 합니다. 테스트를 위해 다음의 정보를 입력하였습니다.
‘입력하기’ 버튼을 클릭해보겠습니다.
중복된 연락처를 확인하였고 중복된 셀의 위치를 잘 전달하고 있네요.
로그도 남아있는 것을 확인할 수 있습니다. createTextFinder는 필요한 검색의 범위에 따라 여러 클래스에서 지원하고 있는데, 지금처럼 검색하는 범위를 최소화하여 지정하면 원하는 정보를 정확하고 빠르게 찾을 수 있습니다.
지금까지 3개의 포스트에 걸쳐서 Spreadsheet, Sheet, Range 클래스에서 createTextFinder()를 사용하는 방법을 살펴보았습니다. 앱스 스크립트로 텍스트를 찾는 기능에 다양한 범위까지 지정할 수 있다니 정말 유용한 기능이죠? 하지만 이 뿐만이 아닙니다. createTextFinder()메소드는 다양한 옵션을 지원합니다.
이어지는 포스트에서 TextFinder 클래스에서 제공하는 다양한 옵션을 소개하겠습니다.