【食事記録】VBAで食事記録アプリを作ろうとしてボツになった話

今回は、食事記録アプリを作成しようとして没になった話をしていこうと思います。

## お腹を連続で壊しまくる事態に

食事記録を始めたきっかけは、**連続でお腹を壊しまくった**からです。

![スクリーンショット 2023-12-02 12.51.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538408/11d3ccb6-6394-99a2-c121-7c8e67533ef7.png)

この日は特に酷く、原因が分からず一日中もがき苦しんでいました。この週から、雑ではあるが食事内容を記述するようになりました。

![スクリーンショット 2023-12-02 13.01.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538408/250b62f1-7729-f270-2d09-7a3de3a5c922.png)

お腹を壊した際は必ず考察をするようにしていました。しかし、原因と思われるものが複数あり、どれが根本原因なのかずっとはっきりしませんでした。

### 原因はバナナだった

原因がわかったのは2022年4月。約5ヶ月してようやく原因がわかりました。おやつ感覚で食べたバナナで、10分足らずでもう腹痛が来て、これやん、と知った感じです。
当時は腹痛まで時間早すぎない？昔は普通に食ってた、という疑問が残っていましたが、その後も、カレーの中に気づかぬうちにバナナが入っており、お腹を下していたり、だんだん確信に変わりました。

![スクリーンショット 2023-12-02 13.17.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538408/0f0d1ba6-649e-1c6e-2059-e7fafe4b58a3.png)

ただ、その後も食事の記録は続けており、あまり良くなさそうな内容については赤字で示すようにしていました。

### PFCバランスを気にする生活に

![スクリーンショット 2023-12-02 13.23.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538408/eb0dee67-616d-2a9a-6be0-dbaaa0d818c7.png)

2023年になってから、今度は眠気でパフォーマンスが低くなることを危惧して、糖質（炭水化物）をメモ。
さらに「タンパク質取らないと不健康になる」というどっかのインフルエンサーの助言より、タンパク質の量もメモするようになりました。

ただ、流石に日記が食事打刻になってて日記じゃなくなっていることや、毎回同じ内容を入力するのが面倒となり、Excelで管理するようになりました。

## VBAの始まり

ここまではただの前提条件で、ここからが多分本題です。

VBA、それはMicrosoft Excelの**マクロ機能**を意味します。

Excelを使用している中で、コピー＆ペースト、セル単位で複製や計算式を入れる、等の操作を自動化できるツールとなっています。

言語はVisual Basicがベースとなっており、ボタンを押す、あるいは関数を実行することで処理が走るようになっています。

![スクリーンショット 2023-12-02 13.40.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538408/1fa40a8c-02c9-a78c-8540-44878de453ea.png)

ダイアログも表示することができ、VB.NETのWindowsデスクトップアプリ開発と似たようなアプリを作ることもできます（Windows限定）。

### 栄養成分の打刻支援

まず初めにやったのが、それぞれの食事データの打刻支援。

![スクリーンショット 2023-12-02 13.47.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538408/f4d904ea-f295-6118-1acc-772c8c134bee.png)

よく食べる食品を一覧にまとめ、左の「登録」ボタンを押すことで、次に示す「今日のデータ」に反映されます。

![スクリーンショット 2023-12-02 13.48.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538408/4f85cc3e-08a4-94b6-55f2-22f04cdda202.png)

こちらが今日のデータとなる部分で、ここにどんどん食べた内容が入るようになっています。

### PFC自動計算機能

上記の画像にも表示されていますが、自動計算をする機能も内蔵しています。

:::note info
P: タンパク質
F: 脂質
C: 炭水化物
カロリー：P×4+F×9+C×4
:::

表を見ると、右側の白い背景部分と左側のグレーの背景で分ける必要があるのか、と思うかもしれません。これは、カスタム量を計算できるようにする機能を持っています。

例えば、１杯150gのご飯ですが、多めに食べるとPFCの値も変わりますね。そこで、一番右に200と記述することで、200g分のPFCが計算されるようになります。

### 理想のPFCの表示

|グラフ|表|
|---|---|
|![スクリーンショット 2023-12-02 13.57.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538408/38bfb6b0-9043-cb34-8205-be3216e0a117.png)|![スクリーンショット 2023-12-02 13.58.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538408/0e104ba0-5706-d380-2ae6-1f9bb7c901c3.png)|

表やグラフに表示されることで、あとどれくらい食べるべきだろう、というデータを出すことができます。理想のバランス（グラム数）は設定した体重から算出されます。

### データは別シートに格納

![スクリーンショット 2023-12-02 14.03.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538408/7e3b8e52-95d6-209e-9871-db275d04c55e.png)

で、１日が終了したら、別のシートにデータを移し、先程の「今日のデータ」は削除されます。

### VBAでやっていること

VBAでは、これらのコピー、ペースト、初期化などをやっています。

```vb
'********************************************************
'=========< ws0 入力データ の リセット
'********************************************************
Function ws0_dataReset()

  Dim rtn As Integer

  Dim ws0 As Worksheet
  Set ws0 = Sheets(glbWs0_name)

  ws0.Activate

  If MsgBox("データを削除してよろしいですか？", vbYesNo + vbExclamation, "削除の確認") = vbYes Then
    '商品ID〜カスタムタイプまで削除
    ws0.Range(Cells(glbWs0_stRow_data, glbWs0_Col_item_id), Cells(glbWs0_enRow_data, glbWs0_Col_cusType)).ClearContents
    '時間〜日にちカウントまで削除
    ws0.Range(Cells(glbWs0_stRow_data, glbWs0_Col_time), Cells(glbWs0_enRow_data, glbWs0_Col_dayCount)).ClearContents
    '倍率設定に式を格納
    ws0.Range(Cells(glbWs0_stRow_data, glbWs0_Col_quant), Cells(glbWs0_enRow_data, glbWs0_Col_quant)).Value = "=IFS(S4="""",T4,S4=0,T4/M4, TRUE, 0)"

    'カスタム倍率に１を格納
    ws0.Range(Cells(glbWs0_stRow_data, glbWs0_Col_cusQuant), Cells(glbWs0_enRow_data, glbWs0_Col_cusQuant)).Value = 1
    '日付をリセット
    ws0.Cells(glbWs0_Row_date, glbWs0_Col_date).Value = "=TODAY()"

    '日記打刻エリアをリセット
    ws0.Range(Cells(glbWs0_stRow_diary, glbWs0_Col_diary), Cells(glbWs0_stRow_diary + glbWs0_max_diary - 1, glbWs0_Col_diary)).ClearContents

    ws0.Cells(glbWs0_stRow_diary, glbWs0_Col_diary).Value = "食事計(初期)"

    '背景を白色にする
    If Not debugMode Then
      ws0.Range(Cells(glbWs0_stRow_data, glbWs0_Col_item_id), Cells(glbWs0_enRow_data, glbWs0_Col_cusQuant)).Interior.ColorIndex = 0
    End If

    ws0.Cells(glbWs0_stRow_data, glbWs0_Col_pro).Select
  End If

End Function
```

VBは、インデントで改行を行うタイプで、`{}`(中カッコ)ではなく、`End If`のような文法で関数の終わりを宣言しています。

Excel独自のプロパティなどもあり、本格的に記述するなら、VB.NETのデスクトップアプリとして作成したほうが絶対にいいです。

https://x.com/KadoUniversity/status/1621986495216377857?s=20

## ２ヶ月継続利用

実際作ってみて使ったかというと、しっかり使ってました。その日の記録は最終的に別シートにまとまる、という話をしましたが、1月23日~3月19日までしっかり埋まっており、1000行に到達しています。

### スマホでマクロが実行できない

しかし問題点もありました。まず、**スマホで打刻ができません**。スマホではマクロが実行できないため、そこだけ手打ちになります。最初のうち（PFCを計算しなくても良かったとき）は、スマホでも文字打つだけで良かったですが、PFCの計算を同時にするとなると、スマホでは到底不可能になります。

### 全ての食品にPFCデータが添付されていない

コンビニやスーパーなどで売っている惣菜系はほぼほぼPFCの記載がありますが、自炊したりレストランなどの外食だったりすると、PFCが記載されていないことがあります。そんなときは似たような料理を探してそれを記述するしかありません。

地味につらいのが、一部の食品はPFCの記載が１食あたりではなく、100gあたりとなっているところです。1食が不明瞭なとき自分の感覚で書くしか無くなってしまうのです。

### 食事するたび打刻が馬鹿らしい

https://x.com/KadoUniversity/status/1637779642399731712?s=20

1日2〜3食程度であれば問題ないが、外出するとなるとそれの度にいちいち打刻する必要があり、流石に馬鹿らしくなりました。

で、3月20日、この日は東京旅行のためExcelへの食事メモを休止。
案の定、それ以降復活することはありませんでした。

### Webアプリ化構想

![スクリーンショット 2023-12-02 14.25.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538408/7287d30b-3b90-93df-9b80-999a5e9751cc.png)

実は当時からWebアプリとして作成したいと思っていました。しかし、当時はそこまでの技術力がなかったことや、結局のところ「打刻する必要あるのか？」と自問自答を繰り返し、アイデアが凍結している次第です。

### chocoZAPが似たようなことをしている

そんなことを妄想している中、某`結果にコミットする`会社が、2023年9月に、chocoZAPの機能として「食事記録」をリリースしていました。ついに私のやりたいことを実現してしまいました。

とはいえまだ使ったことがなく、chocoZAPに加入するしかない、と食事記録のためだけに加入しようか迷っている次第でございます（chocoZAP施設は地元から気軽に通えない距離のため）。

## 今後の展望

今後は、chocoZAPに通えるほどのお金を稼いだ後、chocoZAPでPFCバランス管理をしようと思います。
似たようなことをするアプリは複数ありますが、AIによる画像解析を行うという点で潔く、普段管理しない人にとっても続けやすいサービスだと思っています。