ST_FUNC開発日記

建築構造設計Excelアドイン開発の記録

Enumを使った場合分け

現状、断面性能のタイプの場合分けはアドイン側のコードで行っているが、アドイン側はできるだけExcel処理に専念してもらい、数値計算についてはライブラリ側で行いたい。 そこで場合分けについてもライブラリへ移行することを考える。

アドインでは、人が入力するために、文字列での場合分けを行ったが、開発時の表記ゆれなどによるタイプミスなどを減らすためにEnumで場合分けをしていきたいと思う。

しかし、Enumの使い方を検索すると「TypeSciriptでEnumは使うな!」みたいな記事がたくさんヒットする。例えばこんなのとか。

しかしおすすめといわれるUnion型は文字列管理なのであまり使いたくない。

chatGPTさんに相談してみると

Enumを使用することは一般的な手段ですが、柔軟性や型の安全性を損なう可能性があるため、一部の開発者は代替手段を検討することを推奨しています。しかし、すべての状況でEnumを避ける必要はなく、プロジェクトの要件やコーディングスタイルに応じて判断する必要があります。

だそうな。

今回はそんな大規模プログラムじゃないし、わかりやすいからEnumを使おうと思う。ライブラリがあっちこっちで活用されるとも思えんしね。

エクセルのCustomFunctions.ErrorCodeだってenumみたいだしね。

Enumの作成

itc.tokyo

qiita.com

この辺を参考にしながら作成してみる。

色々見ていると、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