《ロストフラグ》絶望の火の遺跡実装、早くも人手不足必至か

先月風の遺跡が実装されたばかりだと言うのに、今月もう次の遺跡が実装されるとの告知あり。

もう絶望感しかありません。(汗)

水の遺跡から主力を剥がすときですら困り果てたというのに、まだ大半の二つ名がゲットできていない風の遺跡からも、この上さらに主力を撤退させろと。

過去の実績から、恐らく紅白奉納試合の月は恐らくガチャが大して回ってなかったからなんだろうが、さすがにペースが速すぎです。

いくら常設コンテンツだからって、ユーザー心理からしたら急いで攻略したくなっちゃうじゃないか。(苦笑)

こうしちゃいられん。
のんびりやろうと思っていた風の遺跡を今のうちに1つでも進めておかねば。

ということで、先ほどLv33をクリア。(Lv34はまだ歯が立ちません)
風の遺跡Lv33結果

次の遺跡用にまたしてもハク・ハクオロをここから剥がし、さらにもしかすると水スズリすらも必要になるかもしれないと考えると、本当に頭が痛い。。。
(自前リンネを水の遺跡から持ってくるしかないか・・・?)


そして、火の遺跡用に戦力アップを狙った今月の英傑ガチャ。

特攻鏡を2枚引けたものの、残念ながらキャラはゼロ。(泣)

つーか、特攻鏡の特性2の説明が当初「連撃弐段発動時」になってたからちょっと奮発して50連の鏡天井まで回したのに、しれっと「連撃参段発動時」に訂正されてやがる。

ざっけんなよ、糞アクアプラス!!

最初から参段発動時の記載だったら、30連目で撤退してたわ。(10連目で1枚引けてた)
20連分の宝珠返せよ、ったく。

ガチャ回させるための故意の誤植ではないと信じたい。
(故意だとさすがに詐欺行為だからな)

ま、アトゥイは闇鍋でまたチャレンジするとして。。。(10連ぐらいしか回せんけど)
仮に引けなかった場合のことも考えておかねばなるまい。

手持ちの土属性アタッカーで使えそうなのは、契約15クオンとマホミぐらいか。
120秒間であればクオンの方が強力だが、いかんせん連撃対象が全て敵単体のみ。
マホミはスロースターターな上に通常攻撃も1発のみで、範囲連撃も弐段しかない。

あとは、今月上限解放されるゲンジマルか・・・
土属性におけるヤクトワルトのような強化内容だが、コイツも連撃範囲はクソ。

はぁ。。。年末の選託祭でトゥスクルが引けなかったことが悔やまれる。

せめて水・風の遺跡用に、男装ムネチカ・アースラ・メムルの誰かが来てくれればいいんだが、果たして。。。
(ジュウニ以降、恒常キャラだから別にいいかと思ってたらその後も全然引けやしねぇ)

あとはサナチタを覚醒5に強化して、代わりに自前リンネを移動させるかね。

還元率の高いポイントサイトで、ハイペースでポイントが貯まります ポイントサイトのポイントインカム

Edge IEモードをVBAから操作するためのソースコード

半年ほど前に、「Edge IEモードをVBAから自動操作できた!」という記事をUPしましたが、これを閲覧された方からソースコードを教えてほしいとのご要望がありました。

なので、今回は私が作ったソースコードを公開したいと思います。
と言いつつ、私自身もネットを探し回ってソースコードをかき集めてきたクチなので、コードに統一性が無いのはご容赦ください。
トレパクしたコードを一部流用させて頂いた部分も結構あります。


Option Explicit


Private Declare Function EnumChildWindows Lib "user32" (ByVal hwndParent As Long, ByVal lpEnumFunc As Long, lParam As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As Long, ByVal wFlag As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetTopWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function IIDFromString Lib "ole32" (lpsz As Any, lpiid As Any) As Long
Private Declare Function ObjectFromLresult Lib "oleacc" (ByVal lResult As Long, riid As Any, ByVal wParam As Long, ppvObject As Object) As Long
Private Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" (ByVal lpString As String) As Long
Private Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" (ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal fuFlags As Long, ByVal uTimeout As Long, lpdwResult As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long

Private Const GW_HWNDNEXT = &H2
Dim m_WinNum As Integer 'ウィンドウハンドル要素数
Dim hWnds() As Long 'ウィンドウハンドル配列
Private hIES As Long


'Edgeオブジェクト取得
Public Function GetEdgeObject(ByVal title As String)

Dim hwnd As Long

hIES = 0 '初期化

hwnd = displayForeground(title) '指定したタイトルのウィンドウハンドルを取得

'IEモードのウィンドウハンドルを探索(Edgeの子ハンドルとして存在しているため)
Do
If GetParent(hwnd) = 0 Then
'Edgeの子ウィンドウ列挙
EnumChildWindows hwnd, AddressOf EnumChildProcIES, 0
If hIES <> 0 Then Exit Do
End If
hwnd = GetNextWindow(hwnd, GW_HWNDNEXT)
Loop While hwnd <> 0

If hIES = 0 Then
Set GetEdgeObject = Nothing
Exit Function
End If

Set GetEdgeObject = GetHTMLDocumentFromIES(hIES)

End Function


'Internet Explorer_Serverクラス(= IEモード)のウィンドウハンドルを取得
Private Function EnumChildProcIES(ByVal hwnd As Long, ByVal lParam As Long) As Long

Dim buf As String * 255
Dim ClassName As String

GetClassName hwnd, buf, Len(buf)
ClassName = Left(buf, InStr(buf, vbNullChar) - 1)
If ClassName = "Internet Explorer_Server" Then
hIES = hwnd
EnumChildProcIES = False
Exit Function
End If
EnumChildProcIES = True

End Function


'Internet Explorer_Serverクラスのウィンドウハンドルから、HTMLDocumentオブジェクトに変換する
Private Function GetHTMLDocumentFromIES(ByVal hwnd As Long) As Object

Dim msg As Long, res As Long
Dim iid(0 To 3) As Long
Dim ret As Object, obj As Object
Const SMTO_ABORTIFHUNG = &H2
Const IID_IHTMLDocument2 = "{332C4425-26CB-11D0-B483-00C04FD90119}"

Set ret = Nothing '初期化
msg = RegisterWindowMessage("WM_HTML_GETOBJECT")
SendMessageTimeout hwnd, msg, 0, 0, SMTO_ABORTIFHUNG, 1000, res

If res Then
IIDFromString StrPtr(IID_IHTMLDocument2), iid(0)
If ObjectFromLresult(res, iid(0), 0, obj) = 0 Then Set ret = obj
End If

Set GetHTMLDocumentFromIES = ret

End Function


'可視の全ウィンドウハンドルを取得
Function EnumWinProc(ByVal hWndX As Long, ByVal lParam As Long) As Boolean

If IsWindowVisible(hWndX) Then
m_WinNum = m_WinNum + 1
ReDim Preserve hWnds(0 To m_WinNum)
hWnds(m_WinNum) = hWndX
End If

EnumWinProc = True

End Function


'ウィンドウ名取得
Function GetWinText(hWndTarget As Long) As String
Dim l As Long
Dim s As String
Dim dum As Boolean

l = GetWindowTextLength(hWndTarget) + 1
s = String(l, 0)
dum = GetWindowText(hWndTarget, s, l)
GetWinText = s
End Function


'指定画面のウィンドウハンドル取得&最前面に表示
Function displayForeground(ByVal title As String) As Long

Dim dumb As Boolean
Dim i As Integer
Dim windowName As String

ReDim hWnds(0)
m_WinNum = -1
Call EnumWindows(AddressOf EnumWinProc, 0&)

For i = 0 To UBound(hWnds)
windowName = GetWinText(hWnds(i))

If InStr(windowName, title) > 0 Then
'指定画面有り

SetForegroundWindow hWnds(i) '最前面に表示
displayForeground = hWnds(i)
Exit Function
End If
Next i

displayForeground = 0 '指定画面無し

End Function



以上のコードを標準モジュールあたりにそのまま貼り付けてください。

あとはメイン処理側で、
 Dim objIE As Object
 Set objIE = GetEdgeObject("hogehoge")
っていうコードを書くだけで、objIEにはHTMLDocumentオブジェクトが入ってきますので、その後は今まで通りのDOM操作が可能となります。

「hogehoge」の部分は、操作対象ウィンドウのタイトルを指定して下さい。
例えばこの記事のウィンドウを操作したい場合は、「36歳中小ベンダーSE」とか「Edge IEモードをVBAから操作する」などと指定します。
(タイトルに指定した文言を含むウィンドウのオブジェクトを取得します)

注意点は、以前の記事でも触れたように、
 objIE.document.getElementById("hoge").Focus
というふうに書いていたところを、
 objIE.getElementById("hoge").Focus
というように書き換える必要があること。
(objIEの時点でdocumentまで含んでいるため)

さらに、画面表示完了を待機する際に使っていた
 objIE.Busy
が使えなくなったこと。
objIE.ReadyStateは引き続き使えるので、ReadyStateが"complete"かどうかという点のみで、画面表示完了を待機することになります。
(= 残念ながら、若干安定性が低下)


ここまでが、Edge IEモードを操作する際の基本的なコードになります。
あとは対象システムの特性に応じて、色々と肉付けしていって下さい。

以上、ご参考までに。

それにしても、今回は超久々にエンジニアっぽい内容を書いたな。(笑)

還元率の高いポイントサイトで、ハイペースでポイントが貯まります ポイントサイトのポイントインカム

【悲報】RPAツール、今後少しずつ使い勝手が悪くなる見込み

ウチの会社ではVBAでのWebスクレイピングが主流なものの、一部業務に対してはWinActorも導入しています。

私も当然WinActorでシナリオを作成することもあるんですが、以前に比べるとだんだんと使い勝手が悪くなっている印象を受けます。
本来はバージョンアップを経て、使い勝手が良くなっていかなければいけないはずなんですが・・・

そう感じる大きな理由が2点。

1.Chrome及びChromium版Edgeでのシナリオ作成がしにくいこと

2.クラウドサービスのWebページで、自動操作を回避する仕組みが導入されてきていること


では、1点ずつ見ていきましょう。

1.Chrome及びChromium版Edgeでのシナリオ作成がしにくいこと

RPAツールが日本で流行していた頃は、まだIE11が主流でした。
IE11はVBAからでも操作しやすく、RPAツールでも自動記録がしやすかったんですが・・・

Chrome・Chromium版Edgeについては、ブラウザ操作については必ず新規ウィンドウの起動から始める必要があります。
そのためか、現在開いているウィンドウに対して自動記録を行うと、毎回必ず「ブラウザ起動」「対象ページへ移動」の2ステップが勝手に組み込まれ、これを毎回削除しなきゃいけないというめんどくさいことになってます。

確かに、自動操作したい内容を最初から最後まで一筆書きのように1回で自動記録する場合はそれでもいいんですが、私の場合は少しずつ動作確認しながらシナリオを作っていきたいんですよね。

また、自動記録した場合は対象要素のXPathも一緒に記録されるんですが、これが全て個々の変数としてシナリオに登録されていきます。
なので、変数一覧のウィンドウを見ると、XPath絡みの変数ばかりで埋め尽くされるという事態に。(汗)
基本的にXPathを使いまわすようなシナリオを作ることはないので、個々のXPath値を変数にする必要性は薄いと思うですけどねぇ。。。


2.クラウドサービスのWebページで、自動操作を回避する仕組みが導入されてきていること

Salesforceがその最たるものなんですが、恐らく意図的に外部プログラムによる自動操作をさせないような仕組みのクラウドサービスが増えてきている印象があります。

具体的には、ある要素の親要素のID属性値がページ表示の度に毎回変わるようになっているため、結果としてXPath値も毎回変わるようになっています。

ということは、自動記録でそのときのXPathを記録できたところで、実行時にはXPathが変わっているため、「要素が見つからない」というエラーになります。

Salesforceはサイト全体に対してこれがかなり徹底されているため、WinActorはおろかVBAですらも自動操作は困難なレベル。
かと言って、画像マッチングや座標指定が満載のシナリオで自動操作するなど愚の骨頂です。
なので、ウチの会社については、「Salesforceは自動操作できない」と業務部門には説明して、納得してもらってます。

で、Salesforce以外にも、こういったサイトをチラホラ見かけるように。

最近も、新しく導入しようとしているクラウドサービスのWebページを自動操作するためにWinActorでシナリオを作ってたんですが、何度記録し直しても、実行時には「要素が見つからない」エラーになって、結構な時間ハマりました。

仕方なく画像マッチングを使ったんですが、当然動作はイマイチ安定せず。

悩んだ挙句、WinActorで作ってたシナリオの9割を捨てて、主要な操作はVBAで作り直すことにしました。
(VBAならID要素での指定や、親要素から子要素に1つずつ辿っていく等、どうとでも実現しようがある)

結果、WinActorを使うのはシナリオの最初と最後だけで、メイン部分はマクロ実行で対処という本末転倒な状態に。(笑)


マジでRPAツールは使い物にならなくなりつつあるな。
(元々、IE11環境下での普及を想定して設計されたものなのかもね)


※今回の件とは違いますが、画像マッチングを使う度に、実行専用ライセンスの端末では画像が設定しなおせないという糞仕様が、本当にイラつきます。
  (例えば目が悪い社員なんかは、自分のPCの表示サイズを大きめに設定してたりしますから)

※さらに今回の件とは違いますが、標準ノードとして用意されている「クリップボードに値を設定する」というやつが、実行の度にエラーになったりならなかったりして、本当にイラつきます。
 (前後に3秒ずつ待機ステップを入れてみてもダメ。なんで画面操作が全く関係ないクリップボードの操作すらまともに動かないんだよ、クソツールが!)

還元率の高いポイントサイトで、ハイペースでポイントが貯まります ポイントサイトのポイントインカム
プロフィール

Author:たみおと
36歳にして社内SEに転職しました。
ベンダーSE・社内SEどちらの方が記事を読んでも、ご参考になる体験談をUPしていきたいと思っていますので、宜しくお願い致します。

検索フォーム
ブログランキング
よろしければ、ポチっと一押しお願いします。m(__)m

ブログランキング・にほんブログ村へ
カテゴリ
よく読まれている記事
最新記事
おすすめ書籍

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

なぜ、システム開発は必ずモメるのか?
価格:999円(税込、送料別) (2024/10/26時点)


[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

絵で見てわかる RPAの仕組み [ 西村 泰洋 ]
価格:2,838円(税込、送料無料) (2024/10/26時点)


月別アーカイブ
リンク