WinActorでプログレスバーを表示する

' Progress-Bar

Option Explicit

Dim ScreenWidth, ScreenHeight, Title_ProgressDisplay, ProgressBarWidth, ProgressBarHeight

Dim objIE ' objExplorer needy for Function "ProgressDisplay"

GetMonitorProperties

Title_ProgressDisplay = "Progress-Bar"
ProgressBarWidth = 400
ProgressBarHeight = 150

' Program

Main

' End of Program

' Procedures

Sub Main: Dim Progress
    ProgressDisplay "Open",""
    For Progress = 0 To 100 ' Get Progress from program
        ShowProgress(Progress)
        WScript.Sleep 20
    Next:   ProgressDisplay "Close",""
            MsgBox "Job done"
End Sub

Sub ShowProgress(Progress0to100): Dim Text, k: k = (ProgressBarWidth - 2*19-21)
        Text = "<p align=""center"">Progress " & CStr(Progress0to100) & " %</p>" & _
            "<table border=""0"" cellpadding=""0"" cellspacing=""0""><tr><td width=""" & _
            CStr(k*Progress0to100/100) & _
            """ height=""15"" bgcolor=""#0000FF"">&nbsp;</td></tr></table>"
        ProgressDisplay "Display",Text: WScript.Sleep 20
End Sub

Sub ProgressDisplay (Mode, AnyText): Dim String1, String2, colItems, objItem
    ' Mode = Open, Display, Close
    ' AnyText only used in Display-Mode
    Mode = UCase(Left(Mode,1)) & LCase(Right(Mode,Len(Mode)-1))
    Select Case Mode
        Case "Open"
            Set objIE = CreateObject("InternetExplorer.Application")
            With objIE
                .Navigate "about:blank"
                .ToolBar = False: .StatusBar = False
                .Width = ProgressBarWidth: .Height = ProgressBarHeight
                .Left = (ScreenWidth - ProgressBarWidth) \ 2
                .Top = (ScreenHeight - ProgressBarHeight) \ 2
                .Visible = True
                With .Document
                    .title = Title_ProgressDisplay
                    .ParentWindow.focus()
                    With .Body.Style
                        .backgroundcolor = "#F0F7FE"
                        .color = "#0060FF"
                        .Font = "11pt 'Calibri'"
                    End With
                End With: While .Busy: Wend
            End With
        Case "Display"
            On Error Resume Next ' for clicking away the bar while running
            If Err.Number = 0 Then
                With objIE.Document
                    .Body.InnerHTML = AnyText: WScript.Sleep 200: .ParentWindow.focus()
                End With
            End If
        Case "Close": WScript.Sleep 100: objIE.Quit
    End Select
End Sub

Sub GetMonitorProperties
    Dim strComputer, objWMIService, objItem, colItems, VMD: strComputer = "."
    Set objWMIService = GetObject("winmgmts:\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery("Select * from Win32_VideoController")
    For Each objItem In colItems: VMD = objItem.VideoModeDescription: Next
    ' VMD = 1280 x 1024 x 4294967296 Farben
    VMD = Split(VMD, " x "): ScreenWidth = Eval(VMD(0)): ScreenHeight = Eval(VMD(1))
End Sub

' End of Procedures

今は仕事でWinActorを使ったちょっとした付け合わせ処理を書いている。

ちゃんとしたビジネスRPAなので安定稼働させるために、ブラウザのボタンなどを押す処理には画像マッチングなどは使えない。

あれはちょっと使いもにならない。

と言うのも、可変のリストの下にボタンがあってスクロールしないと押したいボタンが出てこないとなると、非常に厄介で、画面のサイズや拡大縮小にものすごく依存していて、運用条件を色々と限定しなければならないとなると、ちょっとプロの提供するRPAではない。

なので、プロとしては、Domを操作して確実に制御する止まらない安定したRPAの提供を心がけているわけだが、最近はサイトの構築方法も様々で今回、3種類のサイトにログインして必要なデータをダウンロードして付け合わせるなどの処理を自動かしているのだ。

それぞれ構築方法が違うのであるサイトでは厄介なiframeの中を代えているサイトややたらjqueryのダイアログを使うサイトや独自のスクリプトで構築しているグループウェア等のサイトを扱うので、それぞれ全く違うアプローチが必要でまぁそこは長年の勘と経験でなんとかなっているのだが、処理を高速化する為、ExcelやCSV等のファイルは画面に表示する必要が無いので非表示状態で処理をするわけだ。

しかし、そうなると処理中なのか終わったのか等の表現が出来ないので画面にProgressbarを表示する事にした。

しかし、WinActorのノードにはそう言った類いのパーツが見当たらず自前で用意するしかない様で自前で用意したわけだ。

と言ってもネットをくまなく検索して一番良さそうなのを頂戴した。「ここ

色々な人がチャレンジしているみたいだが、どれも妥協出来なかったので探しまくってようやく辿り付いたのがこのProgressbarのスクリプトだ。

これを実践で書いているWinActorのスクリプトノードにはめ込んで、画面には何も出さず、ただ、Progressbarが表示されるだけと言う理想通りのRPAが構築出来た。

処理が終われば、結果ログをグループウェアのメッセージに添付して送信すると言う単純な物なのだが、Progress表示があるのと無いのとでは全然違う印象で、一般的にはprogress表時が当たり前だと思われるので、ユーザに見てもらってもなんの反応も無い。

それがエンジニア冥利に尽きるというもので、ユーザがなんのためらいも無く普通に操作出来ると言うのがいいプログラムだと俺は思っている。

ちょっと前だとWebの入力時にユーザはためらいも無くEnterキーで次の項目に行くと思っているので、当然、Enterが押されれば次のコントロールに行くと言う処理を俺は忘れずに書いているが、別の誰かがそう言う仕様は外部仕様で話しに出なかったと言う事でもめた事がある。

ならばと、俺が引いてそいつの言う通に提供したのだが、案の定、使いにくいと言うクレームが入り、TABキーで移動すると言う説明をしていたみたいだ。

まぁ結局俺がEnterキーで次のコントロールに移動出来る様にしてやったわけだが、ユーザの感覚やリテラシーは見ればわかるわけで、この辺が教科書で勉強してきたヤツと独学でやってきた勘と経験の積み上げで勝負している俺との違いと言う事なんだろう。

そう言う意味ではRPAの構築は俺にとっては水を得た魚の様にすいすいと捗って次から次へ案件をこなしていると早い確実、安定して動くと言うのが更に経験を積み上げることとなり良いことづくめなのだ。

実はRPAはハッキングプログラムなので最も得意とする分野と言う事でもある。

それに、RPAを携わって思うのがExcelが絡んだ案件が多いと言うか、殆どExcelをなんとかする案件ばかりだと感じる。

そんなとき、WinActorのノードでセルの値を拾って別のシートに貼り付けるとかを言うノードをループさせてとか、まぁ見た目のフロチャートがかなりスパゲッティーじみてくるのだが、極力、若いエンジニアにもわかる様に備え付けのノードを多用するようには心がけているが、肝心な部分や速度的な面からスクリプトを細切れにしてノード化して構築する様にしている。

その1つがこのProgressでもあるのだがちゃんとお金を取る仕事なんだから妥協はしない方が身のためだと思うのだ。

最初は面倒でも妥協せずにユーザの思い通りのシステムを構築していくと、それは全部自分の為になるわけで、情けは人のためならずと言うわけだ。

情けは人の為ならずも誤用されていることわざだが、これは、情けは人の為にならないと言う意味では無く、情けは人の為じゃ無く、自分の為だと言うのが本来の意味なんだがなぁ。

それに、このProgressbarをベースに、起動時にダイアログを表示して対話形式RPAを動かすと言う事も簡単に出来るのだが、ノードのいくつかを試して見たが、どうも自分の思っている動きにならず面倒で仕方が無い。

まぁWinActorでお困りのことなら有料でいくらでも相談にのってあげますよ。

ちなみに、このサンプルスクリプトはものすごく癖のある書き方しているので注意が必要で、VB書いた事があれば、コロンを挟んで別のコードを1行に書くというのは知っていると思うけどそう言う作りになっているので、わかりにくければ、コロンのところで改行して見ると、教科書に書いてある様なプロシージャになるのでわかり易くなると思う。

俺がこのスクリプトよく作ったなぁと関心したのは、画面の解像度に応じてちゃんとダイアログを真ん中に表示すると言うのが計算されている部分でしっかりと作り込んでいる。

ただ、言っておくが、このProgressを動かすと当然ではあるが処理は少し遅くなる。

スレッド動作ではなくあくまでもループの間に処理が追加されるのでその分遅くなるわけだが、処理無いようによって適宜使うシーンを考える必要はあるだろう。