GNU makeとMakefileの機能を把握したら、後はこれを仕事に応用していくだけだ。この方法は実のところ、今のWindowsと相性が良い。現在のWindowsはUbuntuが使えるようになっているし、MSYS2といったアプリケーションも使える。要するに、LinuxのツールをWindowsのツールとして利用できる。事務処理などはWindowsを使うことが多いので、ここにMakefileを組み合わせると日々の業務を整理できるのだ。今回は、そのサンプルを見ていこう。

仕事をMakefileに落とし込む - 経理処理編

前回、毎日の売上関係の経理処理をMakefileに整理する方法を取り上げた。仕事ごとにディレクトリを作ること、毎日発生するような仕事は日付のディレクトリを作成してさらに分けること、必要なMakefileを用意することなどを説明した。

前回は、経理処理用のディレクトリおよびファイル構造として次のサンプルを取り上げた(今回の説明のために、1つファイルを増やしてある)。

$ tree 経理処理(売上関係)
経理処理(売上関係)
├── Makefile
├── mk
│   └── base.mk
└── templates
    ├── mailbody
    └── Makefile

2 directories, 4 files
$

それぞれ内容は次のようなものにした。

◆経理処理(売上関係)/Makefile

all:    clean

#========================================================================
# 新規作業ディレクトリのセットアップ
#========================================================================
add:
    dir=$$(date +%Y%m%d);                       \
                                    \
    if  [ ! -e $${dir} ];                   \
    then                                \
        mkdir   -p $${dir};                 \
        cp  templates/Makefile              \
            $${dir}/;                   \
    fi

#========================================================================
# クリーンナップ
#========================================================================
clean:
    for i in 20*;                       \
    do                              \
        cd  $${i};                      \
        make    clean;                      \
        cd  ..
    done

◆経理処理(売上関係)/templates/Makefile

include ./../mk/base.mk

◆経理処理(売上関係)/mk/base.mk

fetch:
    # 経理関連データの取得処理

edit:
    # 経理関連データの編集処理

report:
    # 作成した経理報告データを提出する処理

clean:
    # 不要なデータの削除処理

「経理処理(売上関係)/Makefile」はその日の業務を開始するための処理が、「経理処理(売上関係)/mk/base.mk」には日ごとの処理が書いてある。

こうした構造にすることで、仕事は全てmakeコマンドを起点にして進んでいくようになっている。手順はMakefileに記載してあるので、ユーザーは「make ターゲット」というコマンドを順次実行し、それに従って作業をしていくだけという状態だ。

前回なかったのは「templates/mailbody」ファイルだ。これは、報告書をメールで送信するときの本文が書いてあるファイルである。メールの新規作成もスクリプトで自動化することができるので、その目的で用意した。

このように可能な限り自動化することで、日々の業務の効率をアップさせることができる。機械ができることは機械にやらせる、これが今のビジネスマンに求められる基本的なスキルの一つだ。

同じことをWindowsで実行する

日本で最も多く販売されているPCは、Windows OSを搭載したものだ。仕事ではMicrosoft Officeが使われることが多い。売上データの編集に関してもMicrosoft Excelを使うのが一般的だろう。

Linuxをデスクトップで使い、統合オフィスアプリケーションを使ったりMicrosoft OfficeやGoogle Driveといったクラウドアプリケーションを使うということもできる。開発者や情報処理に長けた方ならば、それで何ら問題はない。

しかしながら会社の環境がWindowsを強要するケースは多く、Windowsで処理できた方がつぶしが効くのは間違いない。Windowsでこれまで取り上げてきたGNU makeを使うようにすると、WindowsのパワーもLinuxのパワーも利用できる。

前回用意した「経理処理(売上関係)/mk/base.mk」を、Windowsで使うことを想定してまとめてみよう。とりあえず今回はMSYS2を使うことを想定して作ってみる。MSYS2に関しては本連載で何度か取り上げているので、そちらを参考にしてもらえればと思う(参考:【連載】にわか管理者のためのLinux運用入門)。

◆経理処理(売上関係)/mk/base.mk - MSYS2 on Windows編

#========================================================================
# ディレクトリに記述されている日付
#========================================================================
date=$(notdir $(shell pwd))

#========================================================================
# 使用するアプリケーション
#========================================================================
ecl="C:\Program Files\Microsoft Office\root\Office16\ecl.EXE"
mail="mail.ps1"

#========================================================================
# POSから売上データを取得
#========================================================================
fetch:
    scp postdata:~/sales/$(date)/sales.csv          \
        ./

#========================================================================
# 売上データの処理および編集アプリケーションの起動
#========================================================================
edit:
    prog1   sales.csv
    $(ecl)  sales.csv
    cp  sales.csv                       \
        C:\\Users\\$(USERNAME)\\Desktop\\売上報告書.csv

#========================================================================
# 売上データの処理および編集アプリケーションの起動
#========================================================================
report:
    mail.ps1                            \
    -To     報告先メールアドレス              \
    -Cc     CCメールアドレス             \
    -Subject    【日報】$(date)締め売上関連データ報告書     \
    -Attachment C:\\Users\\$(USERNAME)\\Desktop\\売上報告書.csv
    -BodyFromFile   ./../templates/mailbody

clean:
    不要なデータの削除処理
  • WindowsでMakefileを利用する

    WindowsでMakefileを利用する

上記内容を整理すると次のようになる。

  • fetch: scpでPOSデータが配置されているサーバからデータをコピーしてくる。
  • edit: プログラムでデータを事前処理、Mirosoft Excelを起動してデータを編集、編集後にファイルをデスクトップへコピーする。
  • report: 編集したデータを添付ファイルとして新規メールを作成する。

Makefileの中で使っている「mail.ps1」というPowershellスクリプトは、Thunderbirdを使って新規メールを作成するためのラッパースクリプトだ。次のような内容になっており、コマンドラインから新規メールを作成できるようになっている。

#!/usr/bin/env pwsh

#========================================================================
# メールコンポーザ起動スクリプト
#========================================================================

#========================================================================
# 引数を処理
#   -To a@example.com,b@example.com 宛先メールアドレス
#   -Cc a@example.com,b@example.com Ccメールアドレス
#   -Bcc a@example.com,b@example.com    Bcccメールアドレス
#   -From bar@example.com       送信元メールアドレス
#   -Subject 'Mail Title'       メールサブジェクト
#   -Body 'Mail body'           メール本文(引数で指定)
#   -BodyFromFile file1.txt     メール本文(ファイルで指定)
#   -BodyFromClip           メール本文(クリップボードからコピー)
#   -Attachment file1.jpg,fil2.png  添付ファイル
#========================================================================
Param(
    [String]$To = $Env:DEFAULT_EMAIL_TO,
    [String]$Cc = "",
    [String]$Bcc = "",
    [String]$From = $Env:DEFAULT_EMAIL_FROM,
    [String]$Subject = "メール送付",
    [String]$Body = "",
    [String]$BodyFromFile = $null,
    [Switch]$BodyFromClip,
    [String]$Attachment = ""
)

#========================================================================
# Thunderbirdアプリケーションパス
#========================================================================
$mailer = 'C:\Program Files\Mozilla Thunderbird\thunderbird.exe'

#========================================================================
# 本文の上限文字数
#========================================================================
# これ以上の値を指定するとThuderbirdがクラッシュすることがある
$bodycharlimit = 24000

#========================================================================
# メール本文を取得するとともに、Thunderbirdのコンポーザに貼り付けできる
# フォーマットへ変換
#========================================================================
if ($BodyFromClip) {
    # システムクリップボードから本文をコピーする場合
    $body = Get-Clipboard | Out-String
}
elseif ($BodyFromFile) {
    # ファイルから本文を持ってくる場合
    $body = Get-Content -Path $BodyFromFile -Raw
}

$body = $body -replace " "," "
$body = $body -replace "<","&lt;"
$body = $body -replace ">","&gt;"
$body = $body -replace "    ","<pre style='display:inline'>&#009;</pre>"
$body = $body -replace ",","&#044;"

#========================================================================
# 引数で指定できる文字列長には上限がある。上限を超えている場合には、上限
# 未満まで文字数を減らして使用する。
#========================================================================
function Get-TrimmedBody {
    # 上限文字数で文字列を切り捨てる。
    $trimmed = $body.Substring(0, $bodycharlimit)

    # 文字列の末尾がこの配列の文字列の途中で切れていたと判断できる
    # 場合に、配列の文字列の分も削除する。これら文字列はすべて記載
    # されている必要があり、途中で切れている場合には削除する必要が
    # ある。
    $a = $("&nbsp;",
           "&lt;",
           "&gt;",
           "<pre style='display:inline'>&#009;</pre>",
           "&#044;")
    :EndTreatment foreach ($v in $a) {
        $len = $v.Length - 1
        for ($i=0; $i -lt $len; $i++) {
            $v = $v.Substring(0, $len - $i)
            if ($trimmed.EndsWith($v)) {
                $trimmed = $trimmed.Substring(0, $trimmed.Length - $v.Length)
                break EndTreatment
            }
        }
    }

    # 終端処理を行った文字列を返す
    $trimmed
}

if ($body.Length -gt $bodycharlimit) {
    $body = Get-TrimmedBody
    $body += "<br>"
    $body += "<br>"
    $body += "(サイズオーバーでカットしました)"
}

#========================================================================
# To、Cc、BccをThunberbirdで指定できる形へ展開
#========================================================================
$to = $to.Replace(' ',',')
$cc = $cc.Replace(' ',',')
$bcc = $bcc.Replace(' ',',')

#========================================================================
# 添付ファイルのパスを絶対パスへ変換
#========================================================================
# 「,」区切りで最初のファイルを調べ、このファイルが存在しなかった場合には
# 「 」区切りで渡されていると判断し、分割処理を行う
$AttachmentFiles = $Attachment -Split ','
if (-not (Test-Path $AttachmentFiles[0])) {
    $AttachmentFiles = $Attachment -Split ' '
}

# パスを相対パスから絶対パスへ変換する
$len = $AttachmentFiles.Length
$AttachmentPaths = ""
for ($i = 0; $i -lt $len; $i++) {
    if ($AttachmentFiles[$i]) {
        $AttachmentPaths += Convert-Path $AttachmentFiles[$i]
        if ($i -ne $len - 1) {
            $AttachmentPaths += ","
        }
    }
}

#========================================================================
# メールを作成
#========================================================================
& $mailer                               `
    -compose                            `
    "to='$To',cc='$Cc',bcc='$Bcc',from='$From',subject='$Subject',attachment='$AttachmentPaths',body='$Body'"

mail.ps1の作り方は、その内容については筆者の別連載で取り上げているので、興味がある方はそちらを参照していただければと思う(参考:【連載】PowerShell Core入門 - 基本コマンドの使い方)。

Windowsの作業をMakefileでまとめていく

Windowsにはさまざまな自動化ツールが用意されている。現在ではPower Automateを無料で使うことができるので、GUIベースでの自動化も簡単だ。

WSLとGNU makeや、MSYS2とGNU makeでも自動化の一助を担うことができる。何も、全てこの技術で固める必要はない。WindowsであればPowershellで多くの操作ができるし、最近はPower Automateも使えるし、Windows Terminalも素晴らしい仕上がりを見せている。こうしたツールを適材適所で組み合わせて全方位で自動化を進めていけばよい。

makeはかなり歴史の古い技術だが、その本質が色褪せることはない。いつまで経っても本質的に優れたツールの一つであり、活用することで効果が得られやすいソフトウエアでもある。OSの垣根はだいぶ低くなっている。優れたツールは利用し、ビジネスを楽にしていく。こうした取り組みを地道に続けていくことで、長期的に大きな効果を得ることができる。

参考