食品成分表の準備
準備概要
●前提条件
●成分表八訂版を取り寄せる
●CSVファイルを作成
このExcelファイルをそのままでは利用しにくいのでCSVファイルにデータを変換します。
ダウンロードしたExcelファイルの1行目~12行目までは13行目からの成分データを説明する管理項目のセクションになっています。
この管理項目では、データを格納している各セルは見やすさのため複数のセルを結合したり書式設定したりしています。また、一つのセルの中で入力した文字列中に改行コードが入っていたりもします。更に、13行目以降の数値データ中に数値に各種記号がプラスされていたり()カッコで括ったりなどした部分もあります。
食品成分値は食品の100ℊ当たりの成分を表示しているので
CSVファイルでは利用する際、数値を利用する重量当たりの値に計算しなおす必要があります。
そのため成分値に数値以外の記号などが含まれていると計算エラーを起こしてしまします。
そのため、セルに含まれる書式や結合などを解除したり記号なども取り除く必要があります。
食品成分八訂版ダウンロード
■ブラウザで文部科学省のページを検索
■赤枠をクリック
■複数のデータ項目が表示されるので上から二番目の赤枠をクリック
■Excel形式のファイルが開くので赤枠のファイルのダウンロードボタンをクリック
■一瞬でダウンロードが終了します。ダウンロードは通常PCのダウンロードフォルダーになります。
■赤枠のファイルを開くリンクをクリック
■PC版のExcelが起動してファイルが開きます。(ここではExcel2016を使っています)
■黄色の警告バーが出るので 編集を有効にする(E)ボタンをクリックします。
■ 12行目までの項目部分のセルはしっかり書式設定されています
■下図はセルの結合や改行コードを取り除いた様子です
■下図は、さらに不必要な項目を別の領域に移動したり、今後必要になると思われる列を予備として追加したりしています
そしてExcelのファイルをCSVファイルにして保存しています
■ファイル→エクスポート→ファイル種類の変更→CSV(コンマ区切り)→名前を付けて保存でCSV形式で保存します。
■ExcelでCSVを開いたところ
■メモ帳で開いた様子
データチェックと変換プログラム
■食品成分表データは横70列で約2400行ほどありセルの数は16万8千個にもなりますからこれを目視で修正するのとても大変なので下図のようなプログラムを利用します。
■下図の文字列置換用の関数を利用して計算処理の障害になるデータ中の数値以外の文字列を取り除きます。(実際一目見ただけでTr、‐、(、)、その他脚注文字などが数値データに交じっていたりします)
ここでは、Replaceは第一引数のstrに含まれる第二引数の(を取り除いて返します。
結果は一番下の”ABCDE)F” になります。
■下図では、このように取り除きたい文字列をすべて指定してとりのぞきました。
Sub spasOff() ' ' spasOff Macro ' ' Dim max As Integer Dim retu As Integer Dim r As Integer Dim c As Integer Dim str As String max = Range("B2").CurrentRegion.Rows.Count retu = Range("B2").CurrentRegion.Columns.Count '1行目~12行目までの項目エリアのセルには様々な書式が設定されています 'これをCSVファイルに変換するときデータ取り出しますが、この書式設定が様々なエラーを引き起こします '例えば、セルの文字列中に改行コードやスペースが含まれているとCSVファイルではこれをカンマ区切りと判断してしまうので 'のちのデータを使用する際データが不整合になり、正しいデータを得ることができなくなります。 '手動でも可能ですが、下記のコードで確実にそれらを取り除きます For r = 1 To max For c = 1 To retu If Cells(r, c) <> "" Then str = Cells(r, c) '半角スペースを取り除く str = Replace(str, " ", "") '全角スペースを取り除く str = Replace(str, " ", "") '改行コードを取り除く str = Replace(str, vbLf, "") '元のセルに書き戻す Cells(r, c) = str End If Next c Next r 'この食品成分データにはそれ以外にも様々な書式設定が使われていますが、上記以外は手動でやりました End Sub
■ 食品栄養成分データは、その食品の100ℊ当たりの成分を表示しています。
■ この食品成分データを利用するシステムでは例えばメニューレシピを作成するシステムの場合、そのメニューレシピを構成する各食品の成分データを使用量当たりのデータに計算で求める必要があります。
■ 具体的な例として、「玉ねぎ」の成分値で蛋白質は1.0gですが、使用量が30gのなら
1.0gを100で割って30gを掛けると 0.3gと計算します。これをプログラムで使うには
■ つまり、食品栄養成分値 / 100 * 使用量 となります。
この計算で食品栄養成分値に数値と判断できない文字列等が含まれていると計算エラーが発生しプログラムがストップしてしまします。ですからあらかじめデータを整理しておく必要があるのです。
■CSVファイルのデータを整えたらいよいよこのデータを動的に利用する具体的な方法を考えていきます。
CSVファイルのデータを二次元配列に取り出す
Function det_in(csvName As String) As Variant 'csvNameはフルパスつきcsvファイル名 'コンボボックスのキーワードで検索した食材のリストを二次元配列に格納して返す Dim fso As Object 'FileSystemObject Dim ffile As Object 'File Dim myData As Variant Dim myDataLine As Variant Dim Ccnt As Long, Rcnt As Long Dim i As Long, j As Long 'csvName = ActiveWorkbook.Path & fail 'オブジェクト作成 Set fso = CreateObject("Scripting.FileSystemObject") Set ffile = fso.OpenTextFile(csvName, 1) ' 配列の上限設定 myDataLine = Split(ffile.ReadLine, ",") Ccnt = UBound(myDataLine) '列数 On Error Resume Next 'ファイルが一行しか無いときエラーになる ffile.ReadAll Rcnt = ffile.line - 2 '行数 ffile.Close '上で取得した列数、行数で配列要素数をセット ReDim myData(Rcnt, Ccnt) ' 2次元配列に格納 Set ffile = fso.OpenTextFile(csvName, 1) j = 0 Do Until ffile.AtEndOfStream myDataLine = Split(ffile.ReadLine, ",") For i = 0 To Ccnt myData(j, i) = Replace(myDataLine(i), """", "") Next j = j + 1 Loop ffile.Close det_in = myData End Function
コード解説
■ det_in(CSVファイル名)は引数で指定したCSVファイルを二次元配列に格納して返すFunction関数。
■16、17行名
この関数の引数で指定しているファイルはここまでの解説で食品成分表のExcelファイルから生成したCSVファイルです。このファイルをプログラム中で操作するためのファイルシステムオブジェクトを作成します。
■20~25行目。上で作ったファイルオブジェクトを使って、指定しているCSVファイルの行数と列数の大きさを調べます。
■28行目。ファイルの大きさを調べて二次元配列の要素数の大きさを指定して宣言しています
■31行目。上で作ったファイルシステムオブジェクトは一旦閉じていますので、ここで再度ファイルをセットしなおしています。
■32~42行目。CSVファイルのデータを上で宣言した二次元配列変数に移し替えています。(36行目は、データを格納するときCSVファイルにデータ変換したとき付加された文字列を表す「””」を取り除いています)
det_in関数の利用
なんらかのプログラムを作るときにはこのCSVファイルを所定のフォルダーに保存しておきます。
プログラムでは食品成分表データが必要になったとき、所定のフォルダーからCSVファイルを呼び出して二次元配列に格納して利用します。
■ Dim arryData As Variant
■ Dim csvName As String
■ csvName = ActiveWorkbook.Path & ”test.csv” ’(プログラムを作成するExcelファイルがあるフォルダーと同じフォルダーにtest.csvがあると仮定しています)
■ arryData = det_in(csvName)
★これでarryDataにCSVファイルのデータが格納できましたからプログラムの中で取り扱うことができます。
コメント