2018年の振り返り

Facebook にシェア
Pocket

あけましておめでとうございます。今年もよろしくお願いします。

今年は年賀はがきが高くなったのでそろそろ送るのをやめようかとも思ったのですが、悩んだすえ送りました。個人的には、年賀状はちょっとした面白さを入れたいタイプです。今回は、「謹賀新年」という文字の前に「平成最後の」とつけました。……。はい、新年早々滑りました(さすがに、上層部への年賀状はもっとまともなものにすればよかったかな……)。

それはともかく、年も明けたので昨年、つまり2018年を振り返りたいと思います。昔は、大みそかに、その年に買ってよかった本を紹介していた時もあったのですが、最近は図書館で借りてばかりで本をあまり買っていないので、本の紹介エントリーは書かないことにします(半分、アフィリエイト収入目的だったけど、全く増えないという)。

振り返りために、まず3月に書いた今後やりたいこと、もしくはやめようと思っていること | while(isプログラマ)を見直してみることにします。果たして2018年にちゃんとやれたのでしょうか。

このサイトをHTTPSにする

これは、比較的すぐにやりました。確か、このエントリーを書いて1週間以内でSSL化したかな……、と思ったら5月でした(ブログをSSL(https)化しました | while(isプログラマ))。

パソコンを買う

今話題のマウスコンピューターのパソコンを購入しました | while(isプログラマ)に書いた通り、アマゾンで購入しました。特に不満点はないです(ほとんど外付けディスプレイに表示させて使っているので、ノートパソコンの意味があまりなくなってますが)。

奨学金を全額返済する

返済しました。スカラネット・パーソナル – トップで繰り上げ申請したのですが、なんだかちょっとややこしかった記憶。利子は安いですが、返せる人は速めに返したほうがいいと思います(特に、機関保障を利用した人は)。

ジムを辞める

辞めましたが、近く(隣の駅の近く)に安いジムがあることを知ったのでそちらに乗り換えました。シャワーやプールはないですし、更衣室は狭いですが、月額3500円とかなりリーズナブルなので変えてよかったです。

iDeCoを始める

申し込みはしましたが、まだ始まってはいません。提出書類に勤務先に書いてもらう必要がある書類があったので、驚きました。幸い、自分はその時社内勤務だったからよかったけど、うちの会社は客先で勤務している人が多いので、申し込みしたかったらどうするんだろうと思いました。ちなみに、提出書類は結構多いです。一度提出したものの、記入していない必要箇所があって返送されました(勤務先に書いてもらわなければならないところも未記入箇所があったので、再度お願いする羽目に)。申込書類を提出する際はちゃんと確認するようにしてください。

ケチケチしない

すごい、曖昧な目標ですが、2018年はそれなりに金をつかったほうだと思います。アマゾンプライムデーとか本当いろいろ買いすぎて、買った後に無駄買いしてしまったと思うものもあったり。後、例年よりちょっと株を買いすぎて結果、損してます。

そうそう。お金をつかったといえば、ゼクシィ縁結びカウンターに加入していたため、女性とごはんに行ったときはお金をつかいました。今までそんな経験なかったので、お金は使ったけどいい経験にはなったかなと思います。ただ、何人かの女性と付き合ったものの、3回デートしたのに振られたりして、さすがに疲れてきたのでやめました。今後どうするかは分かりませんが、しばらく婚活はしないと思いますし、一生独身でも別にいいかなと思っています。

できるだけ現金を使わない

2018年は本当、キャッシュレスが大きく取り上げられましたね。現金以外が使えるところはその決算方法を使うようにしました。ただ、近所に2店舗あるスーパーはどちらも現金しか使えないんですよね。早く、キャッシュレス対応してもらえないだろうか。

こうやって見ると、ある程度、やりたいと思ったことができてますね。自分にしては珍しく有言実行です(そんな大げさにいうほど、大したこと書いてませんが)。

その他

自分の中で2018年に一番大きかったのは、上にも書いた通り婚活をしたことかなと思います。思ったよりはうまくいったとは思うのですが、ベストではなかったですね。そうそう、うまくはいかないです。

後は、6月13日(水)にぎっくり腰になりましたが、それも自分の中では2018年に起きたことの中でも印象深いできごとです。ジムでレッグプレスを、ちょっと足のバランスが悪いままやっちゃいまして……。やったすぐ後は、「いてててて」程度だったのですが、だんだん痛みがひどくなってきて、ジムを終えて駅にむかっている最中に、「これはやばい……」と思いました。家に帰ってからは座ることすら怖くて、うまくご飯を食べれませんでした。寝るときも、どうやって寝ころんだらいいんだと思いながら、思い切って強烈な痛みを一瞬感じて寝ころびました。もうあんな経験はしたくありません。

しかも、ぎっくり腰になった二日後が健康診断で、休んだら自費で受けに行く必要があるため、がんばって会社にむかいました。週末になるとまだだいぶ痛みは残っていますがだいぶマシにはなり、月曜日は通常通り出勤しようと思いました。思いましたが、大阪北部地震で電車が止まり、二時間電車の中で閉じ込められました(幸い、一つ前の駅で目の前に座っていた人が降りてくれたので、座ることができたのはよかったです)。

2018年はそれ以外にも災害が多い年でしたが、うちの会社も、地震の日も含めて3回ぐらい、自宅待機の日があったような。本当、災難な年でした。

そういえば、このブログは一応、技術ブログでした。技術的なことでいえば、UiPathを知れたことは大きいと思いますが、それ以外はとくに何もないです。

2019年はどんな年になるでしょうか。新元号元年。いい年になるといいですね。

UiPathのカスタム入力アクティビティでデータの入出力

Facebook にシェア
Pocket

前回のUiPathの入力ダイアログで初期値をいれたり複数選択するようにする方法 | while(isプログラマ)の続き(余談ですが、WordPress5.0.1にアップデートしたらエディタがかなり変更になったので、Classic Editorというプラグインをインストールして元の形式に戻しました)。

前回、入力ダイアログアクティビティについて説明しましたが、このアクティビティは簡単には使えるものの、制約も多く、汎用的に使いたいと思ってもできないことがあります。

そこで使ってほしいのが、『カスタム入力アクティビティ』。どういうものかというと、HTML形式のフォームを作って、それを入力ダイアログ代わりに使うというものです(参考:2018.3リリース新機能のご案内 – 日本 / お知らせ – UiPath Community ForumUiPath Developer Community 第7回ワークショップ 覚え書き「カスタム入力アクティビティ」 – Qiita)。v2018.3と結構最近に実装された機能のため、ググってもこのアクティビティについて書かれてあるサイトがあまりないため、この機能を知ったときは結構衝撃的でした。

とりあえず、今回は前回までに入力ダイアログで実装した部分をすべてこのHTMLに置き換えていきたいと思います。まずはフォームとなるHTMLを作成していきます。下記のようなHTMLをロボットファイルのプロジェクトフォルダに「form」というフォルダを作成し、その中に「form.html」という名前で作成することにします。

ここで一つ気を付けたほしいのが、5行目にあるように「」という記述をいれること(公式のサンプルでは「」ですが)。このカスタム入力アクティビティのレンダリングはIEを利用しているのですが、この記述がないとどうやらIE7モードで動いてしまうようです。

そして、このソースの一番の肝は56行目の「window.external.setResult(url.value + ‘,’ + sortVal + ‘,’ + (pageNum.value – 0));」の部分。このsetResultという関数を使うことで、UiPath側に文字列として値を渡すことができます。公式ではJSONで記述しているみたいなんですが、今回は簡単にCSVで記述して返すことにします。

また、今回のHTMLでは並び順のデフォルトに「すべて」を指定し、取得数は数値入力としてデフォルトを100としました。こういうことは入力ダイアログではできないことですね。

つづいて、UiPath側は前回ダイアログを使っていた箇所をすべて削除し、カスタム入力に置き換えます。今回の場合だと、URLに”form/form.html”、結果にretValという文字列変数を指定します。このretValはCSV形式なので、retValArrというString型の配列にSplit関数を使って渡し、前回urlやsortPropやpageNumとしていたところをretValArrの値に置き換えます。

実行すると下記のような画面が表示されます。

無駄にサイズが大きいですね。JavaScriptのresizeToメソッドでサイズを変更できるかと思いきや、できませんでした。ググってみるとフォーラムでどうやったらサイズを変更できるのか質問している人がいて、運営っぽい人が「バグっぽいので調べて対応します」と書いてあると思われるページを見つけました(New Custom Input activity – RPA Dev Advanced / Bug Reports – UiPath Community Forum)。早く、指定のサイズで開くようにできるようになってほしいです。

話は戻って、先ほどのOKボタンを押すと、うまく動きます。ただし、右上の×ボタンで閉じるとretValには空文字””が入るため、途中でエラーとなって落ちます。どうしようかなと思ったのですが、自分が関わった業務では、retValが空文字の場合、下記のように繰り返し(後判定)アクティビティを使って、retValが空文字の場合は再度開くようにしました(もちろん、場合によっては×ボタンを押せば即プログラムを終了するようにしたり、何もしないでエラーを発生させるというほうがいいこともあると思います)。

つづいて、カスタム入力に値を渡してみたいと思います。ウェブページなので、GETパラメータにしたらいいかな? と思ったのですが、URIに「?」が含まれているとエラーが発生しました。

仕方がないので、ハッシュ(アンカー)を利用することに。URIの後に#を書いて、その後にCSV形式で値をセットします。

HTMLファイルは下記のように変更。

フォームのデフォルト指定をなくし、JavaScriptのロード時のイベントでハッシュを取得してそれぞれをデフォルト値としてセットしています。

動かすと確かに、渡した値がセットされました。

値を渡す方法としては微妙かもしれないですが、多分一番簡単な値の渡し方だと思います。渡すデータ量が多くなるようだと、一時ファイルを作ってそこから呼び出すようにしたほうがいいかもしれないです。

これができるなら、UiPathで(HTMLを使った)GUIアプリケーションなんてものも作れそうですね。

UiPathの入力ダイアログで初期値をいれたり複数選択するようにする方法

Facebook にシェア
Pocket

前回のUiPathで「名前を付けて保存」ダイアログを表示する | while(isプログラマ)のつづき。

いつも最初のURLの入力に「am-yu.net」と入力するのが何気に面倒なので、初期値で「am-yu.net」といれることにします。ついでに、並び順や取得数の変更もできるように変更します。

まず、URLのデフォルト値を入れる変数を作成します。この時、変数の型はString型ではなく、Stringの配列型を選んでください。

この変数は、既定値として「{“am-yu.net”}」と設定し、入力ダイアログのオプションに設定します。

そうすると、下記のような感じでデフォルトで「am-yu.net」と入るようになりました。

ちなみに、上記で設定した入力ダイアログのオプションですが、配列の中身を2つ~3つにするとラジオボタンの選択式になります。とりあえず今回は、並び順の変更をできるようにします。sortListというString型配列変数を設定して既定値として、「”人気”,”新着”,”すべて”}」とし、結果をsortKindという変数にいれます。

そうすると、下記のように入力ダイアログがラジオボタンの選択式となりました。ただ、デフォルトの選択はできないようで、何も選択せずにOKを押すと結果にはnullが入ります(既定値のままではないようです)。

ちなみに、配列の中身が4つ以上だとプルダウンリストとなります。とりあえず今回は取得する数を変更できるようにします。pageNumListというString型配列を作成して既定値を「{“10″,”50″,”100″,”200”}」に、結果をpageNumという変数にいれます。数値型の配列でもいけるかなと思って試したのですが、String型じゃないとダメでした。

そうすると、下記のようにプルダウンリストの選択式となりました。ただ、やっぱりこれもデフォルト値は選べず。

後は他に必要なことを実装していきます。とりあえず、並び順は日本語名ではなく、URLに指定するプロパティ値として取得したいので、スイッチアクティビティでダイアログで選択した並び順によって、プロパティ値を設定するようにします。まず、スイッチアクティビティのTypeArgumentをStringに変更し、式に「sortKind.ToString」と設定します。その後、今回は、sortPropという変数を作成し、”人気”なら「sortProp = “count”」、”新着”なら「sortProp = “”」、”すべて”かDefaultの場合は「sortProp = “eid”」としました(どうでもいいけど、なぜかCaseの中に代入アクティビティを入れると、表示名が「代入」ではなく、英語の「Assign」となった)

もちろん、開くURLの設定も、「”http://b.hatena.ne.jp/entrylist?url=” & url.ToString() & “&sort=” & sortProp」と変更します。

つづいて、構造化データを抽出用のアクティビティの結果の最大数に「CInt(pageNum)」と設定します。CIntというのは、引数の値を整数型に変換して返す関数です。

これで、うまくいくはずです。実行して並び順に「人気」を選択し、取得数に「10」を選択します。

ただ、ここで問題が。動きはしたのですが、「人気」を選択したのになぜか「すべて」のページで実行されました。

今回作成したプログラムにはバグがあります。スイッチアクティビティのCaseの文字列にはなんと、ダブルクォーテーションをつけてはいけません。最初にスイッチアクティビティを使った時にここで悩みました。なので、sortList(0)というような変数も使えません(変数名がCaseの文字列だと思われる)。この仕様は非常に分かりづらかったです。マニュアルにも書いてないし……(参考:Switch)。

というわけで先ほどと同じように実行すると、今度は無事、人気の並び順でスクレイピングしてくれました。

結果も10件のみとなっています。

ただ、やっぱり入力ダイアログの複数選択時は既定値設定がほしいです。後、複数回ダイアログを出さなきゃいけないのも微妙かもしれません。そんな時に役立つのが「カスタム入力」というアクティビティですが、この話は次回します。このアクティビティを知ったときは結構衝撃的でした。

UiPathで「名前を付けて保存」ダイアログを表示する

Facebook にシェア
Pocket

前回のUiPathではてブのスクレイピング | while(isプログラマ)で作ったプログラムですが、URLを指定できるのはいいものの、保存先が”hatebu.csv”と固定になっているため、保存用のダイアログを表示して保存先を指定するようにしたいと思います。

ですが! UiPathには「ファイルを選択(File Select)」というアクティビティはあるのですが保存用ダイアログのアクティビティがありません。「ファイルを選択」アクティビティだとボタンの名称が『開く』となっているので、保存用のダイアログとして使うには違和感があります。

そこで、今回はVB.NETにあるSaveFileDialogという保存用のダイアログを呼び出す方法を紹介します。

まずは、保存用ダイアログ用の変数を追加します。ここでは、saveDlgとしました。

saveDlgの型はSystem.Windows.Forms.SaveFileDialogです。「savefiledialog」でフィルターをかけるとでてくると思います。選択してOKボタンを押してください。

そうすると、インポートした名前空間に、「System.Windows.Forms」が追加されます。この時、!マークが表示されますがあまり気にしなくていいです。気になるようでしたら一度、保存してUiPath Studioを落とし、再度起動しなおすとこの!マークは消えます。

saveDlgの既定値に「New System.Windows.Forms.SaveFileDialog()」と指定します。

つづいて、saveDlgの設定をしていきます。デフォルトのファイル名(FileName)に”hatebu.csv”、フィルターに”CSVファイル(*.csv)|*.csv|すべてのファイル(*.*)|*.*”と指定します。他にどのようなプロパティがあるかは、SaveFileDialog Class (System.Windows.Forms) | Microsoft Docsを参照してください。

次に、最初に表示されるデフォルトパスを、現在実行しているフォルダパスを指定することにします。これは、「環境変数を取得(GetEnvironmentVariable)」アクティビティを利用して”CurrentDirectory”を指定します。出力には直接、「saveDlg.InitialDirectory」を指定しました。このアクティビティで他にどのような値が取得できるかは、Environment Class (System) | Microsoft Docsを参照してください。

保存ファイル選択ダイアログ自体は「saveDlg.ShowDialog()」で開きます。このメソッドの返り値はDialogResultというEnum型になっているので、ちゃんとファイルが選択されたかどうか判別したうえで、CSVに書き込むことにします。

これで実行すればうまくいくはず……。と思ったのですが、保存用のダイアログが表示されると思ったタイミングでなかなか表示されません。かといってタイムアウトエラーになりません。おかしいなぁ、と思いながらもしかしてと思ってIEのウィンドウを動かすと、後ろにありました。

困ったことに、UiPathではダイアログが最前面に表示されないことがよくあるんですよね。そもそも、最初に表示されるURL指定用のダイアログだって最前面に表示されるものの、アクティブにならないことがあるので、文字を入力しようとキーを押しても入力できません(わざわざマウスでダイアログを選択して入力しないといけない)。調べてみると、デスクトップをアクティブにしてからダイアログを表示させたらいいらしいので、「アクティベート」アクティビティを一番上に追加して、デスクトップを選択します。選択した後にセレクターを確認すると二行になっていると思いますが、うまくいかないことがありそうなので、一行だけにしておきました。

さて、これで実行すると、最初に表示されるURL入力ダイアログがアクティブになり、わざわざダイアログを選択せずとも文字を入力することができました。これでうまくいくはず……。と思ったのですが、保存用のダイアログはあいかわらず、バックに表示されてしまいます。ダイアログ表示の直前にデスクトップをアクティブにするアクティベートアクティビティを追加しても変わらず。仕方がないので、ダイアログを表示する前に「Win + M」キーを押下して、表示されているウィンドウをすべて最小化する処理をいれてダイアログを表示することにします。

まあ、よくよく考えたらこの時点でIEは必要ないのだから、「タブを閉じる」アクティビティを使ってIEを閉じてからダイアログを開いたほうがいいかもしれないです。

ちなみに、Input dialogを前面に出したい – 日本 / フォーラム – UiPath Community Forumによると、「文字を入力(TypeInto)」アクティビティで”k(ctrl)”としたらいいと書いてあり、確かにこれでダイアログが最前面に表示されたのですが、自分の環境ではこのタイミングでエラーが発生したような「チャラン」という音が鳴りました。

話は戻って、これで無事に保存用のダイアログが表示されました。

「hatebu-amyu.csv」という名前で保存すると、確かにその名前で保存できました。

なんだか回りくどい書き方になりましたが、これで無事にファイルを保存先を指定することができました。UiPathはVB.NETをもとにしているので、このようにデフォルトで無い機能(アクティビティ)は自分で追加することもできます。

ちなみに、最初に「ファイルを選択(File Select)」アクティビティならUiPathにあると書きましたが、このアクティビティは最新のv2018.4のバージョンではデフォルトのフォルダパスを指定することができません。デフォルトのフォルダパスを指定したい場合は、今回試したように、OpenFileDialogを使うようにするとデフォルトのフォルダを指定することができます。それぐらい、指定できるようになってほしいものです。

UiPathではてブのスクレイピング

Facebook にシェア
Pocket

今月から業務でUiPathを使うようになりました。使ってみると本当、簡単にプログラムを作成できて、もうプログラミングはいらなくなるんじゃないかとさえ思いそうです(注:そんなことはない)。

というわけで、今回はUiPathで簡単にできる、ウェブスクレイピングの機能を紹介。とりあえず、指定のURL(というよりドメイン)内を含むページのすべてのエントリーページを取得したいと思います。UiPathのウェブ操作はIE以外にFirefoxやChromeにも対応していますが、今回は標準で使えるIEで試してみます(FirefoxやChromeは拡張機能を入れる必要がある)。

まず最初に、IEではてブの指定のURLのすべてのページを開いておきます。例えばここのブログだと、http://b.hatena.ne.jp/entrylist?url=http%3A%2F%2Fam-yu.net%2F&sort=eidです。

次に、UiPathでプロセスを開始して、リボン上の『データスクレピング』をクリック。

そうすると、下記のような画面が表示されるので、『次へ』をクリック。

すると、取得したい要素を選択することになるので、取得したい要素を選択します。ここでは、ブクマされているページのタイトルを選択します。

選択すると、下記の画面が表示されます。これは、上記で選択した要素と、同じ種類の要素を選択します。そうすることで、どの要素を取得すればいいかUiPathが自動で判断してくれます。

とりあえずここでは、3つ目のタイトル要素を選択することにします。

そうすると、『カラムを設定』という画面が表示されるので、テキストカラム名と(指定した要素がリンクであれば)URLカラム名を入力します。とりあえずそのまんまですが、『Title』と『URL』と入力し、『次へ』をクリックします。

すると、データプレビュー画面が表示されます。こんな感じで取得することになるようです。うまく取得できていそうですね。結果件数の最大値はデフォルトで100と入っていますが、もっと大きくすることもできます(あまり大きくしたり、0とすると最悪、時間がかなりかかってパソコンにもはてブのサーバーにも負荷がかかりそうなのでやめておいたほうがいいです)。とりあえず、100のままにしておきます。ここで終わってもいいのですが、次に『相関するデータを抽出』をクリックします。

先ほどと同じく要素選択画面となるので、ブクマ数の要素を選択します。

つづいて、タイトルを選択したときと同じように、別のブクマ数の要素を選択します。

テキストカラム名『Users』としておきます。今回URLはいらないので、チェックは外しておきます。

『データプレビュー』は下記のようになりました。ブクマ数もうまく取得できているようです(と言いたいところですが、選択したのはブクマ数の数値部分だけなはずなんですよね。なんで「users」まで取得対象になってしまうのかと……)。とりあえず、「終了」ボタンをクリックします。

そうすると、「データは複数ページにわたりますか?」というダイアログが表示されます。複数ページにまたがるので、「はい」をクリックします。

つづいて、次のページへ遷移するリンク要素をクリックします。この時、マウスのホイールが使えないのですが、キーボードのPage Downキーや矢印キーを使ってページを下まで移動し、「次のページ」の要素を選択します。

そうすると、UiPath Studioの画面にもどり、データスクレイピングというシーケンスアクティビティや構造化データを抽出用のアクティビティがセットされます。この構造化データを抽出用のアクティビティは出力として、.NetプログラミングではおなじみのDataTableという表形式の型の変数に入ることになります。デフォルトでは「ExtractDataTable」という名前の変数に格納されます。

上記で作成したデータテーブルをCSVファイルに保存することにします。CSVに書き込むアクティビティを構造化データを抽出アクティビティの下に置き、ファイル名とデータテーブル変数を入力します。

ついでに、ブクマ数を取得するURLは最初に指定できるようにします。入力ダイアログアクティビティを一番上に追加します。出力にはurlという変数を設定することにします。出力結果にカーソルを置き、Ctrl+Kを押すと、自動的に入力して変数が作成されます。

上記で指定したURL用のはてぶページを開くために、ブラウザーを開くアクティビティをセットして、URLを「”http://b.hatena.ne.jp/entrylist?url=” & url & “&sort=eid”」とします(余談ですが、UiPathのマニュアルでは文字列結合に+を使っていることが多いのですが、個人的にはVBの文字列結合は&を使いたい派なので&としています)。処理はこの中のDo(シーケンスアクティビティ)内で行うほうがいいので、先ほど自動的に作成されたブラウザーにアタッチというアクティビティ内のアクティビティをドラッグアンドドロップで移動します。Ctrlキーを押しながら複数のアクティビティを選択することで、複数選択できます(順番がおかしくない? と突っ込まれそうですが、自分も思いました。スクリーンキャプチャを取り直すのが面倒なのでそのままにしています)。

これで完成! と言いたいところなのですが、どうやら青いひし形マークがついています。これがあるということは何かしら失敗しているということです。マウスをあててメッセージを表示してみると、「演算子’&’は型’String’および’UiPath.Core.GenericValue’に対して定義されていません。」とあります。どうやら、先ほど自動的に作成したurlという変数の型は「UiPath.Core.GenericValue」という型になっているようです。この型はジェネリック型変数といって、どんな型もとりうる型となっています(参考:ジェネリック型変数)。なので、変数の型を「String」に変えるとエラーメッセージはなくなります(他に、ブラウザーを開くURLを「”http://b.hatena.ne.jp/entrylist?url=” & url.ToString() & “&sort=eid”」としてもOKです)。

実際にできた、ワークフローは下記のようになりました。

この状態で、実行ボタンを押すとちゃんと動きました。

実行するとIEではてブの新着エントリーページが開き、勝手にページが遷移します(ただ、「am-yu.net」で試すと、最後の3ページ目でしばらく止まりました。どうやら、件数が100件未満しかないので、次のページにいきたいのにそのリンク要素がないのでタイムアウトエラーになるまで止まっていたっぽいです)。

処理が終了して、フォルダを確認すると、確かにCSVが作成されていました。

中を見てみると、うまく取得できたようです。

ついでに、Yahoo!ニュースのヘッドラインページで試してみても、うまくいくことを確認しました。

ということで、UiPathだと簡単にウェブスクレイピングを実現できます(取得対象がどういう構造になっているかによりますが)。今後は簡単なウェブスクレイピングについては、UiPathでやってみようと思います。