やったこと
Excel ファイルに書き出した時にセル幅が残念な場合があります。これを自動調節してみました。ただ、残念ながら MATLAB 側の機能ではできそうにないので、MATLAB から Excel の機能を使います。
公式ページとしてはこちら:Excel をオートメーション サーバーとして使用したスプレッドシート データの読み取り
xlswrite を使っている方は「なんで xlswrite が非推奨?」の項がお勧めです。
Livescript 版(MATLAB)は GitHub: ActiveX-Excel-MATLAB1 に置いてあります。
セル幅調整?具体的には
例えば table 型で
data = ["fileEnsembleDatastore","ds","datastore"];
data = array2table(data)
data1 | data2 | data3 | |
---|---|---|---|
1 | "fileEnsembleDatasto... | "ds" | "datastore" |
というデータを Excel に書き出してみます。
filename = 'undisiredFormat.xlsx';
writetable(data,filename);
Excel で開くと多少残念な気持ちになります。
これを
autoFitCellWidth(filename);
とデータの長さに合わせてセル幅を調整させるというお話。
余談:Excel に書き出すための関数
MATLAB から Excel ファイルに出力する関数としては xlswrite 関数が長らく使われていましたが、最近は
- writetable 関数(R2013b~): table 型変数の出力
- writetimetable 関数(R2019a~):timetable 型変数の出力
- writematrix 関数(R2019a~):array (double型/string型) の出力
- writecell 関数 (R2019a~):cell 配列の出力
などが推奨されています。同様に csvwrite 関数も「非推奨」の文字が出るようになりました。
なんで xlswrite が非推奨?
書き出し速度が段違いです。この例では 100 倍以上違います。
data = rand(10,10);
tic
xlswrite('test_xlswrite.xlsx',data);
toc
経過時間は 8.999516 秒です。
tic
writematrix(data,'test_writematrix.xlsx');
toc
経過時間は 0.071814 秒です。
かなり違います。
xlswrite 関数は Excel を起動しているので時間がかかります。さらに都合が悪いことに、何度も呼び出すとそのたびに Excel 起動して閉じてを繰り返すので大変時間がかかります。write* 系を使いましょう。
セル幅調整
さて本題。関数の中身を見た方が速いですね。VBA に詳しい方ならピンとくると思いますが、、どうでしょう。
function autoFitCellWidth(filename)
% Excel ファイルへの絶対パスを取得
filepath = which(filename);
% Excel に対して ActiveX を開く
h = actxserver('excel.application');
wb = h.WorkBooks.Open(filepath);
% UsedRange: データが入っている範囲の
% EntireColumn: 列全体を
% AutoFit: データに合わせた幅にします
wb.ActiveSheet.UsedRange.EntireColumn.AutoFit;
% 指定したファイル名で保存しエクセルを閉じる
wb.SaveAs(filename);
wb.Close;
h.Quit;
h.delete;
% 注意:この辺キッチリ Close/Quit/delete しておかないとあとでややこしいです。
%(ほかのアプリで使われていて開けない・消せないなど起こります)
% PC 再起動すれば大丈夫です。
end
ActiveSheet やら UsedRange やら EntireColumn などは Excel 側のコマンド。同じ要領で他にも Excel ができることはできちゃう、、はず。
その他の編集作業例
範囲を指定して同じ作業をするなら
range = 'A1:H5';
wbrange = wb.ActiveSheet.get('Range',range);
wbrange.EntireColumn.AutoFit;
とか、セル幅を決め打ちで行くなら
wbrange.EntireColumn.ColumnWidth = 20;
など。
あとセルの塗りつぶしや文字の色を変えるなら
% セルの塗りつぶし
wb.ActiveSheet.UsedRange.Interior.Color=hex2dec('00FF00'); % 緑
% フォントの色
wb.ActiveSheet.UsedRange.Font.Color=hex2dec('0000FF'); % 赤
% 色は16進数の BGR の組み合わせで指定
% 赤: 0000FF
% 青: FF00FF
% 緑: 00FF00
% 黒: 000000
% 白: FFFFFF
こんな感じです。他にも MATLAB Answers にもいくつか例がありますのでもし必要があればぜひ。
参考
- Office VBA Reference/Excel/Object model/Range object
- TipsFound: VBA 列の幅を調整する
- MATLAB Answers: ActiveX を使って Excelの任意のセルに画像を挿入することはできますか?
- MATLAB Answers: MATLAB から Excel Spreadsheet にセル背景色やフォント色を指定してデータを書くにはどうしたらよいですか?
- MATLAB Answers: XLSWRITE 関数で、指定したワークシートのみ持つ Excel ファイルを作成できますか?
- MATLAB Answers: Excel ファイルのシート名を変更することはできますか?
- Can MATLAB pre-format individual cells when writing data to an EXCEL spreadsheet?
Appendix: autoFitCellWidth 関数
function autoFitCellWidth(filename)
% Excel ファイルへの絶対パスを取得
filepath = which(filename);
% Excel に対して ActiveX を開く
h = actxserver('excel.application');
wb = h.WorkBooks.Open(filepath);
% UsedRange: データが入っている範囲の
% EntireColumn: 列全体を
% AutoFit: データに合わせた幅にします
wb.ActiveSheet.UsedRange.EntireColumn.AutoFit;
% 指定したファイル名で保存しエクセルを閉じる
wb.SaveAs(filename);
wb.Close;
h.Quit;
h.delete;
% 注意:この辺キッチリ Close/Quit/delete しておかないとあとでややこしいです。
%(ほかのアプリで使われていて開けない・消せないなど起こります)
% PC 再起動すれば大丈夫です。
end
-
Livescript から markdown への変換は livescript2markdown: MATLAB's live scripts to markdown を使っています。 ↩