現状、断面性能のタイプの場合分けはアドイン側のコードで行っているが、アドイン側はできるだけExcel処理に専念してもらい、数値計算についてはライブラリ側で行いたい。 そこで場合分けについてもライブラリへ移行することを考える。
アドインでは、人が入力するために、文字列での場合分けを行ったが、開発時の表記ゆれなどによるタイプミスなどを減らすためにEnumで場合分けをしていきたいと思う。
しかし、Enumの使い方を検索すると「TypeSciriptでEnumは使うな!」みたいな記事がたくさんヒットする。例えばこんなのとか。
しかしおすすめといわれるUnion型は文字列管理なのであまり使いたくない。
chatGPTさんに相談してみると
Enumを使用することは一般的な手段ですが、柔軟性や型の安全性を損なう可能性があるため、一部の開発者は代替手段を検討することを推奨しています。しかし、すべての状況でEnumを避ける必要はなく、プロジェクトの要件やコーディングスタイルに応じて判断する必要があります。
だそうな。
今回はそんな大規模プログラムじゃないし、わかりやすいからEnumを使おうと思う。ライブラリがあっちこっちで活用されるとも思えんしね。
エクセルのCustomFunctions.ErrorCodeだってenumみたいだしね。
#Enumの作成
この辺を参考にしながら作成してみる。
色々見ていると、const Enumというのにして、値に文字列を指定するとよいっぽい。
src/constant.tsを作りその中に作成する。(定数系はここにいれようかな)
初めての言語なので相変わらず何ケースにするか迷う・・・。
これもいろんな流派があるみたいだけど、CShaperとしてはアンダースコアを打つのが面倒になってきたのもあり、パスカルケースで行こうと思う。
constant.ts
/** * 断面性能のタイプ */ export const enum SectionPropertyType { Area = "断面積", SecondMomentOfAreaY = "断面二次モーメントY", SecondMomentOfAreaZ = "断面二次モーメントZ", }
これでSecBuildHFunctionクラスに関数を追加する。
sec/build-h-function.ts抜粋
import { SectionPropertyType } from "../constant"; 中略 /** * 組立H形鋼の断面性能 * @param propertyType 出力する断面性能のタイプ * @param a 成 A * @param b フランジ幅 B * @param t1 ウェブ厚 t1 * @param t2 フランジ厚 t2 * @returns 断面性能 */ static build_h( propertyType: SectionPropertyType, a: number, b: number, t1: number, t2: number ): number { switch (propertyType) { case SectionPropertyType.Area: return SecBuildHFunction.build_h_area(a, b, t1, t2); case SectionPropertyType.SecondMomentOfAreaY: return SecBuildHFunction.build_h_second_moment_of_area_y(a, b, t1, t2); case SectionPropertyType.SecondMomentOfAreaZ: return SecBuildHFunction.build_h_second_moment_of_area_z(a, b, t1, t2); default: throw new Error("実装していない断面性能です。"); } }
indexとかのexportも忘れずに記載。
テストコードも追記。しかし断面二次モーメント長ったらしくて行数が増えてしまう。まあいいか・・・。 sec/build-h-funciton.test.ts抜粋
import { SectionPropertyType } from "../constant"; 中略 test("ビルドHのIy", () => { expect( SecBuildHFunction.build_h_second_moment_of_area_y(1200, 400, 19, 25) ).toBe(9312218750.0); expect( SecBuildHFunction.build_h( SectionPropertyType.SecondMomentOfAreaY, 1200, 400, 19, 25 ) ).toBe(9312218750.0); });
組立H形鋼の断面性能計算をenumで断面性能タイプを指定できる関数を追加 · st-func/st-func-ts@968dc0b · GitHub
アドインへの組み込み
アドインのほうも修正する。よく考えるとこっちにもtestを書いておいたほうがいいか。
ちょっと二度手間で、ライブラリに分けたのは早まったかと思ったが、きっと何かの役に立つと思ってそのまますすめよう。
テスト環境を作ったら、jest.config.jsでなぜかmodulesに波線が。前と同じようにエラーを消してしまおう。 あれ、でもなんでライブラリのほうではエラーにならなかったんだろう?まあいいか。
test環境の作成 · st-func/st_func_addin@b9a12cb · GitHub
testをかいてみる。今度はtestとexpectがエラーになった。 なんでだろう・・・これも強引に無視設定をする。
こっちはpackageとかを自分で書いてないからよくわからん・・・。
npm tとして、とりあえずテストは動いた!
secBuildHのテストを作成 · st-func/st_func_addin@c066846 · GitHub
テストを書いたので、今度は関数を修正する。
断面性能タイプはエクセルでは文字列なので、文字列をenumに変換して関数を呼び出す。 function.ts
import { SectionPropertyType, SecBuildHFunction } from "@st-func/st-func-ts"; /** * 文字列をenumのpropertyTypeに変換する * @param propertyType 文字列の断面性能タイプ * @returns enumの断面性能タイプ */ function ToSectionPropertyType(propertyType: string): SectionPropertyType { switch (propertyType) { case "A": return SectionPropertyType.Area; case "Iy": return SectionPropertyType.SecondMomentOfAreaY; case "Iz": return SectionPropertyType.SecondMomentOfAreaZ; default: let error = new CustomFunctions.Error( CustomFunctions.ErrorCode.invalidValue, `[${propertyType}]は正しくないタイプ名です` ); throw error; } } /** * 組立H形鋼の断面性能。 * @customfunction secBuildH secBuildH * @param propertyType 表示したい断面性能のタイプ * @param a 成 A * @param b フランジ幅 B * @param t1 ウェブ厚 t1 * @param t2 フランジ厚 t2 * @returns 断面性能 */ export function secBuildH(propertyType: string, a: number, b: number, t1: number, t2: number): number { return SecBuildHFunction.build_h(ToSectionPropertyType(propertyType), a, b, t1, t2); }
これでエクセル側の計算部分はだいぶすっきりした。
secBuildHの断面性能の場合分けをライブラリを使う方式に変更 · st-func/st_func_addin@1aa8804 · GitHub