中小企業で生きていくシステムエンジニアが考えるライフハック・ITツール・投資、人生100年を生き抜く人生戦略、生産性向上をノリックが考える

中小企業で働くシステムエンジニアがライフハック、ツール、投資、人生100年を生き抜く人生戦略、生産性向上を語ります

RPA(ロボテックプロセスオートメーション)なくても、AutoHotKeyでPC入力自動化できますが何か?

 

RPAで効率化って言うけど、前からやってた

 RPAマーケットが盛り上がっている。PCのアプリケーションへの入力を自動化することで事務効率を上げて生産性の向上に結びつけて働き方改革するというはやりの言葉を並べれば、なんかすごいような気がしてくる。しかし私がシステムズエンジニアとして働き出したときからアプリケーションを連携させて事務作業の生産性向上や品質向上をするというのはやってきたことで、何を今更言っているのだろうかという気がする。私が入社したときにはLotus NotesからデータをAccessにデータを取り込んでExcelに出力するとかアプリ連携は普通に行われていたことである。

 いやいや、アプリ連携のための汎用的なソフトウェアが出てきて、IT部門の人でなくても簡単に使えるようになったのがRPAでしょ?ということはあるかもしれない。

 UiPathがお試しで使えたのでRPAがどんなソフトか試してみたが、全然わからなかった。私のスキルレベルが低すぎるのか?少なくとも現場にいるちょっとパソコン使えますという人たちには難しいと感じた。

 

アプリケーション連携といえばエクセルマクロ

 私がシステムズエンジニアになった頃は、ユーザー部門にいるのにエクセルマクロに詳しい人があちこちにいて、その人達が作ったマクロが事務効率化の役割を担っていた。しかし2000年代中頃にはIT内部統制の観点からそのような野良マクロは好ましくないと言ってどんどん廃止されていったのである。おかげでシステムを改修したときに、不要なテーブルと思って削除したら実は野良マクロが使っているテーブルでユーザーがマクロが使えなくなったんだけどどうしてくれるのよ!と文句を言われることもなくなった。

 ユーザー部門主体でRPAが導入されるって野良マクロの二の舞にならないかと思ったが、自社で取り扱っているRPAとかUiPathを見る限りはユーザー部門だけでRPAを導入するのは難しいのではと感じる。

 

ITベンダーにおけるRPA導入

 で、我々システムズエンジニアの領域でRPAって何に使えるのかと考えたときにシステム運用でログを監視してアラートが上がったらメールを投げるとかと思ったが、それだったらRPAでなくて運用監視ソフトを使ったほうが良いよなと思うわけである。

 あとはテストのときにデータをシステムに登録して想定通りの結果になるか検証するわけだが、前の会社では協力会社の人がやってくれていた。この通りに入力してシステムが計算した結果がこのようになるはずだから違ったら協力会社の人が、思ったとおりに出力されないんですけど?って相談に来てくれる。

 中小ITベンダーに転職した今となっては自分でテストケースを考えて自分で入力して自分で検証しなければならない。途方もないデータ件数を入力するのは40歳を過ぎると肩こりがひどい。転職して一発目の案件で久しぶりにテスト実施をしたが、もう懲り懲りである。今、2つ目の案件に取り掛かっているので私が担当するシステムにエクセルの値を自動入力するスクリプトを作って対応することにした。

 

AutoHotKeyで対応する事にした理由

 本当はAppiumで対応したかったが、Windows7対応のアプリをWindows10に対応するようにコンバージョンする必要があり、テスト方法は同じデータを新システム・旧システムそれぞれに入力して比較するテストをしようと思っている。AppiumはWindows10だと動くが、Windows7では動かない。スクリプトもテキストエディタがあれば組めるのでお手軽である。

 

Autohotkeyでエクセルから読込で画面入力するスクリプト

タブキーで移動しながら該当のテキストボックスに来たらエクセルから読み込んだ値を入力しているだけである。テスト対象のアプリケーションを立ち上げておき、Ctrl+Shift+a でスクリプトが起動する。

タブ移動するごとにSleepで1000(1秒)待機を入れているが、これはPC環境によっては500ぐらいにしてよいかもしれない。正直1秒の待機時間だともっさり感があるが、途中で止まるほうが嫌なので、今は1秒間を開けるようにしていいる。 

 

#IfWinActive ,ahk_class WindowsForms10.Window.8.app.0.378734a
^+a::
   objEx := ComObjCreate("Excel.Application")
   objWb := objEx.Workbooks.Open("C:\test\test.xlsx")
   ;objEx.Visible := True
   Sleep 1000
   objWs := objWb.Worksheets("data")
   i = 2
   Sleep 1000

   Sleep 1000
   Send,{home}
   Sleep 1000

   strValue := objWs.Range("B" i).Value ;売上日
   Sleep 1000
  ;値を入力すると自動で次の項目に移ってしまう場合は入力するタブ数が変わるので分岐
if strValue <> "" { Sleep 1000 Send,% strValue Sleep 1000 Send,{tab} Sleep 1000 } Else { Send,{tab}  Sleep 1000 Send,{tab}  Sleep 1000 } strValue := objWs.Range("D" i).Value ;商品コード Sleep 1000 Send,%strValue% Sleep 1000 Send,{tab} Sleep 1000 Send,{tab} Sleep 1000 strValue := objWs.Range("E" i).Value ;数量 Sleep 1000 Send,% strValue Sleep 1000 objWb.Close(False) Sleep 1000 Send,{F2} ;保存 return #IfWinActive

 

残課題

明細形式の画面データ登録とスクリーンショットも自動で撮れると良いな。テスト開始までに調べよう。

追記

明細形式についても対応してみた。

 D列の番号が連番で1,2,3,4・・・と続くと同じ伝票

f:id:norihiko_matsumoto:20190524085931p:plain

エクセルのサンプル

 

単純にループ文を追加しただけですが。大体の画面でちょっとカスタマイズすれば使えるね。

#IfWinActive ,ahk_class WindowsForms10.Window.8.app.0.378734a
^+a::

objEx := ComObjCreate("Excel.Application")
objWb := objEx.Workbooks.Open("C:\test\test.xlsx")
Sleep 1000
objWs := objWb.Worksheets("data")
j = 1

;伝票単位のループ分
Loop
{
j := j + 1
Sleep 1000
strValue := objWs.Range("A" j).Value ;No.

Sleep 1000
if strValue <= 0    ;No
{
 Break
}	
Gosub,Header

;明細行のループ
Loop{
strValue := objWs.Range("E" j).Value ;商品コード
Sleep 1000
Send,% strValue

Sleep 1000
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
strValue := objWs.Range("F" j).Value ;数量
Sleep 1000
Send,% strValue
Sleep 1000
Send,{tab}
Sleep 1000
strValue := objWs.Range("G" j).Value ;単価
Sleep 1000
;単価が設定されていれば登録する。
if strValue <> ""
   Send,% strValue
   Sleep 1000
   Send,+{tab} 
   Sleep 1000
;次の明細があるかどうか確認
strValue := objWs.Range("D" j + 1).Value ;明細No.

if strValue >= 2  
{
  Send,{tab}
  Sleep 1000
  Send,{tab}
  Sleep 1000
  Send,{tab}
  Sleep 1000
  Send,{tab}
  Sleep 1000
  Send,{tab}
  Sleep 1000
  j := j +1 

  Sleep 1000
}
;もし次の伝票番号だったら明細のループを抜ける
else 
{
  Send,{F2}
  Sleep 1000
  Send,{Enter}
  Sleep 1000
  Break ; Terminate the loop
}

}


;もし次の伝票番号もなければテストを終了する。
;strValue := objWs.Range("A" j).Value ;No.
;if strValue <= 0
;{
;Send,{F2}
;Send,{Enter}
;Break ; Terminate the loop
;}
}
;xl.Application.ScreenUpdating := 1
Sleep 1000
objWb.Close(False)
Sleep 1000
msgbox, "終了です。"
return


Header:
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
Send,{home}
Sleep 1000
strValue := objWs.Range("B" j).Value ;売上日
Send,% strValue
Sleep 1000

Send,{tab}
Sleep 1000
strValue := objWs.Range("c" j).Value ;納品先
Sleep 1000
Send,% strValue
Sleep 1000
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
Send,{tab}
Sleep 1000
Return

#IfWinActive


; test.ahkをctrl+sで保存した時にリロードする(vimでは保存はできないがリロードはOK)

SetTitleMatchMode,2

#IfWinActive, test.ahk

^s::

 Send,^s

 Sleep,250

 Reload

return

#IfWinActive

 

 AutoHotKeyに関する基本的な使い方の記事は以下を御覧ください。

 

www.norick-matsumoto.com