Help us understand the problem. What is going on with this article?

RPAで業務を効率化って、専用ソフトとか無くてもソコソコできますよ

More than 1 year has passed since last update.

きっかけ

身近で「某社のRPAのソフトを契約して、事務系の業務を自動化するんだぁ」って話が複数聞こえてきて。。。
そんなん無くても、「VBScriptだけでもソコソコの作業は自動化できるよ」ってのが伝わらないので、自分の作業自動化用に作っていたVBScriptのClassを公開してみます。

概要

仕事で、PC(Windows)でやって大抵の作業は

  • ブラウザの操作(ちゃんと制御できるのはIEのみですが)
  • マウス操作
  • キーボード入力

ができれば、ほぼいけます(ただし、「力業で何とか」の場合もありますが)。

あとは、

  • エクセル操作
  • ファイルの入出力

あたりでしょうか。

ちょっと特殊(?)なところで

  • CSVにSQLを投げて検索、集計

ができれば、大丈夫かな。
あとは、その組み合わせで、日々の定型業務はこなせると思います。

で、「VBScriptでもClass作れるんじゃん」ってことを、恥ずかしながら最近知ったので、Class化して便利に使っている、今日この頃です。

Classファイル

IE関連

IeUtilClass.vbs
' IE関連のクラス
Class IeUtilClass
    ' 内部変数宣言 -------------------------------------------------------------
    Private Ie

    ' コンストラクタ
    Private Sub Class_Initialize()
        Set Ie = CreateObject("InternetExplorer.Application")
    End Sub
    ' デストラクタ
    Private Sub Class_Terminate()
        Set Ie = Nothing
    End Sub

    ' Public関数 ---------------------------------------------------------------
    ' URLオープン
    Public Sub Navigate(str)
        Ie.Navigate(str)
    End Sub

    Public Sub Visible(bln)
        Ie.Visible = bln
    End Sub

    Public Sub FullScreen(bln)
        Ie.FullScreen = bln
    End Sub

    Public Sub Quit
        Ie.Quit
    End Sub

    Public Sub WaitProc
        Do While ie.Busy = True Or ie.readystate <> 4
        Loop
    End Sub

    Public Function getElementById(id)
        Set getElementById = Ie.document.getElementById(id)
    End Function

    Public Function GetElementsByName(name)
        Set GetElementsByName = Ie.document.GetElementsByName(name)
    End Function

    Public Function GetElementsByClassName(name)
        Set GetElementsByClassName = Ie.document.GetElementsByClassName(name)
    End Function

    Public Function GetElementsByTagName(name)
        Set GetElementsByTagName = Ie.document.GetElementsByTagName(name)
    End Function

End Class

マウス関連

以下のサイトを参考に(というか、ほぼそのまま)クラス化しました。
VBScriptでマウスポインタを動かしたりクリックしたり座標を取得したりするサンプル · GitHub

マウスを操作するには、WindowsのAPIをたたく必要がありますが、エクセルを使えば簡単なようです。
「まぁ、ほとんどの業務用のPCならExeclはあるでしょ」ってことで、APIたたくのにExcelを使って楽してます。
「エクセル使うのやだ」って方は・・・ググってください m(__)m
(そういうサンプルも見かけました)

MouseUtilClass.vbs
' マウス関連のクラス
Class MouseUtilClass
    ' 内部変数宣言 -------------------------------------------------------------
    Private Excel
    Private SCREEN_X
    Private SCREEN_Y

    ' Property宣言 -------------------------------------------------------------
    ' Private-----------------------------------------------
    'キーコード
    Private Property Get VK_SHIFT
        VK_SHIFT = &H10
    End Property
    'マウス定数
    Private Property Get MOUSEEVENTF_ABSOLUTE
        MOUSEEVENTF_ABSOLUTE = &H8000&
    End Property
    Private Property Get MOUSE_MOVE
        MOUSE_MOVE = &H1
    End Property
    Private Property Get MOUSEEVENTF_LEFTDOWN
        MOUSEEVENTF_LEFTDOWN = &H2
    End Property
    Private Property Get MOUSEEVENTF_LEFTUP
        MOUSEEVENTF_LEFTUP = &H4
    End Property

    ' Private関数 --------------------------------------------------------------
    ' コンストラクタ
    Private Sub Class_Initialize()
        Dim items
        Set items = CreateObject("WbemScripting.SWbemLocator").ConnectServer.ExecQuery("Select * From Win32_VideoController")
        For Each item In items
            SCREEN_X = item.CurrentHorizontalResolution
            SCREEN_Y = item.CurrentVerticalResolution
        Next
    End Sub
    ' デストラクタ
    Private Sub Class_Terminate()
        Set Excel = Nothing
    End Sub

    ' Public関数 ---------------------------------------------------------------
    'クリック
    Public Sub MouseClick
        Dim dwFlags
        dwFlags = MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP
        Call API_mouse_event(dwFlags, 0, 0, 0, 0)
        WScript.Sleep 100
    End Sub

    'SHIFT+クリック
    Public Sub MouseClickShift
        Dim dwFlags

        Call API_keybd_event(VK_SHIFT,0,1,0)
        dwFlags = MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP
        Call API_mouse_event(dwFlags, 0, 0, 0, 0)
        Call API_keybd_event(VK_SHIFT,0,3,0)
        WScript.Sleep 100
    End Sub

    'ダブルクリック
    Public Sub DoubleClick
        MouseClick
        MouseClick
    End Sub

    'マウスポインタ移動
    Public Sub MouseMove(x, y)
        Dim pos_x, pos_y, dwFlags

        dwFlags = MOUSEEVENTF_ABSOLUTE Or MOUSE_MOVE
        pos_x = Int(x * 65535 / SCREEN_X)
        pos_y = Int(y * 65535 / SCREEN_Y)
        Call API_mouse_event(dwFlags, pos_x, pos_y, 0, 0)
        WScript.Sleep 100
    End Sub

    ' マウスポインタの座標取得
    Public Function GetMousePos()
        GetMousePos = API_GetMessagePos
    End Function
    Public Function GetMousePosX()
        Dim pos
        pos = API_GetMessagePos
        GetMousePosX = pos(0)
    End Function
    Public Function GetMousePosY()
        Dim pos
        pos = API_GetMessagePos
        GetMousePosX = pos(1)
    End Function

    ' Private関数 --------------------------------------------------------------
    '************************
    'APIを叩く処理
    '************************
    Private Sub API_mouse_event(dwFlags, dx, dy, dwData, dwExtraInfo)
        Dim strFunction
        Const API_STRING = "CALL(""user32"",""mouse_event"",""JJJJJj"", $1, $2, $3, $4, $5)"
        strFunction = Replace(Replace(Replace(Replace(Replace(API_STRING, "$1", dwFlags), "$2", dx), "$3", dy), "$4", dwData), "$5", dwExtraInfo)
        Call Excel.ExecuteExcel4Macro(strFunction)
    End Sub

    Private Sub API_keybd_event(bVk, bScan, dwFlags, dwExtraInfo)
        Dim strFunction
        Const API_STRING = "CALL(""user32"",""keybd_event"",""JJJJJ"", $1, $2, $3, $4)"
        strFunction = Replace(Replace(Replace(Replace(API_STRING, "$1", bVk), "$2", bScan), "$3", dwFlags), "$4", dwExtraInfo)
        Call Excel.ExecuteExcel4Macro(strFunction)
    End Sub

    Private Function API_GetMessagePos()
        Dim ret, strHex, x, y
        Dim strFunction
        Const API_STRING = "CALL(""user32"",""GetMessagePos"",""J"")"
        strFunction = API_STRING
        ret = Excel.ExecuteExcel4Macro(strFunction)
        strHex = Right("00000000" & Hex(ret), 8)
        x = CLng("&H" & Right(strHex, 4))
        y = CLng("&H" &  Left(strHex, 4))
        API_GetMessagePos = Array(x, y)
    End Function
End Class

キーボード関連

Sendkeysは半角のみ(全角は未対応)なので、全角を投げたい場合はクリップボード経由で行うのですが、そこはSendkeys関数を宣言して、内部で「全角を含むかどうか」を判断し、Sendkeysでいくか、クリップボードを使うかを判断しています。

KeyboardUtilClass.vbs
' キーボード関連のクラス
Class KeyboardUtilClass
    ' 内部変数宣言 -------------------------------------------------------------
    Private wsh

    ' Private関数 --------------------------------------------------------------
    ' コンストラクタ
    Private Sub Class_Initialize()
        Set wsh = WScript.CreateObject("WScript.Shell")
    End Sub
    ' デストラクタ
    Private Sub Class_Terminate()
        Set wsh = Nothing
    End Sub

    ' Public関数 ---------------------------------------------------------------
    'クリック
    Public Sub Sendkeys(str)
        If Len(str) = LenByte(str) Then
            wsh.SendKeys str
        Else
            ' 全角文字が含まれている場合は、クリップボード経由で
            wsh.Run "cmd.exe /c echo " & str & "| clip", 0, true 
            wsh.SendKeys "^v"
        End If
    End Sub

    ' Private関数 --------------------------------------------------------------
    Private Function LenByte(ByVal s)
        Dim c, i, k
        c = 0
        For i = 0 To Len(s) - 1
            k = Mid(s, i + 1, 1)
            If (Asc(k) And &HFF00) = 0 Then
                c = c + 1
            Else
                c = c + 2
            End If
        Next
        LenByte = c
    End Function
End Class

呼び出しサンプル

上記のクラスの呼び出しサンプルです。
呼び出し元のスクリプトで、クラスファイルを読み込む必要があるので、そのへんを参考にしてください。
操作の自動化をしていると、どうしても「マウスカーソルを特定の座標に移動させて、クリック」みたいなことが必要になります。
そんなとき、「ここの座標っていくつよ?」を調べるためのスクリプトです。
(カーソルを移動させるのはオマケ)

フォルダ構成が以下の場合のサンプルです。

VBScripts
│  99.mousepos.vbs
│
└─lib
        IeUtilClass.vbs
        KeyboardUtilClass.vbs
        MouseUtilClass.vbs
99.mousepos.vbs
' マウス座標取得スクリプト

' ライブラリ読み込み
    Dim fso
    Set fso = CreateObject("Scripting.FileSystemObject")
    ' 実行ファイルパス取得
    Dim myPath
    myPath = fso.getParentFolderName(WScript.ScriptFullName)
    ' マウス関連クラス -------------------------------------
    Dim libMouse
    Set libMouse = fso.OpenTextFile(myPath & "\lib\MouseUtilClass.vbs")
    ExecuteGlobal libMouse.ReadAll()
    libMouse.Close
    Set libMouse = Nothing

' メイン処理 -------------------------------------------------------------------
    Dim mouseUtil
    Set mouseUtil = New MouseUtilClass

    Dim pos
    WScript.Echo "3"
    WScript.Sleep(1000)
    WScript.Echo "2"
    WScript.Sleep(1000)
    WScript.Echo "1"
    WScript.Sleep(1000)
    pos = mouseUtil.GetMousePos()
    WScript.Echo pos(0) & " / " & pos(1)

    WScript.Sleep(1000)
    WScript.Echo "Move to "
    WScript.Sleep(1000)
    Call mouseUtil.MouseMove(pos(0)+100,pos(1)+100)

    ' 解放
    Set mouseUtil = Nothing
    Set fso = Nothing
    '終了
    WScript.Quit

ひとまず

ここまで。

  • ファイルの入出力

は、次の機会に。
ファイルの読み書きは、文字コードの問題があるので、クラス化しとくと便利ですね。

会社業務だと、

  • エクセル操作
  • データベース関係
  • CSVにSQLを投げて検索、集計
  • ネットワークドライブの接続・切断

あたりを使うこともありますね。
CSVにSQL投げて検索は地味に便利です。
でも、このへんはクラスにしてみましたが、あまり便利感がなかったのは、僕の作り方が悪かったのか・・・というところ。
(要望があれば、公開します)

Kiyotaka
肩書きは「システムエンジニア兼インストラクタ」。 業務は主にPMとインストラクタ。 プログラミングを小学生から社会人まで教えてます。 最近はRPA(っぽいこと)を手掛けることが多く、VBScriptのスキルがアップしています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした