14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MATLAB/SimulinkAdvent Calendar 2021

Day 1

MATLABアプリを「外から」ぶったたく方法

Last updated at Posted at 2021-12-11

はじめに

MATLABの(割と)最近の便利機能としてApp Designerがあります。
image.png

詳しくは下記の記事を参照ですが、ドラッグ&ドロップでGUIを設計できるためアプリ作成をめっちゃスムーズに行うことができます。(語彙)
MATLABで簡単にGUIを作ろう!

どれぐらいスムーズかというと、気が付いたらアプリを滅茶苦茶作りこんでしまい、後になってから「やべっ、再利用性を考えたらコードをアプリに書くんじゃなくて関数化しとくべきだった…」と後悔するぐらいにスムーズです。

別に後から関数化すればよいだけの話ですが、コードの量が嵩みがちなアプリから必要な個所を抜き出して関数化するのはちょっと面倒です。

本記事はそのような面倒を避けるための方法を提案したもので、具体的にはMATLABアプリの関数やプロパティを「外から」、すなわちmファイルから読み書きするにはどうしたら良いか?の解説を行います。

image.png

余談ですがMATLABアプリは要するにクラスなので、クラスの作法を理解している場合は本記事は飛ばし読みで十分と思います。読んでほしいポイントをあえて挙げるとしたら 3.1 かなぁ。

1. 解説に用いるアプリ

App Designerのサンプルに「住宅ローン計算器」があったので、これを例として用います。
image.png
利率やローン年数をもとに、月々の支払額やら元本(Principal)とか利息(Interest)とかを計算してくれるようです、知らんけど。

ローン年数を色々変えた場合の支払額がどうなるか? を調べたいと思った場合に、計算をアプリ内に組み込んでいた場合はアプリをポチポチいじって結果をエクセルとかにまとめなければなりません。
耐え難い作業ですね。ローンの支払いのように。
効率化したいですよね?ローンの支払いのように。

ということで、「外から」アプリを読み書きすることで解決します。

2. データを外から出し入れできるようにする

2.1 データの名前を調べる

例として、入力=ローン年数(Loan Period)を書き換えた場合の、
出力=月々の支払い(Monthly Payment) と、元本(principal) を取り出したいものとします。

アプリ画面にテキストエリアが存在する情報については、設計ビューから該当のテキストエリアを左クリックすると右側ウィンドウにてコード内でのオブジェクト名がグレーで強調されます。
image.png
ローン年数はLoanPeriodYearsEditField
月々の支払いはMonthlyPaymentEditFieldというオブジェクト名のようです。
またこれらのオブジェクトの数値についてはLoanPeriodYearsEditField.Valueのように定義されているようです。

一方で principal(グラフの青線) はテキストエリアがありません。
この場合、principalが表示されるグラフを右クリックしてグラフのオブジェクト名を調べ、コード内でどのような処理が行われているかを調べる必要があります。
オブジェクト名はPrincipalInterestUIAxesだったので、コード該当箇所は下記。

            % Plot the principal and interest
            plot(app.PrincipalInterestUIAxes,(1:nper)',principal, ...
                (1:nper)',interest);
            legend(app.PrincipalInterestUIAxes,{'Principal','Interest'},'Location','Best')
            xlim(app.PrincipalInterestUIAxes,[0 nper]); 

データ名はそのまま、principalであったことが分かります。

2.2 データの公開/非公開を調べる

コードビュー内をデータ名で検索して調べます。
LoanPeriodYearsEditFieldMonthlyPaymentEditFieldについてはいずれもpublicすなわち公開オブジェクトとなっていることが分かります。
この場合、外部から読み書きする上での特別な措置は不要です。
image.png

一方でグラフ内に表示されていたprincipalで調べると、publicプロパティとしては定義されていないようです。この場合、publicプロパティに引き出してやる必要があります。次節参照。

2.3 非公開データの公開化

まずはじめに、publicプロパティの設定枠を準備します。
コードビューから下記のボタンをクリック。(別に手打ちでも良いです)
image.png

公開プロパティを記載する欄が出来るので、そこに公開プロパティとしての名称を書きます。

    properties (Access = public)
        principal_pub % Description
    end

principal自体を公開プロパティとしても良いですが、便宜上新たなプロパティとしてprincipal_pubを定義しました。
続いてコード内でprincipalを公開プロパティであるprincipal_pubに受け渡して外部から読めるようにします。
今回はグラフの描画直後に受け渡しの処理を書きました。

            plot(app.PrincipalInterestUIAxes,(1:nper)',principal, ...
                (1:nper)',interest);
            app.principal_pub = principal;

アプリ内部で公開プロパティに読み書きを行う場合、上記のようにapp.を付けてやる必要がある点注意下さい。

3. アプリを外から実行可能にする

3.1 コールバック関数の公開化

この住宅ローン計算器は、「Monthly Payment」ボタンを押すことで計算が行われます。
このため、このボタンを押したことによって実行される関数を公開化する必要があります。
プロパティと同じ要領で、公開関数の作成を行います。
image.png

ボタンを押した場合のコールバック関数 MonthlyPaymentButtonPushedは既にプライベート関数として定義されており、同じ関数名を公開関数として記載することは出来ません。
このため、下記のように関数名は別の名前で定義しておき、その中で呼び出したい関数MonthlyPaymentButtonPushedを呼ぶような処理とします。

    methods (Access = public)
        function MonthlyPaymentButtonPushed_pub(app)
            MonthlyPaymentButtonPushed(app)
        end
    end

関数に対する措置はこれだけです、簡単。

4. アプリを「外から」ぶったたく

ポイント:アプリをオブジェクトとして定義する

冒頭で少し述べた通り、アプリ=クラスなのでmファイル内でオブジェクトとして定義することが出来ます。アプリのファイル名をMortgage_EX.mlappとすると、オブジェクト定義は下記のコマンドにて可能です。

app = Mortgage_EX;

オブジェクト定義したら後は簡単で、あとは公開データに書き込む・公開関数を呼び出す・公開データを読み込めばよいのです。

サンプルコードおよび実行結果

下記のデータを取りだすためのコードを下記に示します。
・ローン年数10~40年の場合の元本
・ローン年数10~40年の場合の月々の支払額

yearsArry = [];
mpArry = [];
app = Mortgage_EX;
for i = 1 : 4
    years = i * 10;
    app.LoanPeriodYearsEditField.Value = years;
    app.MonthlyPaymentButtonPushed_pub;
    prLegend = "principal("+ num2str(years) + "years)";
    figure(1);
    hold on;
    plot(app.principal_pub,"DisplayName", prLegend);
    legend();
    
    yearsArry = [yearsArry years];
    mpArry = [mpArry app.MonthlyPaymentEditField.Value];
end

figure(2);
hold on;
mpLegend = "MonthlyPayment("+ num2str(years) + "years)";
bar(yearsArry,mpArry);

ローン年数10~40年の場合の元本
image.png

ローン年数10~40年の場合の月々の支払額
image.png

ね、簡単でしょう?

おわりに

何気にApp Designer関連の記事はこれが始めてでした。
ちなみに著者は余り自分でApp Designer作ることは無く、本手法は「自分意外の誰かに作って頂いたアプリを俺々mファイルでいじくりまわす」事を目的として開拓したものとなります(ひどい)
ボタン押したりするのめんどくさいからね、しょうがないね。

14
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?