![見出し画像](https://assets.st-note.com/production/uploads/images/75208610/rectangle_large_type_2_6c6496b29f0b34bccdbb1357ba018903.png?width=1200)
【開発哲学_ちょいとブレイク】〜CODECOMPLETEのここまでの話の復習を兼ねてコード書いてみた
有料にしようかなと思ったけど、無料でw
簡単なコードをゆっくり手直し(=リファクタリング)
していく手順を書いているので長文です🕺
概要
GASで簡単なツールを作って、
作る間に書いたコードを
これまでの内容を加味して、
リファクタリングする過程も含めて紹介。
VBAについては、
も覗いてみてね。
作った機能
正規処理(下の要件を全て満たすもの)
インプットボックスを表示
1 〜 5のいずれかの半角数字を入力
現在の日付が、
明治、大正、昭和、平成、令和で
何年にあたるかを計算
エラー処理(入力ミスの対処)
1 〜 5のいずれかの半角数字以外を入力すると、エラーメッセージを表示。
完成品の画像
実行前
![](https://assets.st-note.com/img/1648457211462-7sbKjRiiXf.png?width=1200)
実行後
![](https://assets.st-note.com/img/1648457211581-xBsWcdx1kN.png?width=1200)
コード(完成形。コピペでOK)
//グローバル
const year = '年';
const ganNen = '元';
const saiMeiji = 1867;
const saiTaisho = 1911;
const saiShowa = 1925;
const saiHeisei = 1988;
const saiReiwa = 2018;
const inputMsgStr = 'いずれかの半角数字を入力。明治:1,大正:2,昭和:3,平成:4,令和:5';
const errorMsgStr = '1~5のいずれかを入力してください。';
let gengo,gengouAry,gengouAryNum,thisYear,wareki,warekiMsg,errorMsg;
function 現在を元号ごとの年数に変換_完成形(){
gengouAry = ['明治','大正','昭和','平成','令和'];
gengouAryNum = Browser.inputBox(inputMsgStr);
if(gengouAryNum == 1 || gengouAryNum == 2 || gengouAryNum == 3 ||
gengouAryNum == 4 || gengouAryNum == 5){
gengouAryNum = gengouAryNum - 1;
switch (gengouAryNum){
case 0:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiMeiji;
元号判定_(gengo,thisYear,year);
break;
case 1:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiTaisho;
元号判定_(gengo,thisYear,year);
break;
case 2:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiShowa;
元号判定_(gengo,thisYear,year);
break;
case 3:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiHeisei;
元号判定_(gengo,thisYear,year);
break;
case 4:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiReiwa;
元号判定_(gengo,thisYear,year);
break;
}
} else {
errorMsg = Browser.msgBox(errorMsgStr);
}
}
function 元号判定_(gengo,thisYear,year){
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
return;
}
コード作成手順
まずはif文で書いてみると、
function 現在を元号ごとの年数に変換_If文(){
let gengo,gengouAry,gengouAryNum,thisYear,wareki,warekiMsg,errorMsg;
gengouAry = ['明治','大正','昭和','平成','令和'];
gengouAryNum = Browser.inputBox('いずれかの半角数字を入力。明治:1,大正:2,昭和:3,平成:4,令和:5');
if(gengouAryNum == 1 || gengouAryNum == 2 || gengouAryNum == 3 ||
gengouAryNum == 4 || gengouAryNum == 5){
gengouAryNum = gengouAryNum - 1;
if(gengouAryNum == 0){
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - 1867;
} else if(gengouAryNum == 1){
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - 1911;
} else if(gengouAryNum == 2){
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - 1925;
} else if(gengouAryNum == 3){
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - 1988;
} else if(gengouAryNum == 4){
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - 2018;
}
if(thisYear == 1){
thisYear = '元';
}
wareki = gengo + thisYear + '年';
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
} else {
errorMsg = Browser.msgBox('1~5のいずれかを入力してください。');
}
}
定型句を改修しやすいように、
マジックナンバーやマジック文字列対策で、
function 現在を元号ごとの年数に変換_If文マジック対策(){
const year = '年';
const ganNen = '元';
const saiMeiji = 1867;
const saiTaisho = 1911;
const saiShowa = 1925;
const saiHeisei = 1988;
const saiReiwa = 2018;
const inputMsgStr = 'いずれかの半角数字を入力。明治:1,大正:2,昭和:3,平成:4,令和:5';
const errorMsgStr = '1~5のいずれかを入力してください。';
let gengo,gengouAry,gengouAryNum,thisYear,wareki,warekiMsg,errorMsg;
gengouAry = ['明治','大正','昭和','平成','令和'];
gengouAryNum = Browser.inputBox(inputMsgStr);
if(gengouAryNum == 1 || gengouAryNum == 2 || gengouAryNum == 3 ||
gengouAryNum == 4 || gengouAryNum == 5){
gengouAryNum = gengouAryNum - 1;
if(gengouAryNum == 0){
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiMeiji;
} else if(gengouAryNum == 1){
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiTaisho;
} else if(gengouAryNum == 2){
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiShowa;
} else if(gengouAryNum == 3){
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiHeisei;
} else if(gengouAryNum == 4){
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiReiwa;
}
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
} else {
errorMsg = Browser.msgBox(errorMsgStr);
}
}
動きはするけど、場合分けが多く、
コードが冗長
なので、Switch文にする。
if文をSwitch文に変えただけ
function 現在を元号ごとの年数に変換_Switch文に変えただけ(){
const year = '年';
const ganNen = '元';
const saiMeiji = 1867;
const saiTaisho = 1911;
const saiShowa = 1925;
const saiHeisei = 1988;
const saiReiwa = 2018;
const inputMsgStr = 'いずれかの半角数字を入力。明治:1,大正:2,昭和:3,平成:4,令和:5';
const errorMsgStr = '1~5のいずれかを入力してください。';
let gengo,gengouAry,gengouAryNum,thisYear,wareki,warekiMsg,errorMsg;
gengouAry = ['明治','大正','昭和','平成','令和'];
gengouAryNum = Browser.inputBox(inputMsgStr);
if(gengouAryNum == 1 || gengouAryNum == 2 || gengouAryNum == 3 ||
gengouAryNum == 4 || gengouAryNum == 5){
gengouAryNum = gengouAryNum - 1;
switch (gengouAryNum){
case 0:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiMeiji;
case 1:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiTaisho;
case 2:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiShowa;
case 3:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiHeisei;
case 4:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiReiwa;
}
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
} else {
errorMsg = Browser.msgBox(errorMsgStr);
}
}
だいぶスッキリしたけど、実行してみると、
![](https://assets.st-note.com/img/1648533190082-vavAOem1J8.png)
元号ごとの判定をSwitch文の内側に埋め込む
function 現在を元号ごとの年数に変換_Switch文に元号判定はめ込み(){
const year = '年';
const ganNen = '元';
const saiMeiji = 1867;
const saiTaisho = 1911;
const saiShowa = 1925;
const saiHeisei = 1988;
const saiReiwa = 2018;
const inputMsgStr = 'いずれかの半角数字を入力。明治:1,大正:2,昭和:3,平成:4,令和:5';
const errorMsgStr = '1~5のいずれかを入力してください。';
let gengo,gengouAry,gengouAryNum,thisYear,wareki,warekiMsg,errorMsg;
gengouAry = ['明治','大正','昭和','平成','令和'];
gengouAryNum = Browser.inputBox(inputMsgStr);
if(gengouAryNum == 1 || gengouAryNum == 2 || gengouAryNum == 3 ||
gengouAryNum == 4 || gengouAryNum == 5){
gengouAryNum = gengouAryNum - 1;
switch (gengouAryNum){
case 0:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiMeiji;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
case 1:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiTaisho;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
case 2:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiShowa;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
case 3:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiHeisei;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
case 4:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiReiwa;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
}
} else {
errorMsg = Browser.msgBox(errorMsgStr);
}
}
実行してみると、
![](https://assets.st-note.com/img/1648533352851-FsHJzJSWrT.png)
![](https://assets.st-note.com/img/1648533434510-z9wbHLYKK4.png)
![](https://assets.st-note.com/img/1648533470736-9YEP4CVdx2.png)
![](https://assets.st-note.com/img/1648533488391-gNd3vaXhKn.png)
![](https://assets.st-note.com/img/1648533509380-RJ1JPpBU7Q.png)
実は、
Switch文ではよくやりがちなんだけど、これは
各case文の間にbreak文を挟まないので、起きる現象 = フォールスルー
各caseの間に、break文を挟む
function 現在を元号ごとの年数に変換_各caseにbreak(){
const year = '年';
const ganNen = '元';
const saiMeiji = 1867;
const saiTaisho = 1911;
const saiShowa = 1925;
const saiHeisei = 1988;
const saiReiwa = 2018;
const inputMsgStr = 'いずれかの半角数字を入力。明治:1,大正:2,昭和:3,平成:4,令和:5';
const errorMsgStr = '1~5のいずれかを入力してください。';
let gengo,gengouAry,gengouAryNum,thisYear,wareki,warekiMsg,errorMsg;
gengouAry = ['明治','大正','昭和','平成','令和'];
gengouAryNum = Browser.inputBox(inputMsgStr);
if(gengouAryNum == 1 || gengouAryNum == 2 || gengouAryNum == 3 ||
gengouAryNum == 4 || gengouAryNum == 5){
gengouAryNum = gengouAryNum - 1;
switch (gengouAryNum){
case 0:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiMeiji;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
break;
case 1:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiTaisho;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
break;
case 2:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiShowa;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
break;
case 3:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiHeisei;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
break;
case 4:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiReiwa;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
break;
}
} else {
errorMsg = Browser.msgBox(errorMsgStr);
}
}
とやると、実行後
![](https://assets.st-note.com/img/1648533755959-IO5m3YmcsD.png)
![](https://assets.st-note.com/img/1648533796138-xeZN8tpdoi.png?width=1200)
念のため、他の元号も試すと、
![](https://assets.st-note.com/img/1648533867765-IuVGAS6e3z.png)
![](https://assets.st-note.com/img/1648533952849-hJN1LKTY48.png)
![](https://assets.st-note.com/img/1648533961906-97NCsjflaR.png)
![](https://assets.st-note.com/img/1648533971347-FVeZXFaWsp.png)
で、確認できた。
このままだと
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
の部分が重複していて、引数
const year = '年';
const ganNen = '元';
const saiMeiji = 1867;
const saiTaisho = 1911;
const saiShowa = 1925;
const saiHeisei = 1988;
const saiReiwa = 2018;
const inputMsgStr = 'いずれかの半角数字を入力。明治:1,大正:2,昭和:3,平成:4,令和:5';
const errorMsgStr = '1~5のいずれかを入力してください。';
let gengo,gengouAry,gengouAryNum,thisYear,wareki,warekiMsg,errorMsg;
が冗長で、メインの処理が見にくい。
そこで、
繰り返される処理を
関数名の後、()の前に'_'(:アンダースコア)
付きでルーチン化
function 元号判定_(gengo,thisYear,year){
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
return;
}
して、引数をグローバル化
//グローバル
const year = '年';
const ganNen = '元';
const saiMeiji = 1867;
const saiTaisho = 1911;
const saiShowa = 1925;
const saiHeisei = 1988;
const saiReiwa = 2018;
const inputMsgStr = 'いずれかの半角数字を入力。明治:1,大正:2,昭和:3,平成:4,令和:5';
const errorMsgStr = '1~5のいずれかを入力してください。';
let gengo,gengouAry,gengouAryNum,thisYear,wareki,warekiMsg,errorMsg;
しておくと、実行できる処理が
function 現在を元号ごとの年数に変換_完成形(){
gengouAry = ['明治','大正','昭和','平成','令和'];
gengouAryNum = Browser.inputBox(inputMsgStr);
if(gengouAryNum == 1 || gengouAryNum == 2 || gengouAryNum == 3 ||
gengouAryNum == 4 || gengouAryNum == 5){
gengouAryNum = gengouAryNum - 1;
switch (gengouAryNum){
case 0:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiMeiji;
元号判定_(gengo,thisYear,year);
break;
case 1:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiTaisho;
元号判定_(gengo,thisYear,year);
break;
case 2:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiShowa;
元号判定_(gengo,thisYear,year);
break;
case 3:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiHeisei;
元号判定_(gengo,thisYear,year);
break;
case 4:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiReiwa;
元号判定_(gengo,thisYear,year);
break;
}
} else {
errorMsg = Browser.msgBox(errorMsgStr);
}
}
になる。
仮に元号が増えたら、
配列要素を追加
配列要素の数に応じたcase文を増やす
だけだから、変更しやすさもOK。
まとめ(コード比較)
どちらが見やすいか最終的には、お好みで〜〜〜🕺
分割前
function 現在を元号ごとの年数に変換_各caseにbreak(){
const year = '年';
const ganNen = '元';
const saiMeiji = 1867;
const saiTaisho = 1911;
const saiShowa = 1925;
const saiHeisei = 1988;
const saiReiwa = 2018;
const inputMsgStr = 'いずれかの半角数字を入力。明治:1,大正:2,昭和:3,平成:4,令和:5';
const errorMsgStr = '1~5のいずれかを入力してください。';
let gengo,gengouAry,gengouAryNum,thisYear,wareki,warekiMsg,errorMsg;
gengouAry = ['明治','大正','昭和','平成','令和'];
gengouAryNum = Browser.inputBox(inputMsgStr);
if(gengouAryNum == 1 || gengouAryNum == 2 || gengouAryNum == 3 ||
gengouAryNum == 4 || gengouAryNum == 5){
gengouAryNum = gengouAryNum - 1;
switch (gengouAryNum){
case 0:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiMeiji;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
break;
case 1:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiTaisho;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
break;
case 2:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiShowa;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
break;
case 3:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiHeisei;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
break;
case 4:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiReiwa;
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
break;
}
} else {
errorMsg = Browser.msgBox(errorMsgStr);
}
}
分割後(完成形のコードと同じ)
//グローバル
const year = '年';
const ganNen = '元';
const saiMeiji = 1867;
const saiTaisho = 1911;
const saiShowa = 1925;
const saiHeisei = 1988;
const saiReiwa = 2018;
const inputMsgStr = 'いずれかの半角数字を入力。明治:1,大正:2,昭和:3,平成:4,令和:5';
const errorMsgStr = '1~5のいずれかを入力してください。';
let gengo,gengouAry,gengouAryNum,thisYear,wareki,warekiMsg,errorMsg;
function 現在を元号ごとの年数に変換_完成形(){
gengouAry = ['明治','大正','昭和','平成','令和'];
gengouAryNum = Browser.inputBox(inputMsgStr);
if(gengouAryNum == 1 || gengouAryNum == 2 || gengouAryNum == 3 ||
gengouAryNum == 4 || gengouAryNum == 5){
gengouAryNum = gengouAryNum - 1;
switch (gengouAryNum){
case 0:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiMeiji;
元号判定_(gengo,thisYear,year);
break;
case 1:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiTaisho;
元号判定_(gengo,thisYear,year);
break;
case 2:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiShowa;
元号判定_(gengo,thisYear,year);
break;
case 3:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiHeisei;
元号判定_(gengo,thisYear,year);
break;
case 4:
gengo = gengouAry[gengouAryNum];
thisYear = new Date().getFullYear() - saiReiwa;
元号判定_(gengo,thisYear,year);
break;
}
} else {
errorMsg = Browser.msgBox(errorMsgStr);
}
}
function 元号判定_(gengo,thisYear,year){
if(thisYear == 1){
thisYear = ganNen;
}
wareki = gengo + thisYear + year;
warekiMsg = Browser.msgBox('現在は、'+ wareki + 'です。');
return;
}
以上です✨