開発時期:2024年
開発者:AmpiTa Project
開発言語:C#言語(Visual Studio 2022)
背景・概要
厚生労働省では、診療報酬(レセプト)データを集計し、毎年1回、Excelファイルを公表しています。
そのデータは年次比較できないため、別途Excelファイルを作ってセルをコピペするなどの対応が必要でした。
また、外来では実施されるが入院では行われない処置などが存在するため、外来と入院で行数が一致せず、単に行番号だけ見てコピペという訳にはいかないという難点もありました。
年を重ねるにつれて集計の手間が増えてきたので、全年度をまとめるシステムを開発するに至りました。
基本構想
厚生労働省が提供している診療報酬データ(レセプトデータ)のExcelファイルを、1つのデータベースとして閲覧や集計できるようにしたい、というのがニーズです。
ソリューションが提供されれば、レセプトデータから様々な情報を得る事ができ、そのデータの基づく分析や、戦略策定などができるようになります。
厚生労働省から配られるExcelデータは、2024年配布分で400個ほどのExcelファイルです。
外来、外来加算、入院、入院加算と4シートあるExcelファイルも多く、欲しいデータを探すだけでも手間がかかります。それが何年分もあると、データ集計だけでも大きな時間を割くことになります。
厚生労働省のウェブサイトからExcelデータをダウンロードして、ファイル名を付与するところまでは手作業で実施することとします。年1回なので自動化しなくても良いかなと思っていますが、ファイル数が年々増えているので要検討課題です。
1年度分を1つのフォルダにまとめることにして、そのフォルダを走査して必要なデータを独自データベースに登録することとしました。
基本設計
Visual Studio 2022を使い、C#で開発することにしました。
今回の開発はExcelを読込んで、XMLファイルに変換する処理を実装します。
最もシンプルな方法としては、フォームを1つ設置、そこに機能実行ボタンを配置すれば処理は実行できます。
厚生労働省のExcelファイルにどのような項目があるのか調べた上でXMLファイルの項目を決定していきます。
重複登録を割けるためのチェック機能、検索性を高めるために項目毎のデータ型の調整などを行います。
概ね、このようなプランで実施設計と施工に移りました。
個人用チープ仕様
開発者がユーザーであり、システム自体を他人に使わせる予定もないので、非常にチープなつくりになっています。
自らの使用頻度も、入力は年1回だけ、出力は必要なときだけなので、キレイにつくり込む必要もありません。
ファイルの指定
今回は厚生労働省が提供しているExcelファイルを取り込むシステムを開発するので、まずは対象となるExcelファイルを指定する機能が必要です。
オープンファイルダイアログ(OpenFileDialog)を使ってファイルを指定しました。
OpenFileDialog OpenFiDi_Excel = new OpenFileDialog();
OpenFiDi_Excel.InitialDirectory = @str_NDB_Excel_Folder + "\\";
OpenFiDi_Excel.Filter = "Excelファイル(*.xlsx)|*.xlsx;*.xls";
OpenFiDi_Excel.Title = "NDBファイル選択";
OpenFiDi_Excel.RestoreDirectory = true;
if (OpenFiDi_Excel.ShowDialog() == DialogResult.OK)
{
txb_Select_File.Text = OpenFiDi_Excel.FileName;
}
else { return; }
await Excel_File_Name_Conversion();
全セル走査
エクセルファイルをExcelDataReaderで読取り、シート番号0から順に巡回していく for 句、その後は全行を最下行まで処理していく for 句を実装しています。Excelの見出し行が4行あるため、処理は5行目から実行しています。
var var_PEP_Excel_FilePath = txb_Select_File.Text;
using (FileStream filestream_Excel = System.IO.File.Open(@var_PEP_Excel_FilePath, FileMode.Open, FileAccess.Read))
using (IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(filestream_Excel))
{
var ds_Data_Set_Excel = excelReader.AsDataSet();
int int_SheetCount = ds_Data_Set_Excel.Tables.Count;
for (int int_Sheet_Number = 0; int_Sheet_Number < int_SheetCount; int_Sheet_Number++)
{
var dt_Data_Table_Excel = ds_Data_Set_Excel.Tables[int_Sheet_Number];
string str_SheetName = ds_Data_Set_Excel.Tables[int_Sheet_Number].TableName;
var yCount = ds_Data_Set_Excel.Tables[int_Sheet_Number].Rows.Count;
int_RowCount = Int32.Parse(yCount.ToString());
int_Total_Record = int_Total_Record + int_RowCount - 4;
for (int int_Row = int_ExRdStRow; int_Row < int_RowCount; int_Row++)
{
ここに読取(走査)処理を記述
}
}
}
データテーブル保存
Excelファイルを走査し、全セルをXMLファイルに転記します。
一時的にはデータテーブル(DataTable)に保存し、それをXMLファイル化します。
下記コードは性年齢別のデータをXML・XSDファイルに保存し、データグリッドビュー(DataGridView)に表示するという処理です。
dtTbl_NDB_Edit.WriteXmlSchema(str_XML_SexYO_Cnt_Xsd);
dtTbl_NDB_Edit.WriteXml(str_XML_SexYO_Cnt_XML);
dataGridView1.DataSource = dtTbl_NDB_SexYO_Cnt;
await DataGridView_Setup_01();
CSV出力
出力先を指定して、CSVファイルを保存(出力)します。
Try を使って処理を実施し、途中で何か不都合な処理があったとしても finally でCSVファイルを閉じる処理を入れて確実に処理を完了します。
SaveFileDialog saveFileDialog_CSV_File_Path = new SaveFileDialog();
saveFileDialog_CSV_File_Path.InitialDirectory = @str_NDB_Export_Folder;
saveFileDialog_CSV_File_Path.Filter = "CSV(*.csv;*.txt)|*.csv;*.txt|Anything(*.*)|*.*";
saveFileDialog_CSV_File_Path.RestoreDirectory = true;
if (saveFileDialog_CSV_File_Path.ShowDialog() == DialogResult.OK) { }
else
{
MessageBox.Show(" ファイルは選択されませんでした。", "Error", MessageBoxButtons.OK);
return;
}
StreamWriter file_CSV_write = new StreamWriter(@saveFileDialog_CSV_File_Path.FileName, false, Encoding.UTF8);
try
{
ここに本文を書き出す処理を記述
}
finally
{
file_CSV_write.Close();
}
実際の出力画面は以下のようになります。
マニュアル
ロゴ
チャットGPTを使って、それっぽいロゴを考えて貰いました。
そのまま使えるという図案は無かったのですが、考え方のヒントを得られたので下図ができあがりました。
たぶんデータベースを意味するような階層かなと思います。
赤と青の色使いは厚生労働省のロゴを参考にしています。
つくり方は、パワーポイントの図形機能で、四角形を並べただけです。
おわりに
元となるExcelファイルからデータを漏らしてしまうと集計データに誤りが生じてしまうため、いくつかのチェック機能を設けて漏れ防止に努めました。
必要なものは集計結果、データですのでそのプロセスについては雑に作った部分もあります。
医薬品の使用推移などコンサルティングの根拠データとして活用しやすくなったので、本質的な使い方を広げていきたいと思います。