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でやってみようと思います。

UiPathでFizzBuzz問題やってみた

Facebook にシェア
Pocket

昨今、あちらこちらで名前をよく聞く「RPA」。「ようは自動化でしょ。大きいマクロみたなもので。プログラマからすればプログラミングで解決できるんだから、あまり関係ないか」。なんて思っていたのですが、来月からRPAツールの『UiPath』の業務に携わることになりました(自分ひとりだけなんですが……)。

ただ、使ってみるとこれが結構面白い。プログラミングと関係ないと思ってたけど、結構プログラミングの概念も必要となってくるし、プログラミングで組むよりも圧倒的に自動化しやすいこともある(例えば、ウェブスクレイピングについてもだいぶ簡単にできる。面白かったのが、画像判定で次の処理にいく機能で、これでページロードに適当な時間を指定して待つ必要がなくなるという)。

というわけで、今回はそんなUiPathについて軽く紹介。UiPathを紹介している記事なんてあちこちにあるので今更なんですが、今公開されている記事は、公式サイトも含めて英語の画面で紹介していることがあるので、この記事では最近でた日本語版で説明します。

まずは、UiPath Community Edition – Request your free downloadにアクセスして無料版をダウンロードしてください。最初に開いたときは下記のようなクッキーポリシーに同意するメッセージが表示されると思いますが、『同意する』を選択して、姓と名とEメールを入力して『COMMUNITYエディションのダウンロード』ボタンをクリックしてください。

ちなみに、『Cookieポリシー』のリンクをクリックすると、そこでもクッキーポリシーのメッセージが表示されて、フィルターがかかってしまうという。

話は戻って、ダウンロードボタンをクリックしたら、下記の画面になります。メールでも案内の連絡が届きますが、『こちらから』のリンククリックでもダウンロードできます。

そうすろと、『UiPathStudioSetup.exe』という実行ファイルがダウンロードされると思うので、それを実行すると、下記のような画面となります。

『Community Editionのアクティベーション』を選択し、次の画面でメールアドレスを入力し、『アクティベーション』をクリックします。

そうすると、UiPathのスタート画面が表示されたと思います。なお、次に実行する時はスタートメニューに『UiPath Studio』があると思うので、そこから起動するようにしてください。『UiPathStudioSetup.exe』を実行しても起動できるのですが、毎回アクティベーションの確認がでてしまいます。

では、『プロセス』ボタンを押してプロジェクトを作成します。今回はFizzBuzz問題を作成しようと思うので、『fizzbuzz』というプロジェクト名にしました。そうすると下記のような画面になります(左側のパネルがアクティビティになっていない場合は、左下のアクティビティタブを選択してください)。

見てわかる通り、現在ダウンロードすると日本語になっています。左にあるのがアクティビティとよばれる、UiPathのプロジェクトを構成する、何をするかをあらわした部品のようなものですが、『プロジェクトを検索』のテキストボックスでアクティビティを検索することができます。現在でている記事や公式サイトのマニュアルではこれが英語となっていて、その英語にあたるアクティビティは日本語でどれなんだと最初分からなかったのですが、英語で入力してもだいたいでてきます。下記は『assign』と入力して、『代入』アクティビティがでてきた画像です(よく分からないですが、でてこないのもある)。

まずは、フローチャートというアクティビティをメインパネルに置きます。名前のとおり、UiPathはフローチャートを書く要領で実装していきます。

FizzBuzzを実装する前に、変数の作成をします。画面下にある『変数』という箇所を選択して、変数パネルを表示します。名前に変数名、変数の型に変数の型(VB.NETと同じです)、スコープにどの範囲に適用するか、規定値にデフォルトの値を入力します。

つづいて、フロー条件分岐というアクティビティを置き、その条件を、「num Mod 3 = 0」とします。これは、numの値が3で割ると0余る(割り切れる)かという条件となります。構文は、VB.NETと同じです。

続いて、代入アクティビティを置き、上記の条件が成立した場合にfizzbuzzを”Fizz”とするようにします。気を付けてほしいのは、文字列を書くときは、ダブルクォーテーションで囲む必要があります。ここらへんはプログラミングと同じですね。

そういう要領でフローチャートを作成していくと、下記のようなものができました(さっきは、最初にfizzbuzzを””とする処理なんてなかったよね? なんて突っ込みはやめてください)。

サンプル:UiPathのFizzBuzz

中に入っているfizzbuzz.xamlをUiPathのスタート画面の『開く』から選択すると、上記のような画面になると思います(ファイルを選択するときは、『ワークフロープロジェクトファイル』から『ワークフローファイル』に切り替えてください)。

このプロジェクトを実行するには、左上の再生ボタンをクリックします(再生マークのボタンが二つあると思いますが、どちらも同じ動きです)。そうすると、出力パネルに1~100までのFizzBuzzの結果が表示されました。

出力パネルが表示されていない場合は、『出力』というタブボタンがどこかにあると思うでクリックして表示してください。パネルは自由に移動できますが、自分は画面の右下に配置しています。

だいぶ最後のほう省略しましたが、UiPathで簡単にFizzBuzz問題を実装できました。プログラミング的な概念もありますが、簡単に実装できるので、プログラミングを学び始めた初心者にとってもいいのではないかと思いました。ただ、FizzBuzz問題程度だとプログラミングでいいじゃんとなるので、もっとUiPathならではのことができないかそのうち紹介したいと思います。

【MySQL】DECIMAL型の小数点以下の末尾の0を取り除く方法

Facebook にシェア
Pocket

データベースにMySQLを使っているシステムにおいて、MySQLから数値を文字列として取得してそのまま表示したいということがあったのだけれども、DECIMAL型だとなんと小数点以下の末尾の0がそのまま表示されてしまうことが発覚。

(decimal_timeがDECIMAL(10,3)型で、double_timeがDOUBLE型)

DOUBLE型なら省略してくれるんですけどね。それならと思って、DOUBLE型にキャストしてみようと思ったのですが、MySQLではDOUBLE型へのキャストはできないようです(参考:MySQL :: MySQL 5.6 リファレンスマニュアル :: 12.10 キャスト関数と演算子)。「CAST(decimal_time AS DOUBLE)」というようにキャストしてみようとすると、下記のようなエラーメッセージが表示されました。

いろいろ考えた末、ちょっと長くなるけど、下記のように小数点以下が何桁まであるか調べて、その分の桁数で切り下げすることに。

結果:

DECIMALの小数点以下の桁数の数をどう設定しているかによって変わってくるんですけどね。これが、DECIMAL(10,4)とかだったら、「WHEN MOD(decimal_time, 0.001) = 0 THEN TRUNCATE(decimal_time, 3)」という条件を追加すればいいです。

なお、先ほどDOUBLE型にはキャストできないと書きましたが、調べてみると関数を作成することで、DOUBLE型に変換することができるそうです。
参考:casting – Is it possible to cast a DECIMAL to DOUBLE in MySQL? – Stack Overflow

下記のような関数を作成し、

実際に下記のSQLを実行すると、先ほどと同じ結果となりました。

関数を利用できるなら、こちらのほうが便利かもしれないです。

サブクエリのサブクエリにメインクエリの値は使えない?

Facebook にシェア
Pocket

先日、業務でSQLを実装してみて、「あれ? これできないの?」と思ったことがるので書きます。試した環境はMySQL8(他のDBMSでは動作が異なるかもしれない)。

うまく動かなかったのは、サブクエリのサブクエリにメインクエリの値を使おうとしたとき。例えば下記のようにmember(会員)テーブルとscore(点数)テーブルがあるとする。

ここから、memberテーブルのname(名前)と、その名前に対応するscoreテーブルの最新のscore(点数)を取り出したいとして、下記のように書きました。

ようは、memberテーブルのmember_idで絞り込んだscoreテーブルのうち、date(日付)でソートしたときの順序を取得して順序が1つ目の値をとってきています(JOINしろといわれそうですが、実際に作成したのはIFNULLの第二引数で取得するようにしていて、ほとんどの行でこの結果を取得することはないので、サブクエリとしました)。

しかし、これを実行すると下記のようなエラーが発生します。

つまり、’member.member_id’なんてフィールドはないということだと思います。

もちろん、下記のようにサブクエリで指定するようにすると取得できます(違いとしては、上記がサブクエリのサブクエリでIDを絞り込もうとしていたのにたし、下記ではサブクエリでIDを絞り込もうとしている)。

結果:

多分、サブクエリのサブクエリにはメインクエリの値は利用できないのだろうと思ったのだけど、調べてみても根拠となるソースが見つからなかった。何でこういうふうになっているんだろう? 内部ロジックが複雑になるからか?