単純作業はUWSCで自動化して効率化しよう
「その作業、手動でやる意味ありますか?」
データをコピーペーストするだけの作業、ファイル形式を変換する作業。こういった同じことを繰り返すだけの単純作業は自動で処理したい。そんな要望に答えてくれるのがUWSCです。
UWSCとはWindowsの操作を自動化するソフトです。
大きく分けて二種類の動作方法があります。マウスやキーボードの動作を記録して同じ動作を実行する方法と、スクリプトを書く方法です。
今回は応用が可能な「スクリプトを書く方法」をメインに解説します。
このページは入門編として、UWSCの基本的な使い方と文法、次のページでは応用編として、エクセルでの操作、画像認証を利用した分岐など、実際の仕事に応用できるサンプルを紹介します。
ダウンロード・インストール
UWSCの公式サイトからダウンロード…と言いたいところですが、2018年4月現在、公式の一部ページがダウンしています。
ひとまずVectorからUWSCをダウンロードしてください。
インストール
インストール作業は必要ありません。ダウンロードした圧縮ファイルを解凍するだけで動作します。
解凍したファイルの中に「サンプル.uws」という動作サンプルのスクリプトファイルがあるのでダブルクリックして実行してみてください。
Paintで画像を切り取ったり、メモ帳に計算式を書いたり、電卓で計算して答えを貼り付けたり、しまいには電卓をぐるぐる回したりと、おちゃめな動作サンプルを見ることができます。
UWSCの基本的な使い方
冒頭で紹介した通り、UWSCには2つのタイプの動作方法が用意されています。
録画と再生を利用する方法
まずは「UWSC.exe」をダブルクリックして起動します。
すると以下のようなウィンドウが表示されます。
左から「読込み」「保存」「再生」「記録」「設定」です。
「読込み」ボタンは作成したスクリプトファイルを読み込むボタンです。先程の「サンプル.uws」を読み込んでみてください。
「再生」ボタンでスクリプトを実行できます。
「記録」ボタンをクリックして、適当にマウスを動かします。ウィンドウのボタンがSTOPへと変化していると思うので、クリックして記録を停止します。
この状態で再度、「再生」ボタンをクリックしてください。すると先ほど動かしたマウスの動きを再現してくれます。
「保存」ボタンを押して記録したマウスの動きをスクリプトファイルに書き出します。今回は「マウスの動き.UWS」という名前で保存しました。
保存したファイルをテキストエディタで開いてみてください。以下のようなファイルが書き出されていると思いまます。
1 2 3 4 5 6 7 8 | MMV(383,683,1094)MMV(395,683,15)MMV(410,683,16)MMV(426,684,16)MMV(449,691,15)MMV(471,699,16)MMV(491,706,15)MMV(506,714,16) |
これがマウスの動きを再現したスクリプトです。
MMV()はUWSCの関数で、マウスの動きを再現する際に利用します。
MMV()の書式は以下のとおりです。
MMV( x, y, [ms] ) |
第一引数からマウスのx座標、y座標、実行までの秒数(ms秒)となります。
ちなみにクリックはBTN()という関数を利用します。
BTN(ボタン,状態,[X, Y, ms]) |
第一引数からボタン(LEFT, RIGHT, MIDDLE, WHEEL)、状態(CLICK, DOWN, UP)、x座標、y座標、実行までの秒数(ms秒)となります。
この2つの関数を組み合わせることで「マウスで移動してクリックする」という動作が再現できます。
UWSCにはこのような関数が多数用意されています。
関数の一覧は以下のサイトに詳しく解説されています。
スクリプトを編集する方法
先に紹介した録画ボタンを使う方法は直感的でわかりやすいのですが、複雑な処理は向きません。
今回はスクリプトで記述することの利点を理解していただくために、特定の2箇所を連続で10回クリックするという処理を書いてみます。
「test.uws」というファイルを作成して以下のスクリプトをコピペしてみてください。
1 2 3 4 | FOR i = 1 TO 10 BTN(LEFT,CLICK,100, 100, 10) BTN(LEFT,CLICK,200, 200, 10)NEXT |
保存したらダブルクリックして実行します。マウスポイントが高速に移動してクリックを繰り返すと思います。
先ほど紹介したBTN()関数で画面の左上からX座標が100px、Y座標がと200pxのポイントを10ms秒間隔でクリックしています。
ループ処理の方法は複数ありますが、今回はFOR-NEXT文を利用しました。
FOR-NEXT文の書式
FOR 変数 = 初期値 TO 終了値 [ STEP 刻み値 ] 処理NEXT |
長い処理の場合は現在何番目の処理をしているのか表示したいという場合があります。
そのような時はPRINTを使います。
1 2 3 4 5 | FOR i = 1 TO 100 PRINT "i:" + i BTN(LEFT,CLICK,100, 100, 10) BTN(LEFT,CLICK,200, 200, 10)NEXT |
すると以下の様がウィンドウが出てきて何番目の処理か表示することができます。
長い処理の途中で停止したいという場合もあると思います。
50回実行後にメッセージボックスを表示し、停止するか選べるスクリプトを書いてみます。
1 2 3 4 5 6 7 8 9 10 | FOR i = 1 TO 100 PRINT "i:" + i IFB i = 50 IFB MsgBox("処理を継続しますか?", BTN_YES or BTN_NO) = BTN_NO Exit ENDIF ENDIF BTN(LEFT,CLICK,100, 100, 10) BTN(LEFT,CLICK,200, 200, 10)NEXT |
IFB-ENDIFという条件分岐を利用してiが50のときと、メッセージボックスでNOが選ばれたときの2つの分岐を追加しています。
IFBのBはブロックと言う意味です。IFも使えますが、こちらは一行でしか書けないので、UWSCではあまり使われません。
このように自分でスクリプトを編集すれば、様々な状況に柔軟に対応できます。
UWSCの基本的な構文
UWSCを使いこなすには独自の構文を覚える必要があります。ただ独自と言っても、プログラムを学んだことのある方には馴染みのものばかりです。
1つ注意していただきたいのは、UWSCの関数や制御文は大文字小文字を区別しません。混乱を避けるために、このサイトでは全て大文字で記述します。
デバッグ(出力の方法)
まずは基本となる出力方法です。
以下のスクリプトを実行してみてください。
1 | PRINT "Hello world." |
「Hello world.」と書かれたウィンドウが表示されたと思います。しかしウィンドウがすぐに閉じてしまいます。そこで、SLEEP()を使って時間を停止します。
1 2 | PRINT "Hello world."SLEEP(1) |
これで表示後、1秒間表示されたままになります。
このSLEEP()はよく使う関数なので覚えておいてください。
もしくは以下のようにメッセージボックスで表示する方法もあります。
1 | MSGBOX( "Hello world" ) |
これならメッセージボックスを閉じるまで表示することができます。
コメント
スラッシュ2つで、それ以降がコメントになります。
1 | // コメント |
または以下のようにTEXTBLOCKで囲むことで複数行のコメントも可能です。
1 2 3 4 5 | TEXTBLOCK 説明この部分はすべてコメントになります。ENDTEXTBLOCK |
この方法は本来コメント用のものではありません。この例では「説明」という変数へ複数行の文字列を代入しています。複数行のコメントに「ダブルスラッシュを入力するのが面倒」という場合にコメント代わりに利用することがあります。
このような事情から、コメント目的で使い場合、変数名はユニーク(他とかぶらないよう)にしてください。
変数(配列、多次元配列)
UWSCの変数には型がありません。すでに紹介したとおり、大文字小文字も区別しません。
以下のようにグローバル変数と多次元配列は宣言が必要です。
ローカル変数(宣言はなくても可)
1 | DIM 変数名 |
グローバル変数
1 | PUBLIC 変数名 |
多次元配列(変数の数を指定し、宣言が必要)
1 | DIM 変数名[num] |
ただし以下のような場合は変数の数の宣言が不要
1 | DIM 変数名[] = 1, 2, 3 |
文字列
文字列はダブルコーテーションで囲みます。
大文字小文字は区別しません。結合には「+」を利用します。
1 2 3 4 5 6 7 8 9 | STR = "文字列"PRINT STR // 文字列STR = "文字列" + "に追加する"PRINT STR // 文字列に追加するSTR = "文字列"STR = STR + "に追加する"PRINT STR // 文字列に追加する |
改行する場合は「<#CR>」を利用します。
1 2 3 | STR = "文字列"STR = STR + "<#CR>で改行する"PRINT STR // 文字列(ここで改行)で改行する |
同じようにダブルコーテーションを表示するには「<#DBL>」、タブを表示するには「<#TAB>」を利用します。
演算子
加算
PRINT 1 + 2 // 3 |
減算
PRINT 2 - 2 // 0 |
乗算
PRINT 2 * 2 // 4 |
除算
PRINT 2 / 2 // 1 |
剰余算
PRINT 5 MOD 3 // 2 |
小なり
PRINT 0 < 1 // Ture |
大なり
PRINT 1 > 0 // Ture |
以下
PRINT 0 <= 1 // TurePRINT 1 <= 1 // Ture |
以上
PRINT 2 >= 1 // TurePRINT 1 >= 1 // Ture |
等しい
PRINT 1 = 1 // Ture |
等しくない
PRINT 1 <> 0 // TurePRINT 1 <> 1 // False |
否定
PRINT ! ( 1 > 0 ) // FalsePRINT ! ( 1 > 2 ) // Ture |
論理和
左右どちらかがTRUEのときに1を返す。
UWSCの論理演算はTRUEの時に1、FALSEの時に0を返す。
PRINT FALSE OR TRUE // 1PRINT FALSE OR FALSE // 0 |
論理積
左右どちらもTRUEの場合1を返す。
PRINT TRUE AND TRUE // 1PRINT FALSE AND TRUE // 0 |
排他的論理和
左右の片方がTRUEで、もう片方がFALSEの場合1を返す。
PRINT FALSE XOR TRUE // 1PRINT FALSE XOR FALSE // 0PRINT TRUE XOR TRUE // 0 |
演算式の優先順位。上から優先される。
( ) !*、 /、 MOD+、 ->、 < 、 =、 >=、 < =、 <>ANDOR、 XOR |
条件式
IF-ENDIF
IF-ENDIFで条件式を記述できます。
上でも解説しましたが、IFBのBはブロックと言う意味です。IFも使えますが、こちらは一行でしか書けないので、UWSCではあまり使われません。
IF 式 [THEN] (もしくはIFB) 真[ELSEIF 式 [THEN]] :[ELSE] 偽ENDIF |
REPEAT-UNTIL
条件の成否にかかわらず一度は実行する処理がある場合はREPEAT-UNTILを利用します。
REPEAT処理UNTIL 条件 |
条件はFalseの場合ループが継続。Trueで終了します。
1 2 3 4 | REPEAT PRINT "出力" SLEEP(1)UNTIL 1 > 10 |
上の例では条件がTrueになることがないので無限ループになります。
このような場合に処理を停止する場合はAlt + F2キーを利用します。
無限ループを避けるにはループ中で条件がTrueになるように変更します。
i = 0REPEAT PRINT "出力" i = i + 1 SLEEP(0.1)UNTIL 10 < i |
SELECT-SELEND
複数の条件でそれぞれ異なる処理をする場合にSELECT-SELENDを利用します。
CASEの条件に一致する場合、その下の処理を実行します。すべての条件に合わない場合はDEFAULTの処理が実行されます。
以下の例は変数にAからEまでの文字列を入れて、値をランダムで取り出してそれぞれの処理を実行しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 | DIM ABC[] = "A", "B", "C", "D", "E"SELECT ABC[ RANDOM(5) ]CASE "A" PRINT "A"CASE "B" PRINT "B"CASE "C" PRINT "C"DEFAULT PRINT "D or E"SELENDSLEEP(1) |
行結合
アンダースコアで複数の行を1つの行として処理できます。
1 2 3 4 5 6 | VAR _= _1 _+ _1PRINT VAR // 2 |
マルチステートメント
上の行結合とは別に、一つの行に複数のスクリプトを記述する方法。セミコロンを文末に記述する。
1 | VAR = 1 + 1; PRINT VAR |
可読性が落ちるので、特に理由のない限り使わないほうが良い。
例外処理
例外にはTRY-EXCEPT-ENDTRYを使います。
変数に想定していない型の値が入力されたというようなエラーが発生する際に実行する処理を記述します。
書式 TRY 処理(エラー) EXCEPT 処理 ENDTRY |
TRY-EXCEPT-ENDTRYの例
1 2 3 4 5 6 7 8 | TRY VAR = "hoge"; VAR = 1 / VAR print "正常に終了"EXCEPT print "エラー発生"ENDTRYSLEEP(1) |
TRY-EXCEPTの間に処理を記述し、エラーが発生した時点でEXCEPT-ENDTRYに記述された処理が実行されます。
例文を実行するとVARに文字列が入っているのでエラーになります。そのため「正常に終了」という処理を行う前にエラーとなるため「エラー発生」と出力されます。
ためしにhogeの部分に適当な数字を入力して実行してみてください。今度は「正常に終了」と表示されます。
TRY-FINALLY-ENDTRYという記述方法もあります。こちらはエラーのあるなしにかかわらず、FINALLY-ENDTRYに記述された処理を実行するというものです。
TRY-FINALLY-ENDTRYの例
1 2 3 4 5 6 7 8 | TRY VAR = "hoge"; VAR = 1 / VAR print "正常に終了"FINALLY print "これは必ず実行"ENDTRYSLEEP(1) |
通常であれば文字列を割り算に利用しているのでエラーが出て処理が停止しますが、この例の場合は「これは必ず実行」というメッセージが表示されます。
ちなみに、エラーメッセージは「TRY_ERRMSG」と「TRY_ERRLINE」という特殊な変数に格納されます。
定数定義
CONSTで定義を行うと定数になります。定数に別の値を入れようとするとエラーになる。
1 2 3 | CONST VAR = 10PRINT VAR // 10VAR = 15 // エラー |
外部スクリプトの取り込み
CALLの後にファイル名を指定します。
1 | CALL UWSファイル名 |
OPTION指定
スクリプトファイルごとにオプションを指定することができます。
OPTION <以下の項目を指定、複数の場合は(,)カンマ区切りも可> |
| EXPLICIT | 変数宣言強制、全ての変数でDIM もしくはPUBLIC宣言が必要 |
|---|---|
| SAMESTR | 文字比較、置換、サーチにて大文字、小文字を区別 |
| OPTPUBLIC | PUBLIC変数の重複定義を禁止 |
| OPTFINALLY | Try-Finally間で強制終了が発生した時にも必ず Finally部を実行 |
| SPECIALCHAR | 実行時に特殊文字(<#CR><#DBL><#TAB>)の変換を無視 |
| SHORTCIRCUIT | 論理演算(IF、IFB、WHILE、REPEAT)で短絡評価 |
| DEFAULTFONT= フォント名 | フォント、サイズを変更(MSGBOX、FUKIDASI、ログ等に反映) e.g. “MS ゴシック,16″ |
| POSITION=X, Y | 位置変更 |
| LOGPATH= ログパス名 | ログファイルのパス、ファイル名を変更 |
| LOGLINES= ログ行数 | ログ最大行数を変更 |
| LOGFILE= ログ出力モード | 1:出力しない、2:日付を付けない、3:秒も付ける、4:以前のログは消去 |
| DLGTITLE= タイトル | INPUT, MSGBOX, SLCTBOX でのタイトルを変更 |
http://canal22.org/control/option/より
OPTIONの例)変数宣言の強制と表示位置を設定
1 2 3 | OPTION EXPLICIT,POSITION=0,0DIM OK = 11133PRINT OK |
ループ処理
FOR-NEXT
特定の回数繰り返し実行する場合に利用します。
FOR 変数 = 初期値 TO 終了値 [ STEP 刻み値]処理NEXT |
FOR-NEXTで1ずつ10までプラスするサンプル
1 2 3 4 | FOR i = 1 TO 10 PRINT "i:" + i SLEEP(0.1)NEXT |
iが1から10まで処理を繰り返します。この例では10回。
WHILE-WEND
特定の条件がTrueの間は処理を継続します。
WHILE 条件処理WEND |
WHILE-WENDで1ずつ10までプラスするサンプル
1 2 3 4 5 6 | i = 1WHILE i < 10 PRINT "i:" + i i = i + 1 SLEEP(0.1)WEND |
iが10になるまで処理を繰り返しています。ループ内でiがインクリメントされないと無限ループになる点に注意してください。
回数ではなく、特定の時間繰り返す、といった場合は以下のようにします。
1 2 3 4 5 6 7 8 9 10 | i = 1TIME = GETTIME()WHILE i < 1000 PRINT "i:" + i i = i + 1 IFB ( GETTIME() - TIME ) > 10 BREAK ENDIF SLEEP(1)WEND |
1秒に1回ループ処理を行い、10秒以上経過すると停止します。
カウントが1000回でスリープの時間が1秒なので、普通であれば1000秒処理を繰り返します。
そこでGETTIME()で秒数を取得し、現在の時間との差が10秒以上になったときにBREAKでWHILE処理を抜けています。
特定の時間だけ実行するという場合によく使います。
関数
関数にはPROCEDURE型とFUNCTION型があります。
PROCEDUREは返り値の無いもの、FUNCTIONはRESULTで返り値の設定が必要となります。
書式は以下のとおりです。
PROCEDURE 関数名( 引数, Var 引数, 引数[], Var 引数[][], 引数=定数, …. ) 処理FENDFUNCTION 関数名( 引数, Var 引数, 引数[], Var 引数[][], 引数=定数, …. ) 処理 RESULT = 戻り値 // Result に戻り値を入れるFENDVar 宣言を付けると引数を変更可能とする(参照引数)配列変数には次元数分 []を付ける (2次元配列の場合 引数[][] )= 定数 にてデフォルトパラメータを指定できる(デフォルトパラメータ以降に通常引数を書く事はNG) |
ちなみに関数名も大文字小文字を区別しません。
関数を抜けるにはEXITと記述します。EXITEXITと2つ記述するとプログラム自体を終了します。
クラス化、モジュール化
共通で利用する関数や定数をCLASS-ENDCLASSでクラス化することが可能です。MODULE-ENDMODULEと書くこともできます。どちらも同じ動作です。
クラス内の要素はそれぞれ以下のように動作します。
| CONST 変数 | 名前.変数名で外部からアクセス可 |
|---|---|
| PUBLIC 変数 | 名前.変数名で外部からアクセス可 |
| DIM 変数 | 外部からアクセス不可 |
| PROCEDURE モジュール名/クラス名 | コンストラクタ |
| PROCEDURE 関数名() | メソッド |
| FUNCTION 関数名() | メソッド |
例えばよく使う関数をCOMMON.UWSというファイルにまとめておけば、後で簡単に再利用できます。
今回はサンプルで「COMMON.UWS」というファイルを作成し、以下を記述し保存します。
1 2 3 4 5 6 | CLASS COMMON CONST HOGE = "ほげ" FUNCTION PLUS_10( VAR ) RESULT = VAR + 10 FENDENDCLASS |
定数HOGEの定義と、引数に10をプラスする関数です。
続いて別ファイルを作成。「COMMON.UWS」と同じフォルダに保存します。
CALL COMMON.UWS // 外部スクリプトの読込みPRINT COMMON.HOGE // ほげPRINT COMMON.PLUS_10( 10 ) // 20SLEEP(1) |
まずCALLで先程のファイルを読込みます。
定数を呼び出すには、クラス名の後にドット「.」でつないで定数名を指定します。
メソッドの場合も同じようにドットでつないで関数名(引数)を指定します。
UWSCの基本劇な書式について解説しました。
普段からプログラムに慣れ親しんでいる方なら、簡単に理解できると思います。
次のページではこれらを組み合わせてEXCELの操作や、特定の画像が出てきた際にクリックするといった方法を紹介します。