[]
SpreadJS는 수식과 셀 간의 관계를 표시함으로써 수식 분석을 광범위하게 지원합니다. 이는 워크시트에서 선행 셀(Precedent) 및 종속 셀(Dependent)을 추적함으로써 수행할 수 있습니다.
수식 분석은 사용자가 스프레드시트 작업 시 계산 병목 지점을 식별하고, 수식을 디버깅하며, 결과의 정확성을 검증하는 데 도움을 줍니다. 또한 이 기능은 사용자에게 다음과 같은 도움을 줍니다:
규정 준수 유지 – 금융, 회계 및 기타 복잡한 애플리케이션 작업 시, 수식 감사 기능은 규정 준수를 유지하는 데 유용합니다.
오류 확인 – 수식 감사는 오류의 원인을 식별하는 데 도움을 줍니다. 특히 워크시트 내 수식이 선행 셀 또는 종속 셀을 사용하는 경우 오류 원인을 찾는 것은 매우 어려운 작업입니다.
순환 참조 위치 확인 – 수식 감사를 통해 선행 셀과 종속 셀을 추적함으로써 모든 순환 참조를 빠르게 찾아내어 수시간의 작업 시간을 절약할 수 있습니다.
불일치 탐지 – 대규모 워크시트에서 사용자는 데이터를 검증할 때 수식을 하나하나 수동으로 검토하지 않고도 열 내 수식의 불일치를 추정할 수 있습니다.
선행 셀(Precedent)은 다른 셀에 있는 수식에서 참조되는 셀입니다. 종속 셀(Dependent)은 수식을 포함하고 다른 셀을 참조하는 셀입니다. 예를 들어, 셀 D10에 수식 "=B5"가 포함되어 있다면, 셀 B5는 D10의 선행 셀이며, 셀 D10은 B5의 종속 셀이 됩니다.
워크시트에서 수식을 감사할 때, getPrecedents()
메서드를 사용하여 선행 셀을 추적하고 getDependents()
메서드를 사용하여 종속 셀을 추적함으로써 선택한 수식 셀과 관련된 셀을 시각화하고 표시할 수 있습니다.
예를 들어, 금융 또는 은행 애플리케이션에서 월별 거래(입금 및 출금)를 스프레드시트 내 수식을 사용해 분석하고 고객별로 월별 보고서를 생성한다고 가정해 봅시다. 이 경우, 단 하나의 평가 오류도 손실로 직결될 수 있으므로 고객에게 월별 회계 보고서를 공유하기 전에 수식을 감사하는 것이 필수적입니다.
아래 이미지는 각 거래에 대해 수식을 사용하여 잔액을 계산하고, 마지막 열의 셀을 클릭할 때 선행 셀 및 종속 셀이 강조 표시되는 소규모 금융 애플리케이션을 보여줍니다.
다음 코드 샘플은 워크시트 내 선행 셀과 종속 셀을 강조 표시하는 예입니다.
var oldPrecedentCells, oldDependentCells;
$(document).ready(function () {
// Spread 초기화
var spread = new GC.Spread.Sheets.Workbook($("#sampleDiv")[0], { autoFitType: GC.Spread.Sheets.AutoFitType.cellWithHeader });
// 시트에 데이터 소스 설정
var jsonArray = [
{
" DATE ": " 3-Oct-17 ",
" TRANSACTION DETAILS ": " INDO GIBL Indiaforensic STL28091 ",
" WITHDRAWAL AMOUNT ": 12106.00,
" DEPOSIT AMOUNT ": 1000000.00,
" BALANCE AMOUNT ": ""
},
{
" DATE ": " 3-Oct-17 ",
" TRANSACTION DETAILS ": " INDO GIBL Indiaforensic STL29091 ",
" WITHDRAWAL AMOUNT ": 12611.00,
" DEPOSIT AMOUNT ": 1000000.0,
" BALANCE AMOUNT ": ""
},
{
" DATE ": " 5-Oct-17 ",
" TRANSACTION DETAILS ": " INDO GIBL Indiaforensic STL04101 ",
" WITHDRAWAL AMOUNT ": 61400.00,
" DEPOSIT AMOUNT ": null,
" BALANCE AMOUNT ": ""
},
{
" DATE ": " 16-Oct-17 ",
" TRANSACTION DETAILS ": " FDRL/INTERNAL FUND TRANSFE ",
" WITHDRAWAL AMOUNT ": null,
" DEPOSIT AMOUNT ": 500000.00,
" BALANCE AMOUNT ": "",
},
{
" DATE ": " 17-Oct-17 ",
" TRANSACTION DETAILS ": " INDO GIBL Indiaforensic STL06101 ",
" WITHDRAWAL AMOUNT ": 6000.00,
" DEPOSIT AMOUNT ": null,
" BALANCE AMOUNT ": "",
},
{
" DATE ": " 17-Oct-17 ",
" TRANSACTION DETAILS ": " INDO GIBL Indiaforensic STL07101 ",
" WITHDRAWAL AMOUNT ": 97950.00,
" DEPOSIT AMOUNT ": null,
" BALANCE AMOUNT ": ""
},
{
" DATE ": " 18-Oct-17 ",
" TRANSACTION DETAILS ": " INDO GIBL Indiaforensic STL17101 ",
" WITHDRAWAL AMOUNT ": 206501.00,
" DEPOSIT AMOUNT ": null,
" BALANCE AMOUNT ": ""
},
{
" DATE ": " 21-Oct-17 ",
" TRANSACTION DETAILS ": " FDRL/INTERNAL FUND TRANSFE ",
" WITHDRAWAL AMOUNT ": null,
" DEPOSIT AMOUNT ": 500000.00,
" BALANCE AMOUNT ": ""
},
{
" DATE ": " 23-Oct-17 ",
" TRANSACTION DETAILS ": " INDO GIBL Indiaforensic STL21101 ",
" WITHDRAWAL AMOUNT ": 39000.00,
" DEPOSIT AMOUNT ": null,
" BALANCE AMOUNT ": ""
},
{
" DATE ": " 26-Oct-17 ",
" TRANSACTION DETAILS ": " INDO GIBL Indiaforensic STL25101 ",
" WITHDRAWAL AMOUNT ": 170125.00,
" DEPOSIT AMOUNT ": null,
" BALANCE AMOUNT ": ""
},
{
" DATE ": " 27-Oct-17 ",
" TRANSACTION DETAILS ": "INDO GIBL Indiaforensic STL26101",
" WITHDRAWAL AMOUNT ": 208000.00,
" DEPOSIT AMOUNT ": null,
" BALANCE AMOUNT ": ""
},
{
" DATE ": " 30-Oct-17 ",
" TRANSACTION DETAILS ": " FDRL/INTERNAL FUND TRANSFE ",
" WITHDRAWAL AMOUNT ": null,
" DEPOSIT AMOUNT ": 500000.00,
" BALANCE AMOUNT ": ""
}
];
var activeSheet = spread.getActiveSheet();
activeSheet.setDataSource(jsonArray);
// 시트 설정 구성
activeSheet.getRange(0, 2, 12, 3).formatter('* #.00');
for (var c = 0; c < activeSheet.getColumnCount(); c++)
{
activeSheet.autoFitColumn(c);
}
// 셀 수식 설정
activeSheet.setFormula(0, 4, "D2");
for (var r = 1; r < activeSheet.getRowCount(); r++) {
activeSheet.setFormula(r, 4, "E" + r.toString() + "+ D" + (r + 1).toString() + "- C" + (r + 1).toString());
}
// 선택된 셀의 선행 셀 및 종속 셀 추적
activeSheet.bind(GC.Spread.Sheets.Events.SelectionChanging, function (e, info)
{
spread.suspendPaint();
var newRow = info.newSelections[0].row;
var newCol = info.newSelections[0].col;
ColorPrecedents(activeSheet, newRow, newCol);
ColorDependents(activeSheet, newRow, newCol);
spread.resumePaint();
});
});
// 선행 셀을 노란색으로 표시
function ColorPrecedents(sheet, row, col)
{
if (oldPrecedentCells)
{
oldPrecedentCells.forEach(function (node)
{
sheet.getCell(node.row, node.col).backColor(undefined);
});
}
var precedentCells = sheet.getPrecedents(row, col);
if (precedentCells)
{
setTimeout(function ()
{
oldPrecedentCells = precedentCells;
precedentCells.forEach(function (node) {
sheet.getCell(node.row, node.col).backColor("yellow");});}, 10);
}
}
// 종속 셀을 초록색으로 표시
function ColorDependents(sheet, row, col)
{
if (oldDependentCells)
{
oldDependentCells.forEach(function (node) {
sheet.getCell(node.row, node.col).backColor(undefined);
});
}
var dependentCells = sheet.getDependents(row, col);
oldDependentCells = dependentCells;
if (dependentCells) {
dependentCells.forEach(function (node) {
sheet.getCell(node.row, node.col).backColor("green");
});
}
}