Windows7 の電卓についていたアレ (住宅ローンの計算)

# Windows7 の電卓についていたアレ (住宅ローンの計算)

Windows7 の電卓についていた住宅ローンの計算が Windows10 で見当たらないので、HTML と JavaScript で再現してみました。
下記のソースをUTF-8で保存後、Microsoft Edge 等のブラウザで読み込んでご利用ください。
計算精度は素の JavaScript のままですので、小数点以下の細かいところは本家の電卓と一致していません。

![loan.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513949/ca0d865e-b9bb-ffcd-c35e-4263cbd3616c.png)


```html:calc_loan.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta charset="UTF-8" />
  <title>Windows7 の電卓についていたアレ (住宅ローンの計算)</title>
<script type="text/javascript">
'use strict';
(function(window, document) {
//==================================================================================================
let $ = e => document.getElementById(e);
//==================================================================================================
class MyLoan {
	constructor() {
		this.Price = 0;				//購入価格
		this.Deposit = 0;			//頭金
		this.Years = 0;				//期間 (年数)
		this.YearRate = 0;			//利率 (%)
		this.PerMonthPayment = 0;	//毎月の支払い
	}

	//購入価格
	Calc_Price() {
		const manth_rate = this.YearRate / 100 / 12;	//月あたりの利率
		const payment_num = this.Years * 12;			//支払い回数

		this.Price = this.Deposit + 
			(this.PerMonthPayment * ((1 + manth_rate) ** payment_num - 1)) / (manth_rate * ((1 + manth_rate) ** payment_num));
		return this.Price;
	}

	//頭金
	Calc_Deposit() {
		const manth_rate = this.YearRate / 100 / 12;
		const payment_num = this.Years * 12;

		this.Deposit = this.Price - 
			(this.PerMonthPayment * ((1 + manth_rate) ** payment_num - 1)) / (manth_rate * ((1 + manth_rate) ** payment_num));
		return this.Deposit;
	}

	//期間 (年数)
	Calc_Years() {
		const manth_rate = this.YearRate / 100 / 12;

		//rate = (1 + manth_rate) ** payment_num;
		let rate = this.PerMonthPayment / (this.PerMonthPayment - (this.Price - this.Deposit) * manth_rate);
		if (rate <= 0) { return "error: 毎月の支払い額が不足しています"; }
		let payment_num = Math.log(rate) / Math.log(1 + manth_rate);

		this.Years = payment_num / 12;
		return this.Years;
	}

	//毎月の支払い額
	Calc_PerMonthPayment() {
		const manth_rate = this.YearRate / 100 / 12;
		const payment_num = this.Years * 12;

		this.PerMonthPayment = (this.Price - this.Deposit) * manth_rate * ((1 + manth_rate) ** payment_num) 
			/ ((1 + manth_rate) ** payment_num - 1);
		return this.PerMonthPayment;
	}
}
//==================================================================================================
window.onload = function() {
	$("selType").onchange = () => {
		const calctype = $("selType").options[$("selType").selectedIndex].value;
		$("txtResult").value = $("txt" + calctype).value;
		$("tr" + $("hidCurrentType").value).style.visibility = "visible";
		$("hidCurrentType").value = calctype;
		$("tr" + calctype).style.visibility ="collapse";
	}

	$("btnCalc").onclick = () => {
		const objLoan = new MyLoan();
		objLoan.Price = $("txtPrice").value - 0;						//購入価格
		objLoan.Deposit = $("txtDeposit").value - 0;					//頭金
		objLoan.Years = $("txtYears").value - 0;						//期間 (年数)
		objLoan.YearRate = $("txtYearRate").value - 0;					//利率 (%)
		objLoan.PerMonthPayment = $("txtPerMonthPayment").value - 0;	//毎月の支払い

		const calctype = $("selType").options[$("selType").selectedIndex].value;
		switch (calctype) {
			case "Years":
				$("txtResult").value = objLoan.Calc_Years();
				$("txtYears").value = $("txtResult").value;
				break;
			case "Price":
				$("txtResult").value = objLoan.Calc_Price();
				$("txtPrice").value = $("txtResult").value;
				break;
			case "Deposit":
				$("txtResult").value = objLoan.Calc_Deposit();
				$("txtDeposit").value = $("txtResult").value;
				break;
			case "PerMonthPayment":
				$("txtResult").value = objLoan.Calc_PerMonthPayment();
				$("txtPerMonthPayment").value = $("txtResult").value;
				break;
		}
	}
}
//==================================================================================================
})(window, document);
</script>
<style type="text/css">
 h1 { font-size:x-large;margin-bottom:0; }
 input[type="button"] { margin-left:0px;width:100px; }
 #tbLoan { border: solid 1px #222222; }
 #tbLoan input[type="number"] { margin-left:0px;margin-right:0px;width:96%; }
 #tbLoan input[type="text"] { margin-left:0px;margin-right:0px;width:96%; }
 #trYears { visibility:collapse; }
 input[type="number"]:invalid { border:solid 3px red; outline:0; }
</style>
</head>
<body style1="padding-top:0px;margin-top:0px;">
<h1>Windows7 の電卓についていたアレ (ワークシート > 住宅ローン)</h1>
※計算精度は生JavaScriptのままです。<br />
<br />
<table id="tbLoan" style="width:450px;">
  <tr><td colspan="2">計算する値を選択してください</td></tr>
  <tr>
    <td colspan="2">
      <select id="selType" style="width:100%;">
        <option id="optYears" value="Years">期間 (年数)</option>
        <option id="optPrice" value="Price">購入価格</option>
        <option id="optDeposit" value="Deposit">頭金</option>
        <option id="optPerMonthPayment" value="PerMonthPayment">毎月の支払い額</option>
      </select>
    </td>
  </tr>
  <tr id="trPrice"><td>購入価格</td><td><input type="number" id="txtPrice" min="0" value="" /></td></tr>
  <tr id="trDeposit"><td>頭金</td><td><input type="number" id="txtDeposit" min="0" value="" /></td></tr>
  <tr id="trYears"><td>期間 (年数)</td><td><input type="number" id="txtYears" min="0" value="" /></td></tr>
  <tr id="trYearRate"><td>利子率 (％)</td><td><input type="number" id="txtYearRate" step="0.0001" value="" /></td></tr>
  <tr id="trPerMonthPayment"><td>毎月の支払い額</td><td><input type="number" id="txtPerMonthPayment" min="0" value="" /></td></tr>
  <tr><td>&nbsp;</td><td></td></tr>
  <tr><td><input type="button" id="btnCalc" value="計算" /></td><td><input type="text" id="txtResult" value="" readonly="readonly" /></td></tr>
</table>

<input type="hidden" id="hidCurrentType" value="Years" />
</body>
</html>

```