Help us understand the problem. What is going on with this article?

【C#】会社への反骨精神からツールを完成させた話

目的意識を持てない作業はやりたくない

過去の記事でも述べてますが私は現在新卒2年目の駆け出しエンジニアです。
弊社では1,2年目はOJT期間として設けられ(手厚い)教育を施されます。
OJT期間には社会人の鉄則「報連相」を身につけるため、会社単位で毎月報告書の提出が義務付けられています。この作業に関しては納得して快く提出していました。
また、担当プロジェクトの定例会議での進捗報告やマネージャーへの報告は欠かさず実施していました。
しかし部内の決まりとして若手はOJT期間に簡易的な週報を作成するというものがあります。
週報のフォーマットは以下です。

20200110_週報.txt
【週報】 1/6~1/10
■今週の報告
1/6 ○○作業
→完了

1/7 ★★作業
⇒進捗率80%

1/8 ★★作業
⇒完了

1/9 休み

1/10 ××作業
⇒進捗率30%

■来週の取り組み
・××作業の続き
・△△作業

この週報は部のファイルサーバに毎週格納するという決まりでした。
書く内容はプロジェクトの業務進捗とその他OJT作業などの進捗を総括したものです。

このフォーマットではまず書く意味があるのかと疑問を抱きます。
また最初のうちはOJT指導者などが週報を閲覧している形跡がありましたが入社して1年が過ぎたころには誰も閲覧しなくなりました。

週報を書きたくないと理由をつけて説明しても「OJT期間はやろう」の一点張りで、要求を受け入れてくれませんでした。

これが会社か。。。
と思いながらもOJT期間中は渋々週報を書くことにしました。

せめて楽したい

やりたくないことはせめて楽したい!
週報作成を自動化しようと思い立ち、何で作ろうかと考えました。
いくつか候補はありましたが(Excelに入力し、VBAを使ってtxtファイルを出力するなど)
ちょうどその時業務でC#を扱っていたので、Windows Formで作ろう!と思いました。

アプリについて

前提

・WindowsFormなのでもちろんWindows環境での動作になります。

機能

・フォームの入力内容から上記フォーマットのテキストファイルを作成する。
・フォーム上で作成日の日付を指定するだけで作業日を含めた過去5営業日を週報に自動出力(土日は非営業日とする)。
・自動的にファイル名を作成日の日付で"YYYYMMdd_週報.txt"にする。

使用方法

①WeekReportForm.exeを実行しアプリを起動する。
main.JPG

②1~5日目の実績と来週の予定を記入する。
main2.JPG

③作成日を指定する。(直接入力orカレンダーから選択)
date.JPG

④フォーム右下のExportボタンをクリックしてダイアログで保存先パスを指定する。
export.JPG

⑤ダイアログのOKボタンをクリックすると週報が作成される。

※入力内容をクリアしたい場合はフォーム右上のクリアボタンをクリックする。

ソースコード

ほとんどコードを書いてません。
IDEが勝手にやってくれます。ありがとうございます。
Visual StudioでメインフォームにTabControlを置いてその上にそれぞれテキストボックスを置きました。日付入力はDateTimePickerを使用しました。

あとはExportボタンとクリアボタンにクリックイベントハンドラを紐づけて、その中にコードを書きました。

Form1.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace WeekReportForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// Exportボタンクリック時動作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            // 各テキストボックスの値を取得
            string text1 = textBox1.Text;
            string text2 = textBox2.Text;
            string text3 = textBox3.Text;
            string text4 = textBox4.Text;
            string text5 = textBox5.Text;
            string next = textBox6.Text;

            string filepath = "";
            // 日付を取得
            DateTime Today = dateTimePicker1.Value;
            string day = Today.Month.ToString() + "/" + Today.Day.ToString();

            FolderBrowserDialog fbDialog = new FolderBrowserDialog();

            // ダイアログの説明文を指定する
            fbDialog.Description = "週報保存先フォルダを選択";

            // デフォルトのフォルダを指定する
            fbDialog.SelectedPath = @"C:";

            // 「新しいフォルダーの作成する」ボタンを表示する
            fbDialog.ShowNewFolderButton = true;

            //フォルダを選択するダイアログを表示する
            if (fbDialog.ShowDialog() == DialogResult.OK)
            {
                filepath = fbDialog.SelectedPath + @"\";
            }
            else
            {
                return;
            }
            // ファイル名決定
            string filename = filepath + 
                Today.Year.ToString() + 
                CheckNum(Today.Month.ToString()) +
                CheckNum(Today.Day.ToString()) +
                "_週報.txt";

            List<int> dayList = WeekCheck(Today.DayOfWeek);

            if (dayList[0] == -1)
            {
                MessageBox.Show("休日に週報は作成できません。");
                return;
            }

            DateTime first = Today.AddDays(-dayList[0]);
            string firstday = first.Month.ToString() + "/" + first.Day.ToString();

            DateTime second = Today.AddDays(-dayList[1]);
            string secondday = second.Month.ToString() + "/" + second.Day.ToString();

            DateTime third = Today.AddDays(-dayList[2]);
            string thirdday = third.Month.ToString() + "/" + third.Day.ToString();

            DateTime fourth = Today.AddDays(-dayList[3]);
            string fourthday = fourth.Month.ToString() + "/" + fourth.Day.ToString();


            // タイトル作成
            StringBuilder sb = new StringBuilder();
            sb.Append("【週報】 " + firstday + "~" + day + "\n");

            // 今週の報告
            sb.Append("■今週の報告\n");
            sb.Append(firstday + " " + text1 + "\n\n");
            sb.Append(secondday + " " + text2 + "\n\n");
            sb.Append(thirdday + " " + text3 + "\n\n");
            sb.Append(fourthday + " " + text4 + "\n\n");
            sb.Append(day + " " + text5 + "\n\n");
            sb.Append("■来週の取り組み\n");
            sb.Append(next);

            File.AppendAllText(filename,sb.ToString());
            MessageBox.Show("週報が作成されました。");

        }

        /// <summary>
        /// 5営業日判定
        /// </summary>
        /// <param name="dow">作成日の曜日</param>
        /// <returns>営業日リスト</returns>
        private List<int> WeekCheck(DayOfWeek dow)
        {
            List<int> retList = new List<int>();
            switch (dow)
            {
                case DayOfWeek.Monday:
                    retList.Add(6);
                    retList.Add(5);
                    retList.Add(4);
                    retList.Add(3);
                    break;
                case DayOfWeek.Tuesday:
                    retList.Add(6);
                    retList.Add(5);
                    retList.Add(4);
                    retList.Add(1);
                    break;
                case DayOfWeek.Wednesday:
                    retList.Add(6);
                    retList.Add(5);
                    retList.Add(2);
                    retList.Add(1);
                    break;
                case DayOfWeek.Thursday:
                    retList.Add(6);
                    retList.Add(3);
                    retList.Add(2);
                    retList.Add(1);
                    break;
                case DayOfWeek.Friday:
                    retList.Add(4);
                    retList.Add(3);
                    retList.Add(2);
                    retList.Add(1);
                    break;
                default:
                    retList.Add(-1);
                    break;
            }
            return retList;
        }

        /// <summary>
        /// ファイル名0追加メソッド
        /// 作成日の月または日が一桁の場合先頭に0を付け二桁にする。
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        private string CheckNum(string i)
        {
            string str = "";

            if (i.Length == 1)
            {
                str = "0" + i;
            }
            else
            {
                str = i;
            }
            return str;
        }

        /// <summary>
        /// クリアボタンクリック時動作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            // 全てのテキストボックスの値をクリアする
            textBox1.ResetText();
            textBox2.ResetText();
            textBox3.ResetText();
            textBox4.ResetText();
            textBox5.ResetText();
            textBox6.ResetText();
        }
    }
}

アイテムの名前などは指定しなかったのでこんなクソみたいなコードになりました。
本当にすみません。

あとがき

会社が無駄な文化を残しておいてくれたお陰でC#の勉強をすることができました。
機会を与えて下さって感謝しています。
開発の原点は便利にしたい、楽したい、だと思うので結果的には"いい開発"になったかなと思います。
毎年入社してくる後輩にはこっそりこのツールを配布して楽してもらおうと思います。

ちなみにGitHubで全てコードは公開しています。同じような境遇の方がいらっしゃったら、コードをいじってフォーマットを整えて使ってみてください!
GitHub/WeekReportForm

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away