none
複数のModuleを連続稼働させるとログインもいちいちやり直すので、なんとか改めたいのですが RRS feed

  • 質問

  • ちょっと長くなりますが、以下事情を説明します。

    とあるQAサイトに、連続自動投稿するVBAを組みました。例えば深夜2時に自動投稿するよう設定すると、5分後には二つ目の投稿が、さらに5分後には三つ目の投稿が自動的になされる仕掛けです。

    アメリカとの時差の関係で、深夜零時過ぎに自動投稿するシステムが入用になって、それで自力で組み上げました。幸いエラーもなく、順調に動いてくれています。

    ただ、一つ目の投稿が終わり、5分後に二つ目の自動投稿が稼働すると、いちいちくだんのサイトへのログインから始まるのです。一つ目の投稿ですでにログインしているので、再ログインは不必要なのですが、二つ目の自動投稿用ソースコードよりログイン過程の部分を削ると、投稿じたいができなくなってしまうのです。

    一つ目の自動投稿ソースコードはModule1に、二つ目はModule2に、三つ目はModule3に収めてあります。基本構造は三つとも同じです。(ちなみに三つとも標準モジュールです)

    稼働時刻指定はModule1の冒頭に置いています。一つ目、二つ目、三つ目の稼働時刻(のプロシージャ)そろって、です。

    Moduleが2、3と改まるごとにログイン設定がリセットされてしまうから、でしょうか?そうだとしたら、Module1でのログイン設定が、後のModuleにそのまま引き継がれるような工夫は可能でしょうか?


    • 編集済み enjin2000 2020年12月30日 10:42
    2020年12月30日 9:36

すべての返信

  • どういうコードを書いたのか、フォーラムを見ている他の人にもわかるように説明しなければ、どこを修正すべきかも指摘できません。質問内容が曖昧だと、回答も概念的な回答になってしまいますよ。

    ひとまず状況的には、通信のために新しいブラウザーセッションを起動しなおしている状態に陥っていると思います。手動操作でいえば、投降後にブラウザーを一旦すべて閉じて、再度、新しくブラウザーを起動しなおしているような状況に当たります。

    サイトの構成が不明ですが、話を聞く限りでは多要素認証系のシステムではなさそうなので、ログイン情報はおそらく、揮発性 Cookie で管理されているものと推察します。現状のコードが不明ですが、MSXML2.ServerXMLHTTP で HTTP Post メソッドを直接サーバーに送信するにせよ、あるいはブラウザーを Selenium 等で制御するにせよ、同一のブラウザーセッションをそのまま引き継ぐように組みなおしてみてください。

    一つ目の自動投稿ソースコードはModule1に、二つ目はModule2に、三つ目はModule3に収めてあります。基本構造は三つとも同じです。(ちなみに三つとも標準モジュールです)

    それは特に問題にはならないでしょう。

    モジュールを分けた理由はさておき、Module の中身が Private ではないのであれば、どのモジュールに書いてあったとしても、呼び出し方に影響はありませんし、変数の有効期間も何ら変わることはありません。Access VBA であれ Excel VBA であれ同じこと。

    Module1 で宣言された「Public a As Integer」という変数を、Module2 から「a = 2」と代入して、Module3 から「MsgBox a」で表示するということができます。処理が終了したとしても、アプリが起動している間は、変数 a の中身は維持されます。

    ただし、変数名を競合させていた場合には注意が必要です。

    Module3 にも「Public a As Stiring」といった同名の変数があった場合、Module1 にとっての a は Integer になり、Module3 にとっての a は String になってしまい、それぞれ別の変数として扱われます。また、Module2 から見ると、「a = 2」ではどちらの変数にアクセスすべきか分からなくなってしまいます。

    普通は同じ名前を競合させたりはしないと思いますが、どうしても同名変数を必要とするようなケースでは、「Module1.a」や「Module3.a」のようにモジュール名を修飾させることで呼び分けることができます。こうすれば、Module2 や Module3 から、Module1 上の a As Integer な変数を読み書きすることができます。

    この「モジュール名の修飾」方法は、変数名の競合だけでなく、Sub / Function プロシージャ―名の競合時にも当てはまります。

    一方、Sub / Function 内で Dim 宣言された変数の場合、End Sub / End Function に到達した時点で破棄されます。もし、モジュールレベル変数を使わず、すべてプロシージャ内で宣言されたローカル変数を使っているのだとしたら、先に書いた通り、二回目の投稿時にブラウザーの再起動(あるいは新規セッションの開始)が行われていて、前回のセッションを捨ててしまっている可能性が高そうです。

    あるいはサイト側がワンタイムセッションを発行するような特殊なつくりになっていて、投降後に新しい認証チケットを発行しているにもかかわらず、次回の投稿時にそれを渡していない…という可能性も無くはないですが。

    いずれにせよ、アプリの動作が説明されていませんし、肝心の Web サイトの仕様も書かれていないので、予想でしか答えられません。

    例えば深夜2時に自動投稿するよう設定すると、5分後には二つ目の投稿が、さらに5分後には三つ目の投稿が自動的になされる仕掛けです。

    時刻指定の起動ということは、自動起動マクロをタスクスケジューラーに登録して定時起動させているのでしょうか?

    それとも、深夜二時になるまで VBA を起動しっぱなしにしているとか?




    2020年12月30日 13:15

  • どんなVBAなのかいちいち説明すると、かえって分かりにくくなるので、機能とその狙いに絞って説明しました。

    タスクスケジューラは使っていません。私のPCではタスクを使ってスリープから目覚めさせることはできないのです。

    VBAの「Application.OnTime TimeValue」を使っています。PCはスリープではなく、深夜無人でも稼働させています。(画面だけスリープするよう設定しました)



    >手動操作でいえば、投降後にブラウザーを一旦すべて閉じて、再度、新しくブラウザーを起動しなおしているような状況に当たります。

    それです。そういう感じです。

    Moduleを複数にした(今日の午前深夜には6つ設定して自動稼働させました)のは、1つのモジュールで投稿ページ一つ分だからです。ちょっと凝った機動を挿んであるので、一回分の投稿で1つのモジュールになっています。

    (「凝った」というのは、テキスト&画像をくだんのQAサイトに自動投稿すると、前に投稿したぶん(つまりすでに投稿されたもの)の[編集]ボタンが自動的に押されて、テキストが訂正されるのです。具体的にいうと、最新投稿ぶんへのリンクが自動的に貼られるのです。貼られた後[編集済]ボタンが自動的に押されると、そういうメカニズムです。ちなみに3つでも6つでも200でも、モジュールを追加していけば自動投稿される(ページリンク機能付き)ページは無限に付け足しできるようになっています)



    >先に書いた通り、二回目の投稿時にブラウザーの再起動(あるいは新規セッションの開始)が行われていて、前回のセッションを捨ててしまっている可能性が高そうです。

    それです。たぶんご指摘の通りだと思います!

    うーん、すると module1 の冒頭に置いた「Application.OnTime TimeValue」の列(6回自動投稿する場合はこれが6つ並んで、6つのmoduleをそれぞれ稼働させるしくみです)のもっと前に、ログインのプロシージャを置けば、解決するのでしょうか?

    後でやってみます。後で結果報告するつもりですので、そのときまた力になっていただけますか?

    [追記] やってみましたが、End Sub によってログイン設定はリセットされてしまうことに変わりはありませんでした。つまり module1 より module2 へログイン設定の引継ぎは(上記の手では)できないようです。


    • 編集済み enjin2000 2021年1月1日 11:45
    2021年1月1日 9:40