適材適所

PowerShellを中心にプログラミングやシステム管理の備忘録的なブログ

Personal CommunicationsをVBAで操作してAS400の作業をプチRPAする

AS400改め、IBMiは登場以来、いぶし銀の活躍を見せるオフコンで、

その黒画面に緑文字は、ある種の郷愁を思い出させるところであります。

f:id:shinmai_papa:20210415230948p:plain

( ´ー`)フゥー...テンションあがるわぁ・・・(白目)

昔は専用の3270や5250端末で接続していました(同軸ケーブルで(白目))が、今はエミュレータソフトを介して接続することが一般的です。

エミュレータソフトはパソコンにインストールして使えるので、自分の机にいながらにしてAS400を操作することできます。

うーん、すごい時代だ。

話を戻して。

エミュレータソフトにはマクロ機能というものが備わっていることがあります。

マクロ機能を使えば簡単なスクリプトを書いたり、記録機能などを駆使して、繰り返し業務等を自動化することができます。

ロボティック・プロセス・オートメーション(RPA)ですね!!

IBM謹製のPersonal Communicationsのマクロ機能

IBM謹製のエミュレータソフトであるPersonal Communicationsにもマクロ機能が備わっております。

このマクロ機能、マクロ言語の形式を選択することができ、VBスクリプトファイル形式で記録することができます。

f:id:shinmai_papa:20210415231113p:plain

保存されたマクロファイルはまんまVBScriptなので、そこから他のアプリケーションを起動することもできます。

もちろんExcelを操作することもできます。

この辺の話も記事にしたい・・・。

でも今回は別の話しです。

これを活用するだけでもかなり楽できるんですが、

実はPersonal CommunicationsはCOMインターフェースも備えているため、VBA他、プログラミング言語から扱うことができます。

事務作業の影の主役となっているExcelと、Personal Communicationsを通して基幹システムのAS400の作業を絡めて自動化できればPersonal Communicationsを使った単純作業は大体完結させることができるかと思います。

今回はPersonal CommunicationsをVBAから操作してプチRPAする方法を紹介したいと思います。

(以下Personal CommunicationsはPCOMMと言うことにします)

⇒PowerShell バージョンも書きました。

www.tekizai.net

VBAからPCOMMを操作してデータを入力する

前提条件

下記にコードの例を示しますが、コーディング時にインテリジェンスを働かせるため、参照設定をすることをお勧めします。

参照設定の一覧を見ると「PCOMM」とついたものがたくさんあります。

とりあえず、「PCOMM」とついているものに一通りチェックをつけておきます。

f:id:shinmai_papa:20210415231224p:plain

こうすることでVBAのコーディングが楽になります。

何かの事情でどうしても参照設定したくない人は、CreateObjectでも大丈夫です。

下記のコードにもコメントで参考に書いておきます。

コード

 
Sub pcommsample()
    'PCOMMの起動準備
    Dim conList As AutConnList: Set conList = New AutConnList ' CreateObject("PCOMM.autECLConnList") 
    Dim conMgr As AutConnMgr: Set conMgr = New AutConnMgr 'CreateObject("PCOMM.autECLConnMgr")
    Dim oia As AutOIA: Set oia = New AutOIA 'CreateObject("PCOMM.autECLOIA")
    Dim ps As AutPS: Set ps = New AutPS  'CreateObject("PCOMM.autECLPS")
    
    '随所にWaitを入れる
    '入れないとExcelが結構クラッシュする
    Application.Wait 3
    conList.Refresh
    '別のPCOMMウィンドウが起動していないか確認
    '起動していたら面倒なので処理を単純にするため終了させる。
    'エミュレータを一度全て終了してからもう一度処理してください。
    If conList.Count <> 0 Then
        Exit Sub
    End If
    'プロファイルを指定してPCOMMを起動
    'プロファイルは予め作成しておきます。
    'というか普段AS400を使っているならPCに保存されているはず。
    '〇〇.WSというファイルの〇〇を指定します。
    conMgr.StartConnection "profile=〇〇"
    '起動完了待ち
    Do While conList.Count = 0
        Application.Wait 3
        DoEvents
        'リフレッシュしないとCountが更新されない
        '仕様なのでリフレッシュし続けます
        conList.Refresh
    Loop
    '操作対象のPCOMMを特定するためセッション名を取得する
    Dim sessionName As String: sessionName = conList(1).Name
    
    '操作対象のPCOMMをセットする
    oia.SetConnectionByName sessionName
    ps.SetConnectionByName sessionName
    
    Application.Wait 3
    oia.WaitForInputReady
    '6行目,53列目に「USER」と入力する。
    ps.SetText "USER", 6, 53
    'Enterを押す
    ps.SendKeys "[enter]"
    'F3キーを押す
    ps.SendKeys "[pf3]"

    'ちゃんと解放しないと次に起動したとき
    'Excelがクラッシュする可能性が高い
    Set conList = Nothing
    Set conMgr = Nothing
    Set oia = Nothing
    Set ps = Nothing
    
End Sub

各種オブジェクトの関係図

オブジェクト間の関係はこんな風になっているらしいです。

f:id:shinmai_papa:20210415231321p:plain

autECLConmMgrオブジェクトの中にautECLConnListオブジェクトが含まれていたり、autECLSessionオブジェクトの中にautECLOIAやautECLPSが含まれているとのことですが、autECLConmMgrオブジェクトを通しautECLConnListオブジェクトを呼び出すとコーディング時にインテリジェンスが働かなかったので、上記のコードではあえて独立して宣言して呼び出すようにしています。

各オブジェクトの詳しい解説は公式サイトが詳しいです。

https://www.ibm.com/support/knowledgecenter/ja/SSEQ5Y_6.0.0/com.ibm.pcomm.doc/books/html/host_access08.htm

ほかにも色々できるよ!!

上記の例では、PCOMMの立ち上げ、キーの送信の例を書いてみましたが、画面の内容を取得して画面の内容に応じて処理を分岐させて・・・なんてこともできます。

その辺りは需要があれば記事にしようと思います。

終わりに

Personal ComminicationsをVBAで操作するプチRPAの紹介でした。

Excelに処理すべきキーと入力値を入れて置いてそれを順番に処理させたり、入力項目が多い画面について、あらかじめExcelに記入しておいて、まとめてPCOMMにまとめて転記等・・・。応用範囲はかなり広いと思います。

もしPCOMMで毎日同じ操作をしている人がいたら、ぜひこの辺りの技術を応用して楽してもらいたいですね・・・。

面倒な仕事は目の前のPCにやらせましょう。

適材適所で行きましょう。

以上、ここまでお読みいただき、ありがとうございました。

プチRPA!?な記事

www.tekizai.net

www.tekizai.net

www.tekizai.net

www.tekizai.net

www.tekizai.net

www.tekizai.net

`; Array.prototype.forEach.call(document.getElementsByClassName('kijinai_koukoku'),function(d){d.innerHTML=KIJINAI_ADS;}); Array.prototype.forEach.call(document.getElementsByClassName('adsbygoogle'), function(){ (adsbygoogle = window.adsbygoogle || []).push({});}); -->