[]
        
(Showing Draft Content)

목표값 찾기

목표값 찾기는 가상 분석의 단일 변수 역분석 도구입니다.

종속 수식 셀이 지정된 숫자 결과를 생성하는 데 필요한 하나의 입력 셀 값을 결정합니다. 입력값 변화에 따라 결과가 어떻게 달라지는지 평가하는 대신, 목표값 찾기는 목표 결과에서 시작하여 해당 결과를 만족하는 입력값을 반복 계산하여 찾습니다.

목표값 찾기는 원하는 결과는 알고 있지만 필요한 입력값은 모를 때 유용합니다.

개념적 모델

목표값 찾기는 세 가지 요소를 기반으로 동작합니다.

  • 변경 셀(Changing cell) – 조정할 입력값입니다.

  • 수식 셀(Formula cell) – 변경 셀에 종속된 수식을 포함하는 셀입니다.

  • 목표 결과(Desired result) – 수식 셀이 계산해야 하는 숫자 값입니다.

해를 찾으면 변경 셀은 계산된 값으로 업데이트됩니다.

해를 찾지 못하면 원래 값이 복원됩니다.

목표값 찾기는 하나의 변수에 대해서만 해를 구합니다.

기본 프로그래밍 사용법

목표값 찾기는 GC.Spread.Sheets.CalcEngine.goalSeek 메서드를 사용하여 프로그래밍 방식으로 호출할 수 있습니다.

// 대출 금액: 10000
// 기간: 18개월
sheet.setValue(0, 1, 10000);
sheet.setValue(1, 1, 18);
sheet.setFormatter(2, 1, "0%");
sheet.setFormula(3, 1, "-PMT(B3/12, B2, B1)");

// B4가 600이 되도록 B3 계산
GC.Spread.Sheets.CalcEngine.goalSeek(
  sheet, 2, 1,   // 변경 셀 (B3)
  sheet, 3, 1,   // 수식 셀 (B4)
  600            // 목표 결과
);

기본값:

  • 최대 반복 횟수: 200

  • 허용 오차: 0.001

해를 찾으면 true, 그렇지 않으면 false를 반환합니다(비동기 시나리오에 대해서는 아래 실행 모델 참조).

고급 반복 제어

목표값 찾기는 선택적 options 매개변수를 통해 고급 반복 제어를 지원합니다. 이를 통해 수렴 동작, 정밀도 및 실행 중 관찰을 세밀하게 제어할 수 있습니다.

수렴 제어

다음 옵션을 사용하여 수치 계산 동작을 조정할 수 있습니다.

  • maximumIterations — 반복 횟수 제한

  • tolerance — 수식 결과와 목표 결과 간 허용 가능한 차이

예제:

GC.Spread.Sheets.CalcEngine.goalSeek(
  sheet, 2, 1,
  sheet, 3, 1,
  600,
  {
    maximumIterations: 500,
    tolerance: 1e-8
  }
);

고정밀 금융 또는 엔지니어링 시나리오에서는 더 엄격한 허용 오차를 사용하세요.

각 반복 단계 관찰

callback 옵션을 사용하면 내부 반복 과정을 관찰할 수 있습니다.

콜백은 다음 정보를 포함한 단계 정보를 전달받습니다.

  • 현재 반복 인덱스

  • 현재 변경 셀 값

  • 현재 수식 결과

  • 현재까지 유효한 해를 찾았는지 여부

예제:

GC.Spread.Sheets.CalcEngine.goalSeek(
  sheet, 2, 1,
  sheet, 3, 1,
  600,
  {
    callback: (info) => {
      console.log(
        `iter=${info.currentIteration}, ` +
        `x=${info.currentValue}, ` +
        `f(x)=${info.currentFormulaResult}, ` +
        `succeeded=${info.succeeded}`
      );
    }
  }
);

이를 통해 다음이 가능합니다.

  • 로깅 및 진단

  • 교육용 시연

  • 수렴 과정의 실시간 시각화

조기 종료 및 비동기 제어

콜백이 true를 반환하면 목표값 찾기는 즉시 중지되고 현재 값을 유지합니다.

콜백은 비동기 함수일 수도 있습니다. Promise를 반환하면 목표값 찾기는 다음 반복으로 진행하기 전에 Promise가 완료될 때까지 대기합니다.


예제:

GC.Spread.Sheets.CalcEngine.goalSeek(
  sheet, 2, 1,
  sheet, 3, 1,
  600,
  {
    callback: async (info) => {
      await new Promise(r => setTimeout(r, 100));
      if (Math.abs(info.currentFormulaResult / 600 - 1) < 1e-10) {
        return true; // 조기 종료
      }
    }
  }
);

이를 통해 다음이 가능합니다.

  • 수렴 과정 애니메이션

  • 대화형 중지 로직

  • 동적 허용 오차 전략

실행 모델

반환 값

  • boolean — 동기 실행 시 반환

  • Promise — 다음 경우 반환

    • 점진적 계산이 활성화된 경우 또는

    • 비동기 콜백이 제공된 경우

Promise는 해를 찾으면 true, 그렇지 않으면 false로 확인됩니다.

화면 갱신(Paint) 동작

  • 동기 실행의 경우 성능 향상을 위해 SpreadJS가 내부적으로 suspendPaint / resumePaint를 사용합니다.

  • Promise 기반 실행의 경우 화면 갱신이 자동으로 중지되지 않습니다. 필요한 경우 직접 suspendPaint를 호출할 수 있습니다.

계산 모드 처리

통합 문서의 계산 모드가 auto가 아니면 목표값 찾기는 실행 중 일시적으로 auto로 전환하고 완료 후 원래 모드로 복원합니다.

동작 제약 사항

  • 목표 결과는 유한한 숫자 값이어야 합니다.

  • 목표값 찾기에 사용되는 수식은 동기적으로 계산되어야 합니다.

  • 비동기 수식은 지원되지 않습니다.

  • 목표값 찾기는 동적 배열의 확장 셀(Spilled Cell)을 지원합니다.

  • Promise 기반 시나리오에서는 SJS.TABLE을 지원합니다.

  • 런타임 API 호출은 실행 취소를 지원하지 않습니다.

    Designer UI에서는 목표값 찾기 작업에 대한 실행 취소를 지원합니다.

  • 협업 시나리오:

    • 런타임 API는 반복 과정 중 임시 업데이트를 전송합니다.

    • Designer는 확인 후 최종 결과만 전송합니다.

해를 찾지 못하면 변경 셀의 원래 값이 복원됩니다.

알고리즘 참고 사항

SpreadJS는 자체 수치 계산 전략을 사용합니다.

  • 먼저 할선법(Secant Method)을 시도합니다.

  • 필요한 경우 이분법(Bisection Method)으로 전환합니다.

구현 방식의 차이로 인해 결과가 Microsoft Excel과 다를 수 있습니다.

Excel이 검색 전략의 한계로 인해 해를 찾지 못하는 경우에도 SpreadJS는 성공적으로 수렴할 수 있습니다.