はじめに
MATLABの(割と)最近の便利機能としてApp Designerがあります。
詳しくは下記の記事を参照ですが、ドラッグ&ドロップでGUIを設計できるためアプリ作成をめっちゃスムーズに行うことができます。(語彙)
MATLABで簡単にGUIを作ろう!
どれぐらいスムーズかというと、気が付いたらアプリを滅茶苦茶作りこんでしまい、後になってから「やべっ、再利用性を考えたらコードをアプリに書くんじゃなくて関数化しとくべきだった…」と後悔するぐらいにスムーズです。
別に後から関数化すればよいだけの話ですが、コードの量が嵩みがちなアプリから必要な個所を抜き出して関数化するのはちょっと面倒です。
本記事はそのような面倒を避けるための方法を提案したもので、具体的にはMATLABアプリの関数やプロパティを「外から」、すなわちmファイルから読み書きするにはどうしたら良いか?の解説を行います。
余談ですがMATLABアプリは要するにクラスなので、クラスの作法を理解している場合は本記事は飛ばし読みで十分と思います。読んでほしいポイントをあえて挙げるとしたら 3.1 かなぁ。
1. 解説に用いるアプリ
App Designerのサンプルに「住宅ローン計算器」があったので、これを例として用います。
利率やローン年数をもとに、月々の支払額やら元本(Principal)とか利息(Interest)とかを計算してくれるようです、知らんけど。
ローン年数を色々変えた場合の支払額がどうなるか? を調べたいと思った場合に、計算をアプリ内に組み込んでいた場合はアプリをポチポチいじって結果をエクセルとかにまとめなければなりません。
耐え難い作業ですね。ローンの支払いのように。
効率化したいですよね?ローンの支払いのように。
ということで、「外から」アプリを読み書きすることで解決します。
2. データを外から出し入れできるようにする
2.1 データの名前を調べる
例として、入力=ローン年数(Loan Period)を書き換えた場合の、
出力=月々の支払い(Monthly Payment) と、元本(principal) を取り出したいものとします。
アプリ画面にテキストエリアが存在する情報については、設計ビューから該当のテキストエリアを左クリックすると右側ウィンドウにてコード内でのオブジェクト名がグレーで強調されます。
ローン年数は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 データの公開/非公開を調べる
コードビュー内をデータ名で検索して調べます。
LoanPeriodYearsEditField
、MonthlyPaymentEditField
についてはいずれもpublic
すなわち公開オブジェクトとなっていることが分かります。
この場合、外部から読み書きする上での特別な措置は不要です。
一方でグラフ内に表示されていたprincipal
で調べると、publicプロパティとしては定義されていないようです。この場合、publicプロパティに引き出してやる必要があります。次節参照。
2.3 非公開データの公開化
まずはじめに、publicプロパティの設定枠を準備します。
コードビューから下記のボタンをクリック。(別に手打ちでも良いです)
公開プロパティを記載する欄が出来るので、そこに公開プロパティとしての名称を書きます。
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」ボタンを押すことで計算が行われます。
このため、このボタンを押したことによって実行される関数を公開化する必要があります。
プロパティと同じ要領で、公開関数の作成を行います。
ボタンを押した場合のコールバック関数 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);
ね、簡単でしょう?
おわりに
何気にApp Designer関連の記事はこれが始めてでした。
ちなみに著者は余り自分でApp Designer作ることは無く、本手法は「自分意外の誰かに作って頂いたアプリを俺々mファイルでいじくりまわす」事を目的として開拓したものとなります(ひどい)
ボタン押したりするのめんどくさいからね、しょうがないね。