LoginSignup
1
4

More than 3 years have passed since last update.

Seleniumで月末に作成する勤務時間表の作成自動化(C#)

Last updated at Posted at 2020-11-09

前回、pythonで単純作業を自動化したものの、C#バージョンです。
微妙に処理内容がpythonの時と違うのであしからず。

自動化の概要

自動化する業務内容

二次受けとして参画しているPJにて、
一次受けの会社に対して月末に勤務時間をまとめたExcelを提出する。

自動化前の業務手順

  1. 日々の業務時間を自社サイトに記録
  2. 月末になったら、自社サイトから日時の出退勤時間を目視で参照
  3. 一時受け指定のExcelに転記
  4. 担当者に提出

上記2, 3の出退勤時間の転記を自動化しました。

自動化後の業務・処理手順

  1. 日々の業務時間を自社サイトに記録
  2. WorkingTimeGet.exe 実行
    (1)【元データ取得】
    ①Seleniumで自社サイトへアクセスし、ID, PASSを入力
    ②ログインボタンをクリックし、ログイン
    ③勤務時間の照会ページへ遷移
    ④HTMLを取得(Webページは閉じる)
    (2)【データ加工、Excel作成】
    ①Tableタグから各項目を取得し、IEnumerableにつっこむ
    ②テンプレートから新規Excelを作成
    ③Excelを開き出退勤時間をセット
    ④Excelを保存して終了
  3. 担当者に提出

使用技術

.NET Core (3.1)
Selenium.WebDriver (3.141.0)
Selenium.WebDriver.ChromeDriver (86.0.4240.2200)
AngleSharp (1.0.0-alpha-844)
EPPlus (4.5.3.3)
※EPPlusの最新は5だけど、ライセンスが変わったので一応…

ソースコード

ソースコード
WorkingTimeGet
using AngleSharp.Html.Parser;
using OfficeOpenXml;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;
using System.IO;
using System.Linq;
using System.Reflection;

namespace WorkingTimeGet
{
    class Program
    {
        static void Main(string[] args)
        {
            // 自社サイトからHTML取得
            string html = GetHtml();

            // HTMLをパースし、必要な情報を取得
            var parser = new HtmlParser();
            var doc = parser.ParseDocument(html);
            var table = doc.QuerySelectorAll("[name=\"{nameセレクタの値}\"] tr")
                .Select(tr =>
            {
                // td単位でデータを取得する
                var td = tr.GetElementsByTagName("td");

                var date = td[0].TextContent.Trim(); // 日付
                var workFrom = td[1].TextContent.Trim(); // 出勤時間
                var workTo = td[2].TextContent.Trim(); // 退勤時間

                return new { Date = date, WorkFrom = workFrom, WorkTo = workTo };
            });

            // Excelへの書き込み
            // テンプレートファイルの存在チェック
            string tmpFile = @"..\勤務表(XXXX)_yyyyMMdd.xlsm";
            if (!File.Exists(tmpFile))
                throw new FileNotFoundException("テンプレートファイルが存在しません。");

            // 新規Excelに必用な情報を入力
            Console.WriteLine("勤務表作成者の苗字と作成年月を半角スペース区切りで指定してください。");
            Console.WriteLine("例)作成者:田中、作成年月:2020年11月 ⇒ 田中 202011");
            string[] values = Console.ReadLine().Split(' ');

            while (values.Length != 2)
            {
                Console.WriteLine("入力が間違っています。");
                values = Console.ReadLine().Split(' ');
            }

            string outFile = @"..\勤務表(" + values[0].ToString() + ")_" + values[1].ToString() + ".xlsm";
            string year = values[1].Substring(0, 4);
            string month = values[1].Substring(4, 2);

            if (File.Exists(outFile))
                File.Delete(outFile);

            // テンプレートから新規Excelを作成
            File.Copy(tmpFile, outFile);
            FileInfo newFile = new FileInfo(outFile);
            using (var package = new ExcelPackage(newFile))
            {
                var ws = package.Workbook.Worksheets["{シート名}"];

                int row = 6;
                const int colFrom = 3;
                const int colTo = 5;

                table.ToList().ForEach(item =>
                {
                    ws.Cells["R2"].Value = year;
                    ws.Cells["S2"].Value = month;

                    ws.Cells[row, colFrom].Value = item.WorkFrom;
                    ws.Cells[row, colTo].Value = item.WorkTo;

                    // 中略(その他の処理)

                    row++;
                });

                package.Save();

            }
        }

        private static string GetHtml()
        {
            const string loginPage = @"{ログインページのURL}";
            const string targetPage = @"{勤務時間取得ページのURL}";

            // Webドライバーのインスタンス化
            IWebDriver driver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));

            // 自社サイト(ログインページ)へアクセス
            driver.Navigate().GoToUrl(loginPage);

            // ID・PASSを入力
            Console.WriteLine("ログインIDを入力してください。");
            driver.FindElement(By.Id("{ID入力欄の要素id}")).SendKeys(Console.ReadLine());
            Console.WriteLine("ログインパスワードを入力してください。");
            driver.FindElement(By.Id("{PASS入力欄の要素id}")).SendKeys(Console.ReadLine());
            // ログインボタンのクリック
            driver.FindElement(By.Name("{ログインボタンの要素id}")).Click();

            // 勤務時間取得用のページへ遷移し、HTML取得
            driver.Navigate().GoToUrl(targetPage);
            string html = driver.PageSource;

            // ブラウザを閉じる
            driver.Quit();

            return html;
        }
    }
}

参考

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4