vbaからchromeへ配列を渡す方法【VBA, chrome拡張機能】

やりたいこと

vbaからchromeへクリップボード経由でパラメータの受け渡しを行う。

経緯

vbaからchromeへアクセスをする際、urlパラメータ経由でリクエストを受け渡す方法はすでにスクレイピングの結果をエクセルへ渡す方法で実装できています。

ただし、url経由での明け渡しができないケースがあります。
Salesforceで新規ケース画面を独自パラメータを付与して開く際のURLは以下の通りです。
URL : https://testcompany83-dev-ed.develop.lightning.force.com/lightning/o/Case/new?count=1&text1=value1&text2&value2

アクセスをするとリダイレクトが発生し、独自パラメータが消去された状態で画面が開きます。
URL : https://testcompany83-dev-ed.develop.lightning.force.com/lightning/o/Case/new?count=1

これを回避するにはやはり、クリップボード経由での受け渡しをする必要があります。
ソースコードについては上記元記事に掲載しており、そこから追加・修正した分のみを抜粋していきます。

ソースコード

VBA

' ブラウザを起動する。
' waitResponse : True - レスポンスを待機します。
' timeout : タイムアウト(ms)
'
' return : レスポンス情報
'          waitResponseがFalseの場合,常にNothing
'
Public Function Launch(Optional waitResponse As Boolean = False, Optional timeout As Long = 10000) As BrowserResponse

    ' リクエストパラメータを設定
    Dim request As New BrowserRequest // (1)
    Call request.SetRequest(mParams)

    ' コマンド実行
    Call ExecuteCommand
    
    ' レスポンス取得
    Dim response As New BrowserResponse
    If (waitResponse = False) Then
        Set response = Nothing
    Else
        Call response.Receive(timeout)
    End If
    Set Launch = response
End Function
  1.  リクエストを設定する処理をBrowserRequestに切り出しています。
Option Explicit

' コンストラクタ
Private Sub Class_Initialize()
End Sub

' デストラクタ
Private Sub Class_Terminate()
End Sub

' url形式に結合したパラメータを返却する
Public Function JoinParam(params As Dictionary) As String
    If (params.Count = 0) Then
        JoinParam = ""
        Exit Function
    End If
    
    ' パラメータ結合
    Dim p As String
    p = "?"
    Dim key As Variant
    For Each key In params
        p = p & key & "=" & params.Item(key)
        p = p & "&"
    Next
    ' 末尾の不要な&を削除
    p = Left(p, Len(p) - 1)
    JoinParam = p
End Function
'
' リクエストデータを設定する
'
Public Sub SetRequest(params As Dictionary) // (1)
    ' クリップボードにパラメータを設定
    Const PREFIX As String = "VBA_TO_CHROME" // (2)
    Dim str As String
    str = PREFIX & vbCrLf
    str = str & JoinParam(params)
    str = Replace(str, "?", "")
    Call Clipboard.SetClipboardData(str)
End Sub
  1.  SetRequestメソッドでChromeに渡すためのパラメータを設定しています。
  2. Chrome側で読み取る際、vbaのデータであると判別がつくよう識別子を先頭に付与しています。

chrome拡張機能

    , "content_scripts":[
        {
            "matches": ["https://www.db.yugioh-card.com/yugiohdb/card_search.action*AutoMode*"]
            , "js": ["VBA_Response.js", "VBA_Request.js", "get_card_detail.js"] // (1)
            , "run_at":"document_end"
        }
    ]
  1. VBAと合わせる形でVBA_Request.jsを追加しています。
/**
 * リクエストデータ
 * データはクリップボード経由で取得する。
 */
class VBA_Request {
    // データを取得する。
    async getData() { // (1)
        const HEADER = 'VBA_TO_CHROME';
        const row_data = await navigator.clipboard.readText();
        const lines = row_data.split("\r\n");
        let params = [];
        console.log(row_data);
        if (lines[0] === HEADER) {
            const kvs = lines[1].split('&');
            kvs.forEach((kv) => {
                params.push(kv.split('='));
            });
        }
        return params;
    }
}
  1. vba側で組み立てたパラメータをjson形式に変換して返却します。
    またchrome > vbaの時は、パラメータが設定されるまで無限ループで待機をする処理をしていました。しかし、今回の場合はvba側でページアクセスの前に既にパラメータが設定されていることが保証されているので、待機処理は実装していません。
    const request = new VBA_Request();
    const data = await request.getData();
    console.log(data);

パラメータを取得する処理です。
実際には取得されたパラメータを、テキストボックスに設定などに利用します。

おわりに

今回の実装が必要になることはほとんどないかと思います。
URLがリダイレクトされない限りは、元記事のURLにパラメータを載せる方法で解決できます。