非エンジニアでもできるC# WinForms入門 — 製造業の社内ツールを自分で作る
「Excelのマクロが壊れた。でも誰も直せない。」
製造業の現場で、この状況を何度見てきたかわからない。検査データの入力フォーム、日報の集計マクロ、在庫の棚卸しツール——Excelマクロで動いている業務ツールが壊れた時、「プログラミングできる人」がいないと業務が止まる。
この記事は、プログラマーではない製造業の現場担当者やDX推進担当者に向けて書いている。「C#って何?」からスタートして、1つの業務ツール(検査データ入力フォーム)を実際に作り上げるところまでを一緒にやっていく。
私自身、製造業の生産技術部門で5年以上働きながら、業務ツールをExcel VBAからC# WinFormsに移行してきた。プログラミングの専門教育を受けたわけではない。だからこそ、「プログラミングに詳しくない人」がどこでつまずくか、を身をもって知っている。
この記事で作るもの
製造現場の「検査データ入力フォーム」を作る。完成するとこんな動きになる:
- 品番とロット番号を入力する
- 測定値を入力する
- 「登録」ボタンを押すと、データがCSVファイルに保存される
- 入力履歴が一覧で見える
Excelでやっていることの「フォーム化」だ。Excelとの違いは、誤入力を防げること。品番の形式が違えばエラー表示、測定値が範囲外なら警告——そういった「ガードレール」を付けられる。
前提条件
- Windows PCが使える(Windows 10 / 11)
- Excelで関数を使ったことがある程度のPC操作力
- プログラミング経験は不要
Step 1: 開発環境を準備する(15分)
Visual Studio Community のインストール
C#のプログラムを書くために、Visual Studio Communityという無料ツールをインストールする。
- ブラウザで「Visual Studio Community」を検索してダウンロードページを開く
- 「無料ダウンロード」ボタンをクリック
- ダウンロードしたインストーラーを実行する
インストーラーが起動すると「ワークロードの選択」画面が出る。ここが最初の分岐点だ。
「.NET デスクトップ開発」にチェックを入れる。 これだけでいい。他のチェックは外したままで問題ない。
インストールには10〜15分かかる。コーヒーでも入れて待とう。
Step 2: プロジェクトを作成する(5分)
Visual Studioを起動したら、以下の手順で新しいプロジェクトを作る。
- 「新しいプロジェクトの作成」 をクリック
- 検索ボックスに 「winforms」 と入力
- 「Windows フォーム アプリ」(C# と書いてある方)を選択して「次へ」
- プロジェクト名に 「InspectionTool」 と入力
- 保存場所はデスクトップでOK
- フレームワークは 「.NET 8.0」 を選択して「作成」
画面に灰色の四角形(フォーム)が表示されたら成功だ。これが、これから作るツールの「外見」になる。
画面の見方
Visual Studioの画面は情報量が多くて圧倒されるが、最初に使うのは3箇所だけ。
| 場所 | 名前 | 何をするところか |
|---|---|---|
| 中央 | フォームデザイナー | ボタンやテキストボックスをドラッグで配置する |
| 右上 | ソリューションエクスプローラー | ファイルの一覧(Excelのシート一覧のようなもの) |
| 右下 | プロパティウィンドウ | 選択した部品の設定を変える |
他のウィンドウは今は無視していい。使うタイミングが来たらその都度説明する。
Step 3: 画面をデザインする(20分)
ここからが楽しいところ。画面の左側にある**「ツールボックス」**(表示されていなければメニューの「表示」→「ツールボックス」)から部品を選んで、フォーム上にドラッグ&ドロップする。
配置する部品
以下の部品をフォームに配置する。Excel的に言えば、「セルに入力欄やボタンを貼り付ける」イメージだ。
| 部品 | 名前(Name) | 用途 |
|---|---|---|
| Label | lblProductId | 「品番」という表示 |
| TextBox | txtProductId | 品番を入力する欄 |
| Label | lblLotNo | 「ロット番号」という表示 |
| TextBox | txtLotNo | ロット番号を入力する欄 |
| Label | lblValue | 「測定値」という表示 |
| TextBox | txtValue | 測定値を入力する欄 |
| Button | btnRegister | 「登録」ボタン |
| DataGridView | dgvHistory | 入力履歴の一覧表示 |
名前の付け方のルール
部品を配置したら、必ず名前(Name)を変更する。これはExcelの「セルに名前を付ける」のと同じだ。
部品を選択して、右下のプロパティウィンドウの一番上にある 「(Name)」 を変更する。
-
TextBoxなら先頭にtxt(txtProductId, txtLotNo) -
Buttonなら先頭にbtn(btnRegister) -
Labelなら先頭にlbl(lblProductId) -
DataGridViewなら先頭にdgv(dgvHistory)
「なぜわざわざ名前を付けるの?」と思うかもしれない。TextBox1, TextBox2, TextBox3 のままだと、コードを書く時に「TextBox2って何の入力欄だっけ?」となる。Excelのシートに「Sheet1, Sheet2, Sheet3」と名前を付けないのと同じ理由だ。
Labelの文字を変える
各Labelの Text プロパティを変更する:
-
lblProductIdの Text → 「品番」 -
lblLotNoの Text → 「ロット番号」 -
lblValueの Text → 「測定値」
Buttonも同様に:
-
btnRegisterの Text → 「登録」
フォームのサイズと配置
フォーム自体のプロパティも設定する:
- Text: 「検査データ入力」(タイトルバーに表示される)
- Size: 「600, 500」(幅600ピクセル × 高さ500ピクセル)
部品の配置は上から順に「品番」「ロット番号」「測定値」「登録ボタン」、下半分に「履歴一覧(DataGridView)」という構成にすると使いやすい。
Step 4: 動きを付ける — 最初のコード(15分)
ここからプログラミングに入る。といっても、最初に書くコードは10行程度だ。
フォーム上の 「登録」ボタンをダブルクリック する。すると、コードの画面に切り替わり、こんなコードが自動で作られる:
private void btnRegister_Click(object sender, EventArgs e)
{
}
この { } の間に、「登録ボタンが押された時にやること」を書く。Excel VBAで Private Sub CommandButton1_Click() の中に処理を書くのと同じだ。
まずはメッセージを出してみる
いきなり本番の処理を書く前に、ボタンが反応するか確認しよう。
private void btnRegister_Click(object sender, EventArgs e)
{
MessageBox.Show("ボタンが押されました!");
}
画面上部の 「▶」ボタン(開始) をクリックすると、ツールが起動する。「登録」ボタンを押して、メッセージが出ればOK。
おめでとう。これであなたの最初のC#プログラムは動いた。
入力値を取得する
次に、テキストボックスに入力された値を使う。
private void btnRegister_Click(object sender, EventArgs e)
{
string productId = txtProductId.Text;
string lotNo = txtLotNo.Text;
string value = txtValue.Text;
MessageBox.Show($"品番: {productId}, ロット: {lotNo}, 測定値: {value}");
}
txtProductId.Text は「txtProductIdというテキストボックスに入力されている文字列」という意味。Excelの Range("A1").Value と似た概念だ。
$"品番: {productId}" の $ は「文字列の中に変数を埋め込む」という書き方。VBAの "品番: " & productId と同じことを、もう少し読みやすく書ける。
Step 5: 入力チェックを付ける(10分)
ここがExcelとの大きな違い。「変な値を入力させない」仕組みを作れる。
private void btnRegister_Click(object sender, EventArgs e)
{
// 空欄チェック
if (string.IsNullOrWhiteSpace(txtProductId.Text))
{
MessageBox.Show("品番を入力してください。", "入力エラー",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtProductId.Focus(); // カーソルを品番欄に戻す
return;
}
if (string.IsNullOrWhiteSpace(txtLotNo.Text))
{
MessageBox.Show("ロット番号を入力してください。", "入力エラー",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtLotNo.Focus();
return;
}
// 測定値が数値かチェック
if (!decimal.TryParse(txtValue.Text, out decimal measureValue))
{
MessageBox.Show("測定値は数値で入力してください。", "入力エラー",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtValue.Focus();
return;
}
// 測定値の範囲チェック(例: 0〜100の範囲)
if (measureValue < 0 || measureValue > 100)
{
MessageBox.Show("測定値は0〜100の範囲で入力してください。", "範囲エラー",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtValue.Focus();
return;
}
// ここまで来たら入力OK
MessageBox.Show("入力チェックOK!");
}
コードの読み方のコツ:
-
if (条件) { 処理 }→ 「もし条件が成り立つなら、処理を実行する」 -
string.IsNullOrWhiteSpace(テキスト)→ 「空欄(スペースだけも含む)かどうか」 -
decimal.TryParse(テキスト, out 変数)→ 「テキストを数値に変換できるか試す。できたら変数に入れる」 -
return;→ 「この先の処理をやめて、ボタンクリックの処理を終了する」
Excelのデータ入力規則(「整数のみ」「0〜100」等)と同じことを、より柔軟に設定できる。
Step 6: CSVファイルに保存する(15分)
入力チェックが通ったデータを、CSVファイルに保存する。Excelで「名前を付けて保存 → CSV」をやるような処理を自動化する。
private void btnRegister_Click(object sender, EventArgs e)
{
// --- 入力チェック(Step 5のコードをここに書く) ---
// 空欄チェック
if (string.IsNullOrWhiteSpace(txtProductId.Text))
{
MessageBox.Show("品番を入力してください。", "入力エラー",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtProductId.Focus();
return;
}
if (string.IsNullOrWhiteSpace(txtLotNo.Text))
{
MessageBox.Show("ロット番号を入力してください。", "入力エラー",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtLotNo.Focus();
return;
}
if (!decimal.TryParse(txtValue.Text, out decimal measureValue))
{
MessageBox.Show("測定値は数値で入力してください。", "入力エラー",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtValue.Focus();
return;
}
if (measureValue < 0 || measureValue > 100)
{
MessageBox.Show("測定値は0〜100の範囲で入力してください。", "範囲エラー",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtValue.Focus();
return;
}
// --- CSVに保存 ---
string csvPath = Path.Combine(
Application.StartupPath, "inspection_data.csv");
// ファイルがなければヘッダー行を書く
if (!File.Exists(csvPath))
{
File.WriteAllText(csvPath, "日時,品番,ロット番号,測定値\r\n");
}
// データ行を追記
string line = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}," +
$"{txtProductId.Text}," +
$"{txtLotNo.Text}," +
$"{measureValue}\r\n";
File.AppendAllText(csvPath, line);
MessageBox.Show("登録しました!", "完了",
MessageBoxButtons.OK, MessageBoxIcon.Information);
// 入力欄をクリアして次の入力に備える
txtValue.Text = "";
txtValue.Focus();
}
ポイント:
-
Application.StartupPathはツールの実行ファイルがある場所。CSVファイルはツールと同じフォルダに保存される -
File.AppendAllTextは「ファイルの末尾に追記」。既存データを消さずに追加する - 登録後に測定値欄だけクリアする。品番とロット番号は同じ製品を連続で測定する場合に残しておくと便利だ
Step 7: 履歴を一覧表示する(15分)
最後に、CSVに保存したデータを画面の一覧(DataGridView)に表示する。
フォームデザイナーに戻って、フォーム自体をダブルクリック する(ボタンではなくフォームの灰色部分)。するとForm1_Loadというイベントが作られる。これは「フォームが表示された時に実行される処理」だ。
private void Form1_Load(object sender, EventArgs e)
{
LoadHistory();
}
private void LoadHistory()
{
string csvPath = Path.Combine(
Application.StartupPath, "inspection_data.csv");
if (!File.Exists(csvPath))
return;
// DataGridViewの列を設定
dgvHistory.Columns.Clear();
dgvHistory.Columns.Add("日時", "日時");
dgvHistory.Columns.Add("品番", "品番");
dgvHistory.Columns.Add("ロット番号", "ロット番号");
dgvHistory.Columns.Add("測定値", "測定値");
// CSVを読み込んで行を追加
dgvHistory.Rows.Clear();
var lines = File.ReadAllLines(csvPath);
// 1行目(ヘッダー)をスキップして、データ行を追加
foreach (var line in lines.Skip(1))
{
var columns = line.Split(',');
if (columns.Length >= 4)
{
dgvHistory.Rows.Add(columns[0], columns[1], columns[2], columns[3]);
}
}
}
そして、登録ボタンの処理(btnRegister_Click)の最後に LoadHistory(); を追加する:
// 入力欄をクリアして次の入力に備える
txtValue.Text = "";
txtValue.Focus();
// 履歴を再読み込み
LoadHistory();
}
これで、データを登録するたびに一覧が更新される。
完成! 実行してみよう
「▶」ボタン を押してツールを起動する。
- 品番に「P001」、ロット番号に「L2026-001」、測定値に「85.3」と入力
- 「登録」ボタンを押す
- 「登録しました!」のメッセージが出て、下の一覧に行が追加される
- 空欄で登録しようとするとエラーメッセージが出る
- 測定値に「abc」と入れると「数値で入力してください」と表示される
ここまでの所要時間は約1時間半。 VBAの知識がなくても、ここまでのツールが作れる。
Excelマクロとの違いを実感する
作ったツールをExcelマクロと比較してみよう。
| 観点 | Excelマクロ | C# WinForms |
|---|---|---|
| 入力チェック | データ入力規則(限定的) | 自由にカスタマイズ可能 |
| 誤操作への耐性 | シートを触って壊す事故 | フォームなのでデータに直接触れない |
| 複数人での利用 | ファイル共有でロック発生 | ツールを配布、データはCSV/DBで共有 |
| バージョン管理 | 「最新版はどれ?」問題 | Gitで履歴管理(後から学べばOK) |
| 動作環境 | Excelが必要 | .NETランタイムのみ(無料) |
特に大きいのは「誤操作でシートが壊れない」こと。Excelマクロの最大のリスクは、ユーザーがシートの行を削除したり、列を入れ替えたりして構造が壊れること。WinFormsアプリでは、ユーザーはフォームの入力欄にしか触れないので、データ構造が壊れる心配がない。
ここから先に進みたい人へ
この記事で作ったのは「動く最小単位」だ。実際の業務で使うには、もう少し機能が欲しくなるだろう。次のステップとして、こんな方向がある:
すぐできること(数時間〜1日)
- CSVではなくExcelファイルに保存する → ClosedXMLライブラリを使う(「ClosedXMLでExcel帳票を自動生成する」で解説)
- コンボボックスで品番を選択式にする → 手入力のミスを減らせる
- 検索機能を付ける → ロット番号で過去データを検索
もう少し頑張ると(数日〜1週間)
- データベースに保存する → SQLite(ファイル1つで動くDB)と組み合わせる
- 帳票出力 → 検査成績書をExcelテンプレートに流し込む
- グラフ表示 → 測定値の推移をリアルタイムでグラフ化
本格的にやるなら
- 計測器との連携 → NI-VISAでデジタルマルチメータ等から自動取得(「WinFormsでVISA計測器制御アプリを作る」で解説)
- VBAからの移行 → 既存マクロをC#に段階的に書き換える(「VBA→C#書き換えパターン集」で解説)
よくある質問
Q: Visual Studioは本当に無料? 会社で使っても大丈夫?
Visual Studio Community は、年商100万ドル(約1.5億円)未満の企業なら無料で商用利用できる。中小製造業であれば問題ない。詳しくはMicrosoftのライセンス条件を確認してほしい。
Q: 作ったツールを他の人のPCでも使えるようにするには?
Visual Studioの「発行」機能を使うと、インストーラー付きで配布できる。相手のPCに.NETランタイム(無料)がインストールされていればそのまま動く。.NET 8以降は「自己完結型」で発行すれば、ランタイムのインストールすら不要にできる。
Q: ExcelのVBAマクロとC# WinFormsを並行して使える?
使える。一気に全部移行する必要はない。まず1つのツールをWinFormsで作ってみて、良ければ徐々に増やすのが現実的だ。
Q: C#のプログラミングで困ったらどうすればいい?
GitHub Copilot(月額10ドル〜)を使うと、コードの書き方をAIが提案してくれる。「この処理をC#で書きたい」と日本語で伝えれば、かなり正確なコードを出してくれるので、初学者の強い味方になる。
まとめ
この記事では、プログラミング未経験の製造業担当者が、C# WinFormsで検査データ入力ツールを1時間半で作る手順を解説した。
作ったもの:
- テキストボックスとボタンの入力フォーム
- 空欄チェック・数値チェック・範囲チェック
- CSVファイルへの保存
- DataGridViewでの履歴表示
ポイント:
- WinFormsはドラッグ&ドロップでUIを作れる。コードを書くのは「ボタンが押された時の処理」だけ
- Excelマクロとの最大の違いは「誤操作で壊れない」こと
- 1つ作って動かしてみれば、2つ目からは格段に速くなる
「プログラミングは専門家のもの」という思い込みが、製造業のDXを止めている最大の壁だと思う。この記事が、その壁を少しでも低くするきっかけになれば嬉しい。
Discussion
1億ドルではなく100万ドルです。約1.5億円なので、規模感としては、個人事業主やスタートアップを想定しているのかなぁと。
ご指摘ありがとうございます🙇♂️
修正いたしました。