【MATLAB】CSVファイルに計算セル（数式セル）を追加してEXCELファイルとして保存する

## はじめに
`matlab`は数値計算に強く，音響ファイルを開いて振幅グラフを出力したりFFTしたりといったことが簡単に行える．
様々な分析結果を客先に提出する場合は，弊社の場合は`excel`ファイル(xlsx)の場合が多く，また，客がパラメタを変えながら確認出来るように，計算結果は生の数値ではなく，計算セルを使用している．

「計算セル」というのはここでは
=round(A1*B1, 0)
みたいな感じの数式の入ったセルのことを言っている．

計算セルがあるために，今までは

1. `matlab`で数値計算して`CSV`ファイルに保存する
1. `excel`で`CSV`ファイルを開き，計算セルを追加してxlsxで保存する

という手順を踏んでおり，計算セルを追加する作業がめんどっちーだった．

今回は上記作業を自動化するということで，`matlab`で身長及び体重が入力された`CSV`ファイルを開き，BMIを計算して`xlsx`で保存するスクリプトを書いてみる．

## 使用するCSVファイル
以下のような`CSV`ファイルを用意した．

<img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373168/cf60bab0-d352-95ce-6579-eaa8c373e07f.png"> [^1]

| 名前| 生年月日 | 身長(cm) | 体重(kg) |
|:-----------|------------:|------------:|------------:|
| hoge huga | yyyy/m/d        | x| y |




これを適当な名前(身長体重.csv)で保存した．

## BMI値をmatlabで計算
### 実装
```matlab:
clc
close all
clear all

path = 'C:\Users\hogehoge';
file = '身長体重.csv';
% 名前,生年月日,身長(cm),体重(kg)
% 桜 衣之,2021/4/4,155,47
% ...
filepath = fullfile(path, file);

% ファイルを開いてcellに格納
T = readcell(filepath,'DatetimeType','text');

% 身長(cm)
height = cell2mat(T(2:end,3));
height = height / 100;% 身長(m)に直す
% 体重(kg)
weight = cell2mat(T(2:end,4));
% BMI ＝ 体重kg ÷ (身長m)^2
BMI = weight ./ (height .^2);
% cell配列にする
TBMI = num2cell(BMI);
TBMI = [{'BMI'}; TBMI];% 1行目を追加

% cellの連結
Tout = [T TBMI];

% ファイルに書き込む
[path, file] = fileparts(filepath);
newFile = sprintf('%s_addBMI.xlsx', file);
outputFilePath = fullfile(path, newFile);
writecell(Tout, outputFilePath);

```

追加したい列を`cell`として用意して，`readcell`で読み取った`cell`に連結するだけである．

### 結果
結果は以下のようになり，BMIの計算結果を追加することが出来た．
<img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373168/46598e41-77be-c9c2-163d-c2fbb086e5f8.png">




## BMI値をexcelで計算
前節でBMIの計算結果が追加され，xlsxファイルとして保存することが出来た．
しかし，やりたいのは計算セルの追加である．
以下の図のように，BMIを`matlab`ではなく`excel`で計算させたいのである．
<img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373168/4eca912e-4f26-0710-9174-11edd2d34d05.png">

### 実装
``` matlab:
%（Toutを求めるところまでは上と同じなので中略）

% 計算セルをさらに追加する
BMI2 = cell(size(TBMI));
BMI2(1) = {"計算セル"};
for n = 2:length(BMI2)
    % =D2/(C2/100)^2
    BMI2(n) = {"=D" + n + "/(C" + n + "/100)^2"};
end
Tout2 = [Tout BMI2];

% ファイルに書き込む
[path, file] = fileparts(filepath);
newFile = sprintf('%s_addBMI.xlsx', file);
outputFilePath = fullfile(path, newFile);
writecell(Tout2, outputFilePath,'UseExcel',true);% UseExcelオプションを追加
```

計算セルの追加方法については，[【MATLAB】ハイパーリンク付きテキストのExcel への書き込み自動化](https://qiita.com/eigs/items/26279a79319992ac123d)を参考にした．
やってることは簡単で，数式をそのまま`string`に入れて，出力する際に`writecell`に`UseExcel`オプションをつけるだけであった．`UseExcel`オプションは気付かなかったわね．

また，`D`や`C`などの列名がハードコーディングになっているが，これが気になる場合は以下などに列番号をエクセル表記（またはその逆）に変換する実装がある．
[I need to convert a number into its column name equivalent](https://jp.mathworks.com/matlabcentral/answers/248797-i-need-to-convert-a-number-into-its-column-name-equivalent)

### 結果
期待通りの結果となった．
もちろん，`excel`上で体重などの値を編集するとBMIの値も自動更新される．
<img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373168/7f419df0-5387-e5c6-73b4-a231b0d5e514.png">

## まとめ
今回は`matlab`から計算セルの入った`excel`ファイルを作成した．
この調子で`excel`と和解していきたい．

[^1]: https://ja.wikipedia.org/wiki/%E3%81%8A%E3%81%A1%E3%81%93%E3%81%BC%E3%82%8C%E3%83%95%E3%83%AB%E3%83%BC%E3%83%84%E3%82%BF%E3%83%AB%E3%83%88