Google 스프레드 시트에서 맞춤 함수로 검색 한 데이터 새로 고침


92

id웹 서비스 (가격)를 수신하고 정보를 가져 오는 맞춤 Google Apps 스크립트를 작성했습니다 .

이 스크립트를 스프레드 시트에서 사용하는데 잘 작동합니다. 내 문제는 이러한 가격이 변경되고 내 스프레드 시트가 업데이트되지 않는다는 것입니다.

스크립트를 다시 실행하고 셀을 업데이트하도록 강제 할 수 있습니까 (각 셀을 수동으로 이동하지 않고)?


1
네, 여기에 내가 이것에 한 설명입니다 : stackoverflow.com/questions/9022984/...은
엔리케 G. 아브레유

내 연구의 일환으로 설명을 읽었습니다. 매우 도움이되었습니다. 감사합니다. 내 대답에 대한 링크를 추가했습니다.
tbkn23

유사한 (정의되고 논리적이지만 때로는 불행한) 동작이 발생하는 경우 Google Issue Tracker : issuetracker.google.com/issues/36763858 에서이 기능 요청을 찬성하는 것이 도움이 될 수 있습니다 .
Timothy Johns

여기 내가 한 간단한 대답 이 있습니다.
안테나

답변:


92

좋아, 내 문제는 Google이 이상한 방식으로 작동하는 것 같습니다. 스크립트 매개 변수가 유사한 한 스크립트를 다시 실행하지 않고 이전 실행의 캐시 된 결과를 사용합니다. 따라서 API에 다시 연결하지 않고 가격을 다시 가져 오지 않으며 단순히 캐시 된 이전 스크립트 결과를 반환합니다.

자세한 정보는 https://code.google.com/p/google-apps-script-issues/issues/detail?id=888을 참조하세요.

및 여기 : 업데이트되지 않는 데이터를 요약하는 스크립트

내 해결책은 스크립트에 사용하지 않는 다른 매개 변수를 추가하는 것이 었습니다. 이제 이전 호출과 다른 매개 변수를 사용하여 함수를 호출하면 이러한 매개 변수의 결과가 캐시에 없기 때문에 스크립트를 다시 실행해야합니다.

따라서 함수를 호출 할 때마다 추가 매개 변수에 대해 "$ A $ 1"을 전달합니다. 또한 새로 고침이라는 메뉴 항목을 만들었고 실행하면 현재 날짜와 시간이 A1에 저장되므로 $ A $ 1을 두 번째 매개 변수로 사용하여 스크립트에 대한 모든 호출을 다시 계산해야합니다. 내 스크립트의 코드는 다음과 같습니다.

function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Refresh",
    functionName : "refreshLastUpdate"
  }];
  sheet.addMenu("Refresh", entries);
};

function refreshLastUpdate() {
  SpreadsheetApp.getActiveSpreadsheet().getRange('A1').setValue(new Date().toTimeString());
}

function getPrice(itemId, datetime) {
  var headers =
      {
        "method" : "get",
        "contentType" : "application/json",
        headers : {'Cache-Control' : 'max-age=0'}
      };

  var jsonResponse = UrlFetchApp.fetch("http://someURL?item_id=" + itemId, headers);
  var jsonObj = eval( '(' + jsonResponse + ')' );
  return jsonObj.Price;
  SpreadsheetApp.flush();
}   

그리고 ID가 5 인 항목의 가격을 셀에 넣으려면 다음 공식을 사용합니다.

=getPrice(5, $A$1)

가격을 새로 고침하려면 "새로 고침"-> "새로 고침"메뉴 항목을 클릭하면됩니다. onOpen()스크립트 를 변경 한 후 스프레드 시트를 다시로드해야합니다 .


4
now ()를 추가 매개 변수로 사용하지 않는 이유는 무엇입니까?
고급 '

5
내 함수가 매개 변수가 변경되지 않았기 때문에 (즉, 셀의 값) 재평가되지 않는 것처럼 now ()도 매개 변수가 없기 때문에 재평가되지 않으므로 반환 값은 변경되지 않으므로 내 함수의 매개 변수가 변경되지 않습니다. 또한, 내 기능을 야기 지금 ()를 사용하여 모든 ... 그것은 여러 HTTP 호출을 생성하는 고려 비트 무거운는 시간을 다시 평가
tbkn23

2
잘 찾았습니다. 명명 된 범위를 입력으로 사용하는 동안이 문제가 발생했습니다. 귀하의 답변을 사용하여 "sum (B : D)"에서와 같이 입력 범위에 대해 더미 합계를 전달하는 것이 충분하다는 것을 알아 냈습니다. 여기서 행 BD는 사용자 정의 함수가 조회 한 범위에 있습니다. 셀을 변경하면 합계가 변경되고 사용자 정의 함수가 새로 고쳐집니다. 그건 그렇고, 커스텀 함수는 무시 된 매개 변수를 선언 할 필요조차없는 것 같습니다.
Shawn Hoover

1
이것이 내가이 문제에 대해 찾은 최고의 해결책이라는 점이 아쉽다. Google이 특정 함수 호출에 대해 캐시를 비활성화하도록 허용하는 대신 캐시 된 값을 얻지 못하도록 캐시에 저장되는 내용을 임의로 늘
립니다


33

나는 이것이 약간 오래된 질문이라는 것을 알고 있습니다. 그러나이 방법은 변경하는 것 외에는 사용자 작업이 필요하지 않습니다.

내가 한 일은 tbkn23과 비슷했습니다.

재평가하려는 함수에는 사용되지 않은 추가 매개 변수 $ A $ 1이 있습니다. 그래서 함수 호출은

=myFunction(firstParam, $A$1)

그러나 코드에서 함수 서명은

function myFunction(firstParam)

새로 고침 기능을 사용하는 대신 다음과 같은 onEdit (e) 함수를 사용했습니다.

function onEdit(e)
{
   SpreadsheetApp.getActiveSheet().getRange('A1').setValue(Math.random());
}

이 함수는 스프레드 시트의 셀이 편집 될 때마다 트리거됩니다. 이제 셀을 편집하고 난수를 A1에 배치하면 tbkn23이 제안한대로 매개 변수 목록이 새로 고쳐져 사용자 정의 함수가 재평가됩니다.


5
잘 작동합니다. 단점은 실행 취소 (ctrl + z) 기록이 엉망이라는 것입니다.
Jon

1
존은 지적 ... 내가 :-) 누군가가 그것을 개선 희망 성가신 단점과 멋진 트릭
Enissay

이 답변에 대한 작고 현명한 경고; 믿을 수 없을 정도로 가능성이 낮은 이벤트에서 Math.random은 동일한 숫자를 반환하며, 그 경우에는 특정 숫자가 이미 캐시 되었기 때문에 업데이트되지 않습니다.
Woody Payne

12

이것은 매우 늦어서 유용할지 모르겠지만 실제로 여기에 설정이 있으므로 NOW()자동으로 업데이트 할 수 있습니다.

여기에 이미지 설명 입력


1
NOW()사용자 정의 함수가 아닌 내장 함수입니다.
Rubén

@ Rubén 요점은 업데이트를 원하는 사용자 정의 함수에 NOW () 함수를 포함 할 수 있다는 것입니다.
Thaina

13
이때 사용자 정의 함수 인수는 결정적이어야합니다. 즉, NOW ()를 인수로 할당하지 않습니다. 참조 developers.google.com/apps-script/guides/sheets/functions
루벤

3
사용자 정의 함수 내에서 NOW ()를 사용하려고하면 오류가 발생합니다
Stefano Giacone

6

사용자 정의 함수가 특정 열에있는 경우 해당 열을 기준으로 스프레드 시트를 정렬하면됩니다.

정렬 작업은 데이터를 강제로 새로 고쳐 해당 열의 모든 행에 대해 한 번에 사용자 지정 함수를 호출합니다.


1

이것은 매우 오래된 스레드 일 수 있지만 방금 지금처럼 이것을하려는 누군가에게 유용 할 수 있습니다.

Lexi의 스크립트를있는 그대로 사용하면 현재 Sheets에서는 더 이상 작동하지 않는 것 같지만, 매개 변수로 함수에 더미 변수를 추가하면 (실제로 함수 내에서 사용할 필요가 없음) 실제로 Google 시트가 페이지를 다시 새로 고치도록 강제합니다.

따라서 다음과 같은 선언 : function myFunction (firstParam, dummy) 및 호출은 제안 된대로됩니다. 그것은 나를 위해 일했습니다.

또한 편집하는 모든 시트에 무작위 변수가 나타나는 것이 성가신 경우 한 시트로 제한하는 쉬운 해결 방법은 다음과 같습니다.

function onEdit(e)
{
  e.source.getSheetByName('THESHEETNAME').getRange('J1').setValue(Math.random());
}

1
@ Rubén 그것은 매우 유사하지만 좋은 성가신; 대신 역사를, 그것은 정의 된 시트 이름을 사용하는 활성 시트를 사용하여 개선
조나스 D.

1

스크립트 로직 :

  • 사용자 지정 함수는 인수가 변경되지 않는 한 업데이트되지 않습니다.
  • textFinder를 사용하여 스프레드 시트에있는 모든 사용자 지정 함수의 모든 인수를 변경하는 onChange 트리거를 만듭니다.

단편:

/*@customfunction*/
function sheetNames(e) {
  return SpreadsheetApp.getActive()
    .getSheets()
    .map(function(sheet) {
      return sheet.getName();
    });
}

/*Create a installable trigger to listen to grid changes on the sheet*/
function onChange(e) {
  if (!/GRID/.test(e.changeType)) return; //Listen only to grid change
  SpreadsheetApp.getActive()
    .createTextFinder('=SHEETNAMES\\([^)]*\\)')
    .matchFormulaText(true)
    .matchCase(false)
    .useRegularExpression(true)
    .replaceAllWith(
      '=SHEETNAMES(' + (Math.floor(Math.random() * 500) + 1) + ')'
    );
}

읽다:


1

앞서 언급했듯이 :

사용자 지정 함수는 인수가 변경되지 않는 한 업데이트되지 않습니다.

가능한 해결책은 단일 셀에 확인란을 만들고이 셀을 사용자 지정 함수의 인수로 사용하는 것입니다.

  1. 체크 박스 생성 : [A1]과 같은 자유 셀을 선택하고 [삽입]> [체크 박스]로 이동합니다.
  2. 이 셀을 인수로 만듭니다. =myFunction(A1)
  3. 공식을 새로 고치려면 확인란을 클릭하십시오.

-3

사용자 정의 함수를 작성하고 스프레드 시트에서 공식으로 사용한 경우 스프레드 시트를 열거 나 참조 셀이 수정 될 때마다 공식이 다시 계산됩니다.

스프레드 시트를 계속 주시하고 값을 변경하려면 셀을 업데이트하는 시간 제한 트리거를 추가하는 것이 좋습니다. 여기에서 트리거에 대해 자세히 알아 보세요.


10
작동하지 않는다는 점을 제외하면 아주 좋을 것입니다. 페이지를 새로 고침해도 값이 새로 고쳐지지 않습니다. 또한 셀을 삭제하고 동일한 함수 호출을 다시 입력해도 이전 값이 유지됩니다. 다른 셀에서 정확히 동일한 함수를 호출하면 새 값이 표시되지만 이전 셀에는 표시되지 않습니다.
tbkn23
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.