インストールレスプログラミング( ´ー`)

VBA , JavaScript , HTAなど 365アプリはインストール必要ですが、仕事に無いケースはほぼないから(・_・;)

( ´ー`)

休みの日なのでのんびりedge操作を遊んでいます。

見つけたやつは結局起動すらさせることができなかったので、

qiita.com

こちらの方の分を自分用にカスタマイズする方向ですすめています。

見つけた方もあきらめきれてはいないので、質問はしてみました。答えてもらえるかなー。

github.com

答えてもらえるかなー。こちらも動いてくれるとうれしい。

カスタマイズしている内容は、edgeのセッションがあると、うまく起動しないことがあるので、見つけた方の分からちょっとだけ変えて抜き出して入れてみました。

Private Sub cleanUpSessions()
'------------------------------------------------------------------
' Provides cleaning before firing up a new session to prevent
' pipe error
'------------------------------------------------------------------
    Dim proc
   'Clean up all running sessions
    On Error Resume Next
    For Each proc In GetObject("winmgmts:").ExecQuery("Select * from Win32_Process")
        If proc.name = "msedge.exe" Then 'chrome.exe
            proc.Terminate
        End If
        DoEvents
    Next
    On Error GoTo 0
 
End Sub

この部分を丸ごといただくことで、事前にセッションを閉じて起動するように変更。

あとは、エラー吐くたびにブラウザの起動しなおしが必要で、この部分が自分に一番ストレスだったので、
a6_ExecuteHelperFunction  57行のEnd をコメントアウトし、変数の解放をとめました。

'共通エラー対応。メッセージ表示、かつインターネットハンドルを解放して強制終了とする。
'※エラー発生時にデバッグモードに入り、ユーザーに任せると解放されない可能性が高いので強制終了とする。
Public Sub DisplayErrorAndEnd(displayText As String)
    displayText = displayText & vbCrLf & "処理を終了します。"
    MsgBox displayText, vbCritical, "エラー"
    'End   解放をとめる
End Sub

わざと解放していただいているのを、自分の都合で止める。これでもう、すでに開いているブラウザを捕まえたいという動機はなくなりました。
何度でも試行錯誤できる。

というか Endだけでステートメントとして成立するんですね 知らなかった。。強制終了できるのか。

あとは、on error resume next って書いてても止められてしまうことの対処とか (設定変更するだけ)

xlam拡張子のやつの使い方とかトラストセンターとか

いろいろと知らなかったこと、以前と変わったこととか・・・ 勉強になります。

あとは見つけた方にはいろんな機能が実装されているので、その中身を理解すればもっと機能を拡張できる気がするので、

自分用にどんどん調整していきたいものです。

追記

もう一個のほうが動いた!

これのせいか!!

いろいろあがいてみるものですね(・_・;)

わからなかったので、他も探してみました。

ブラウザーを操作するやつ、直接いじるのはあきらめたので、他も探してみました。

というか、そもそも目的の作業は十分果たしているので、さらにいろいろ試してみているだけ。


github.com

こちらがとっても良さそうなのですが、ブラウザの起動自身で失敗する。

coreってオブジェクトが入ってこないみたい。。

どこだ・・ドコガワルインダ(・_・;)

学習再開

わたしもなかなかあきらめが悪いようで、もう少し考えてみようということで、いろいろ調べてみました。

ちゃんと大事なこと書いてある。。

qiita.com

普通に起動したものを外部から操作しているわけではなく、CDPでコントロールできるように起動オプションをつけて起動したものを操作するって話でした。。

オプション付きのクロームのショートカットを作り、それに対して通信を試みると、URLとかの情報がJSONできちんと帰ってくる。

それを閉じないまま、もう一度オプション付きのショートカットから起動して、複数のクライアントを起動し、帰ってくるJSONを見てみると、詳しくは読み取れないけどどうみても両方が開いている情報を返してきてくれていることはわかる。

あとはCDPとかをきちんと読んで必要な情報をもらえるようにすればいいようだ。

明日はEdgeで同じことをしよう。

Edgeだとwebdriverというところと、この型のライブラリを参考に変更していけばいいだけ。。

ライブラリの方から理解を試みるんじゃなくて記事をきちんと最初から読んでいけばわたしでもわかりそう。

今年度の私の課題はこれだなー。

(ΦωΦ)楽しそうだ。

繰り返し書きますが、結局私たちに使用が許されている手段はMicrosoft365アプリ群とVBA,HTMLやJavscriptとそれをローカルで使わせてもらえるHTAJScript

そのほかはすべてWebアプリみたいな感じで提供されるので、そこを自由に扱える可能性が開けたのは夢が広がる。

明日また読み進めて、もう少し手掛かりをつかみたいところです。

休日とかしか小説読んだりできないので、遅々とした歩みですが、歩み始めることができそうです。

結局わかりませんでした。

すでに開いているEdgeの制御についても悪戦苦闘していましたが、いったんあきらめようと思います。

EdgeのプロセスIDを使ってるぼいなぁとか、APIのへんの勉強をしつつ、いろんなコードも見漁ってみましたが、

制御に成功しない。Edgeを起動するモードとかも関係あるならお手上げですしね。。

ぶつ切りのほうでなら、途中で操作もはさめるし、定型のものなら、完全に制御できそうなので、問題はないんですが、

色々調べてて、いけるのか・・!?と思いつつ、勝てなかったので残念。。

もうちょいあがいてはみますが、とりあえずあきらめないとかなぁ。

でも、いろいろ学べたので、TinySeleniumとか、webdriverを使う方も勉強をしてみて、

qiita.com

なんとか満足がいくところまでいきたい。

今、webアプリですませてしまう業務が多いので、効率化のためには必須だと思っています。。

進捗なし

EdgeやChromeを制御できるようにはなったので、とてもありがたいですが、

すでに開いているやつをどうにかするのが、今のところほんとにできない。

ブラウザ全部閉じて・・・、とやり直すのが回数が増えると面倒。

どうすればいいのかなぁ・・というのを試行錯誤中です。

Chrome,EdgeをVBAでを操作する②

引き続き、取り組んでいます。

qiita.com
とてもお世話になっています。ほかの方の記述とかで引用されていないのがなぜかわからない。
すごいものなのに。

今日クリアしたことは2点。

①実際の作業と並行して扱いたい。

こんな風にしてみました。

Public Edgedrv As IWebDriver

Sub 起動()
    Set Edgedrv = New EdgeDriver
End Sub
    
Sub ①()
     Edgedrv.OpenURL ("https://www.yahoo.co.jp")
End Sub

Sub ②()
    Edgedrv.OpenURL ("https://www.google.co.jp")
End Sub

Sub 終了()
    Edgedrv.CloseWindow
    Set Edgedrv = Nothing
End Sub

とても単純ですが、変数を保持してれば、手作業を間に入れてもやれたというもの。

本当は、すでに開いているものを捕まえて・・というのをやりたかったのですが、その余裕はなかったので、

こうしてみたらすんなり動く。イミディエイトウィンドウでもけっこうやりたい放題できるのでテストとしてもいい。

これは捗ります。


②テーブルの対処
先週15分ほどかかっていた作業が30秒ほどで終わってた。これでもうこわいものはあまりない(・_・;)

       Set elem = New HTMLDocument
        elem.write "<!DOCTYPE html><html><head></head><body><table>"
        elem.write Edge.FindElementByXPath("とりたい部分のtbody部分のフルXPath").GetHTML 
        elem.write "</table></body></html>"
        
        Set objTable = elem.getElementsByTagName("table")(0)

        If Replace(objTable.innerText, " ", "") <> "" Then
            For i = 0 To objTable.Rows.Length - 1
                PSht.Cells(l, 1) = Format(DateStr, "mm/dd")
                For j = 0 To objTable.Rows(i).Cells.Length - 1
                    PSht.Cells(l, j + 2) = Replace(Replace(objTable.Rows(i).Cells(j).innerText, Chr(10), ""), "未登録", "")
                Next j
                l = l + 1
            Next i
        End If

GetHTMLっていうメソッドは勝手に作ったものです。元の方のコードのGetTextContentを参考にちょっっとだけ修正したもの。
でも、この違いはでかい。

あとは、一つのテーブルをもつHTMLDocumenに強引にしたてて、昔からの方法でExcelシートに放り込む。
速い( ´ー`) コードもとても楽 Microsoft HTML Object Libraryへの参照設定はシテクダサイ。

さくさくやりたかったことができ始めました。

'Public
'エレメントのTextContentを取得
Private Function IWebElement_GetTextContent() As String
    Dim funcCode As String, res As String
    funcCode = "function(){return this.textContent.replace(/\\s/g, ' ');}"
    res = CallFunction(funcCode, "")
    
    IWebElement_GetTextContent = Json_.GetValue(res, "result", "result", "value")
End Function

'Public
'エレメントのTextContentを取得
Private Function IWebElement_GetHTML() As String
    Dim funcCode As String, res As String
    funcCode = "function(){return this.innerHTML;}"
    res = CallFunction(funcCode, "")
    
    IWebElement_GetHTML = Json_.GetValue(res, "result", "result", "value")
End Function

思いつくままメモるので、足りないところは補完してください(・_・;)

Edge,ChromeをVBAで操作する

わたしの手柄ではありませんが、とてもすばらしいですし、ずっと使わせてもらおうと思っているので、紹介します。

ただ、素人の私では使えるところまで来るのにまぁまぁかかったので、その辺はメモ。

github.com

こちらです。
一つ上に戻って、

zipでコードを保存します。スマートなやり方あるなら教えてほしい(・_・;)

githubでダウンロード

ZIPファイルを展開し、After_refactoring_srcフォルダの中身のクラスモジュールコードをExcelにインポートします。

まず、このインポートから私はつまづきました。

githubの仕様という記事を見かけたのですが、改行コードがこのままだとちゃんとインポートできません。

LF → CR+LF に改行コードを変えましょう。また、日本語が化けるので、ShiftJISに文字コードを変えました。

私はMS Codeを使いました。

Win11のメモ帳でもなんとかできそうでした。やり方は、メモ帳で開いて、コードをコピー、新しいタブを追加してそこに貼りつけると改行コードはCR+LFになります。
あとは、文字コードANSIで保存すればいけそうでした。Win10のメモ帳もいけるのかなぁ?

Excelにインポートしたとき、標準モジュールになると失敗しています。クラスモジュールにならないとだめです。


環境によってはもう使えると思います。

でも、私はいくつかの環境下で使用できませんでした。

エラーは忘れましたが、ローカル配列が多すぎる的なことを確か言われました。

細かいことが苦手な私は、

Buffer(32767) As Byte  ここを  Buffer(10000) As Byte

と変えました。そしたら職場ではとりあえず動いた。。

なんて雑な・・・と自分でも思っていますが、とりあえずそれで動き出したのでわたしはよしとしています。

ツイッターにてきとーに書きなぐった内容はこれだけです。


とりあえず動き出したこれを使ってると、素晴らしすぎました。

iframeにもきちんと対応してくれる。

だいぶ使えだしましたが、今の悩みはすでに開いたブラウザからのスタート。

だれかわかる人いれば教えてください。。

次回はテーブルのデータを吸い出すことをいつか書きます。

私がやろうとしていたことをこの状態でやると、DeBug.Printを止めたとしても15分もかかってしまったんです。

それじゃあ時間がかかりすぎるということで、昨日から今日までかかり、対応は見えました。ツイッターにそのへんは散らばっています。

VBAすごい。ちゃんとやればちゃんと動く。

あいかわらず私には十分すぎる言語です。