質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

同じ名前のページは1枚だけ開いていてほしい

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,365

score 216

 前提・実現したいこと

ExcelのシートのA列に伝票番号が列挙されています。
この伝票番号を、社内Webの伝票番号を登録するページに登録させるマクロを書きました。
IEで登録ページはもう開いておいて、そのページを見つけて捕まえて、順に伝票番号を入力して登録するような手順です。
IEのページを見つけるのは三流君とかの記事を見て学びました。
登録ページは、1件ずつ伝票番号をテキストボックスに入力して、登録ボタンを押すようになっています。

    Dim sh As Object                '起動中のShellWindow一式を格納する
    Dim win As Object               '各ShellWindowを格納する
    Dim ie As InternetExplorer      'ShellWindowから見つけたIEを格納する
    Dim document_title As String    'IEのドキュメントタイトルを格納する
    Dim inputbutton As HTMLAnchorElement    'ボタンとかを探すときに要素を格納する
    Dim i As Long                   'イテレータ
    Dim endRow As Long: endRow = ThisWorkbook.Worksheets("Sheet1").Cells(Rows.Count, "A").End(xlUp).Row 'Sheet1の最終行


    '*-- 起動中のShellWindow一式を変数shに格納 --*
    Set sh = CreateObject("Shell.Application")

    For Each win In sh.Windows
        'ドキュメントタイトル取得失敗を無視(処理継続)--*
        On Error Resume Next

        If TypeName(win.document) = "HTMLDocument" Then
            document_title = ""
            document_title = win.document.Title
            On Error GoTo 0

            '*-- ページのタイトルで探す --*
            Set ie = win
            If InStr(document_title, "伝票番号入力") > 0 Then

                '*-- シートの伝票番号の数だけ繰り返す --*
                For i = 1 To endRow Step 1
                    '*-- 伝票番号を入れて登録ボタンを押す --*
                    ie.document.getElementsByName("denpyoNo")(0).Value = ThisWorkbook.Worksheets("Sheet1").Cells(i, 1).Value
                    For Each inputbutton In ie.document.getElementsByTagName("input")
                        If inputbutton.Value = "登録" Then
                            inputbutton.Click
                            Exit For
                        End If
                    Next
                    Do While ie.Busy Or ie.readyState <> READYSTATE_COMPLETE
                        DoEvents
                    Loop
                Next i
                Exit For
            Else
                '*-- 画面を閉じる(登録画面以外のIE) --*
                ie.Quit
            End If
        End If
    Next

    '*-- いろいろ解放 --*
    Set sh = Nothing
    Set ie = Nothing

 発生している問題・エラーメッセージ

バカみたいにいっぱいIEを立ち上げてる人がいて(ウィンドウを開いたら開きっぱなしで閉じないスタイル)
なので伝票登録のこれ動作時に、同じ名前のウィンドウが複数開いていると、目的のと違うウィンドウを捕まえてしまうことが多く……

なので、これを動かす前に、この伝票番号入力ページが複数開いていたら
「開いてますよ!」と怒ったうえでこれの処理はしない、というようにしたいのですが
複数開いています、というのをどうやったらいいのか思いつきません。
「起動中のShellWindow一式を変数shに格納」の後に

    cntPage = 0
    For Each win In sh.Windows
        'ドキュメントタイトル取得失敗を無視(処理継続)--*
        On Error Resume Next

        If TypeName(win.document) = "HTMLDocument" Then
            document_title = ""
            document_title = win.document.Title
            On Error GoTo 0

            '*-- ページのタイトルを数える --*
            Set ie = win
            If InStr(document_title, "伝票番号入力") > 0 Then
                cntPage=cntPage + 1
            End If
        End If
    Next
    If cntPage <> 1 then
        MsgBox "IEは目的の1枚だけ開いておいてあとは閉じてください"
        Exit Sub
    End If


みたいなのを書けばよいのでしょうか。
同じようなコードが2回来るのってみっともなくないでしょうか。

 補足情報(FW/ツールのバージョンなど)

Win10、Excel2016、IE11です。

追加1

皆様ありがとうございます!
教えていただいた内容を踏まえて、関数にしてみました。

Sub entryDenpyo()

    Dim sh As Object                '起動中のShellWindow一式を格納する
    Dim win As New Collection       '各ShellWindowを格納する
    Dim ie As InternetExplorer      'ShellWindowから見つけたIEを格納する
    Dim document_title As String    'IEのドキュメントタイトルを格納する
    Dim inputbutton As HTMLAnchorElement    'ボタンとかを探すときに要素を格納する
    Dim i As Long                   'イテレータ
    Dim endRow As Long: endRow = ThisWorkbook.Worksheets("Sheet1").Cells(Rows.Count, "A").End(xlUp).Row 'Sheet1の最終行


    '*-- 起動中のShellWindow一式を変数shに格納 --*
    Set sh = CreateObject("Shell.Application")

    '*-- IEで開かれている[伝票番号入力]ページを探す、1個だけ開かれてるんじゃなかったら処理はしない。 --*
    Set win = FindPages(sh,"伝票番号入力")
    If win.Count = 1 Then
        Set ie = win(1)
    Else
        MsgBox ("伝票番号入力画面を1個だけ開いて、あとは閉じてください。")
        Exit Sub
    End If

    '*-- シートの伝票番号の数だけ繰り返す --*
    For i = 1 To endRow Step 1
        '*-- 伝票番号を入れて登録ボタンを押す --*
        ie.document.getElementsByName("denpyoNo")(0).Value = ThisWorkbook.Worksheets("Sheet1").Cells(i, 1).Value
        For Each inputbutton In ie.document.getElementsByTagName("input")
            If inputbutton.Value = "登録" Then
                inputbutton.Click
                Exit For
            End If
        Next
        Do While ie.Busy Or ie.readyState <> READYSTATE_COMPLETE
            DoEvents
        Loop
    Next i

    '*-- いろいろ解放 --*
    Set sh = Nothing
    Set ie = Nothing

End Sub

'*-- 開いているIEのページをcollectionに入れて戻す --*
Function FindPages(ByVal shs As Object,ByVal pagetitle as string) As Collection

    Dim win As Object               '各ShellWindowを格納する
    Dim document_title As String    'IEのドキュメントタイトルを格納する
    Dim ie As InternetExplorer      'ShellWindowから見つけたIEを格納する
    Dim clIE As New Collection      'コレクション格納用    

    For Each win In shs.Windows
        'ドキュメントタイトル取得失敗を無視(処理継続)--*
        On Error Resume Next

        If TypeName(win.document) = "HTMLDocument" Then
            document_title = ""
            document_title = win.document.Title
            On Error GoTo 0

            '*-- タイトルで探す --*
            Set ie = win
            If InStr(document_title, pagetitle) > 0 Then
                clIE.Add ie '合致したページをコレクションに格納
                Set FindPages = clIE
            End If
        End If
    Next

End Function


ここまで書いてから、h.horikoshiさんの回答を見て
「目的のページ1枚だけを戻すほうがいいっぽい…」
ということに気づきましたので、もういっかい考えます。

追加2(できた!)

Sub entryDenpyo()

    Dim sh As Object                        '起動中のShellWindow一式を格納する
    Dim ie As InternetExplorer              'FindPages関数で見つけたIEを格納する
    Dim inputbutton As HTMLAnchorElement    'ボタンとかを探すときに要素を格納する
    Dim i As Long                           'イテレータ
    Dim endRow As Long: endRow = ThisWorkbook.Worksheets("Sheet1").Cells(Rows.Count, "A").End(xlUp).Row 'Sheet1の最終行


    '*-- 起動中のShellWindow一式を変数shに格納 --*
    Set sh = CreateObject("Shell.Application")

    '*-- IEで開かれている[伝票番号入力]ページを探す、1個だけ開かれてるんじゃなかったら処理はしない。 --*
    Set ie = FindPages(sh,"伝票番号入力")

    If (Not (ie Is Nothing)) Then
        '*-- シートの伝票番号の数だけ繰り返す --*
        For i = 1 To endRow Step 1
            '*-- 伝票番号を入れて登録ボタンを押す --*
            ie.document.getElementsByName("denpyoNo")(0).Value = ThisWorkbook.Worksheets("Sheet1").Cells(i, 1).Value
            For Each inputbutton In ie.document.getElementsByTagName("input")
                If inputbutton.Value = "登録" Then
                    inputbutton.Click
                    Exit For
                End If
            Next
            Do While ie.Busy Or ie.readyState <> READYSTATE_COMPLETE
                DoEvents
            Loop
        Next i
    else
        MsgBox "登録画面がみつかりません!"
    End If

    '*-- いろいろ解放 --*
    Set sh = Nothing
    Set ie = Nothing
    MsgBox "おわりました"

End Sub

'*-- 開いているIEのページを目的の1個だけ戻す。ページがなかったり複数だったりしたらNothingを戻す。 --*
Function FindPages(ByVal shs As Object, ByVal pagetitle As String) As InternetExplorer

    Dim win As Object               '各ShellWindowを格納する
    Dim document_title As String    'IEのドキュメントタイトルを格納する
    Dim ie As InternetExplorer      'ShellWindowから見つけたIEを格納する

    Set FindPages = Nothing
    For Each win In shs.Windows
        'ドキュメントタイトル取得失敗を無視(処理継続)--*
        On Error Resume Next

        If TypeName(win.document) = "HTMLDocument" Then
            document_title = ""
            document_title = win.document.Title
            On Error GoTo 0

            '*-- IEだったらタイトルで探す --*
            Set ie = win
            If InStr(document_title, pagetitle) > 0 Then
                If FindPages Is Nothing Then
                    Set FindPages = ie
                Else
                    MsgBox pagetitle & ("画面を1個だけ開いて、あとは閉じてください。")
                    Set FindPages = Nothing
                    Exit Function
                End If
            End If
        End If
    Next

End Function


皆様のご指導のもとに、とても改善して書けました!
「開いているIEのページを目的の1個だけ戻す」というのは
他にも1件ずつエントリするような作業がいろいろありますので(社内システムがイケてないので……)
この部分を関数にできたので、使いまわせそうな気がします。

ベストアンサーっていっぱいつけられないのですね……
teratailは先生がいっぱいいるので嬉しいです!ありがとうございます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

+3

>同じようなコードが2回来るのってみっともなくないでしょうか

関数を作ってしまいましょう。
関数の中で多重チェックとIEウィンドウの取り出しを同時にやれば
すっきりすると思います。

Public Function getIEWindow(ByVal title As String) As Object
'==============================================================================
'■getIEWindow : 開いているIEのウィンドウを返す。取得に失敗または複数起動の場合
'はNothingを返す。複数起動の場合はメッセージが出る。
'==============================================================================
  Set getIEWindow = Nothing

On Error Resume Next
  Dim sh As Object: Set sh = CreateObject("Shell.Application")
  Dim win As Object
  For Each win In sh.Windows
    If (TypeName(win.document) = "HTMLDocument") Then
      If (InStr(win.document.title, title) > 0) Then
        If (getIEWindow Is Nothing) Then                                    ' 初出の検出
          Set getIEWindow = win
        Else                                                                ' 複数検出
          MsgBox "IEは目的の1枚だけ開いておいてあとは閉じてください"
          Set getIEWindow = Nothing
          Exit Function
        End If
      End If
    End If
  Next
  Set win = Nothing
  Set sh = Nothing
On Error GoTo 0

End Function

呼び出し元

Dim ie As Object: Set ie = getIEWindow("伝票番号入力")
If (Not (ie Is Nothing)) Then ...

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/27 16:28

    コレクション使うよりこの方がいいですね。
    無駄がないし、すっきりします。

    キャンセル

  • 2018/03/29 09:30

    >hatena19さん

    フォローありがとうございます。

    自分の関数を見直してみたのですが、
    呼び出し元がエラー状況を判断できないので、戻り値には処理結果の
    コードとかを返したほうがよさそうですね。(取得したオブジェクトは
    ByRefの引数に返すということで...)。

    キャンセル

checkベストアンサー

+2

現状ではWindow検索ループ(外側ループ)の中で目的のWindowを探し、見つけたその場で登録処理のループを行っていると思います。

Window検索ループ
② Windowタイトル判定
③ ⇒合致していたら登録処理(登録用の内側ループ)
④Loop Next

ここにそのまま全Windowタイトルのチェックを追加しようと考えると
>同じようなコードが2回来るのってみっともなくないでしょうか。
となってしまうと思います。

他の回答者さんからも指摘が出ているとおり、同じ処理を複数回行う必要があるのなら関数化してしまった方が機能的です。

しかし今回の場合、Window検索ループは「対象となる1Windowを見つける」ことが目的のループ処理です。
見つけたWindowに片っ端から登録処理をしたいわけではありませんので、このループ内で登録処理まで行う必要はありません。
目的のWindowさえ特定できていれば、登録はループを抜けた後でもかまわないのです。

Window検索ループはあくまで目的のWindowを見つけるためのループ処理にとどめ、対象のWindowを見つけた際には即登録ではなくオブジェクト変数に格納しておくようにします。
全てのWindowを検索し終えた後、対象が1ページだけ見つかっていた場合には、オブジェクト変数に格納しておいたページに対して登録処理を行えば無駄なコーディングが避けられると思います。

Window検索ループ
② Windowタイトル判定
③ ⇒見つけたページをオブジェクト変数に格納する
③ ⇒2つ目の対象Windowが見つかったタイミングでメッセージ表示&処理中断
④Loop Next
⑤見つけたページがあれば登録処理(複数見つけた場合はこの処理までこない)

参考になれば幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/28 11:59

    どういう基準で関数化して外に出すのか
    という基準がいまいち理解できなくていままでテキトウにやっていたのですが
    そういう判断基準でわけたらいいのですね。
    ありがとうございます。学びました!

    キャンセル

  • 2018/03/28 12:36

    機能単位でみて同じ処理(似たような処理)を複数回行うのなら関数化した方がいいです。

    例えば全Windowの検索ループを複数回行いたいのなら、そこを関数化してループ結果の対象ウィンドウだけ返すような関数を作った方がいいです。

    同じロジックを複数個所に記述していると、片方に修正(例えばループ回数を変更したいとか)を行った場合、もう片方にも同じ修正をあてなければならないことが多いです。(ダブルメンテ)
    これは非常に面倒ですし、改修漏れや記述誤りの温床ともなります。なによりスマートではありません。

    関数化の指標としては、大きくなりすぎる処理を関数化してコードを見やすくするというものもあると思います。
    この場合、関数化することでコードはスマートになりますが、関数内で何が行われているのか、見通しは悪くなります。

    今回の場合、おそらく検索ループは1回で十分ですので「繰り返し使う」という意味では関数化は必要ないでしょう。
    ループ内のコードが肥大化するようであれば関数化を考えてもいいかもしれません。
    ※提示いただいたくらいのボリュームなら関数化は必要なさそうですが。

    やるのなら
    ①全ウィンドウをチェックして対象ウィンドウを返す関数
    ②取得したウィンドウに登録を行う関数
    という2本立てにしたらすっきりしそうですね。

    キャンセル

+2

IEで登録ページはもう開いておいて、そのページを見つけて捕まえて、順に伝票番号を入力して登録するような手順です。

この、「IEで登録ページはもう開いておいて」の部分は、具体的にどういうことなのでしょう。
ユーザーが手作業で開くのでしょうか。それともVBAの別の処理で開くということでしょうか。

VBAでの自動登録ということなら、CreateObjectでIEを新規に開いて、そのIEで登録ページを開いて登録処理をすれば、既存のIEがどのページを開いていようが、関係ないと思いますが、そうできない理由はなんでしょうか。

追記

条件に合致するページが1枚だけのときに、処理を実行するということなら、
合致するページをコレクションに格納して、その件数で処理を分けたらどうでしょう。
(動的配列かDictionalyオブジェクトに格納する方法もありますが今回はコレクションで。)

    Dim win As Object               '各ShellWindowを格納する
    Dim ie As InternetExplorer 
    Dim clIE As New Collection

    '*-- 起動中のShellWindow一式を変数shに格納 --*
    Set sh = CreateObject("Shell.Application")

    For Each win In sh.Windows
        'ドキュメントタイトル取得失敗を無視(処理継続)--*
        On Error Resume Next

        If TypeName(win.document) = "HTMLDocument" Then
            document_title = ""
            document_title = win.document.Title
            On Error GoTo 0
            '*-- ページのタイトルで探す --*
            Set ie = win
            If InStr(document_title, "伝票番号入力") > 0 Then
                clIE.Add IE '合致したページをコレクションに格納
            Else
                '*-- 画面を閉じる(登録画面以外のIE) --*
                ie.Quit
            End If
        End If
    Next

    Select Case clIE.Count
    Case 0
        MsgBox "登録ページを開いてください。"
    Case 1
        Set IE = clIE(1)
        '登録処理
    Case Else
        MsgBox "IEは目的の1枚だけ開いておいてあとは閉じてください"
            'ここでコレクション内のページを閉じる処理をいれるのもあり
    End Select

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/28 10:55

    これはですね
    同じ伝票入力ページを複数開いている人がいるのが原因です。
    伝票入力ページに伝票番号を入れて登録はしないでそのまま開きっぱなしにして
    また別のタブで伝票番号入力ページを開いて…ということをしていて
    このツールが、その開きっぱなしで放置されているページを誤って捕まえてしまい
    「せっかく入力しておいた伝票番号を『潰された』」というクレームが出るのです。
    知らないよそんなの!中途半端で放置してるのが悪いんじゃん!バカ!せっかくとか言ってるけど単に忘れてただけでしょ!
    と思うのですが、私のできることは「開くのは1枚だけにしてください」と都度お願いすることだけなのです。

    キャンセル

  • 2018/03/28 11:19

    なるほど、ご苦労、お察しします。
    ちょっと気になったのは、質問の一番最初のコードでは、登録画面以外のページは強制的に閉じてますが、これはクレームは来ないのでしょうか。

    キャンセル

  • 2018/03/28 11:55

    来ました…( ˘•ω•˘ )
    余計なページを開かないでって言ってるんだからいいじゃんと安直に閉じる処理を入れたら怒られました…。なので外しました。

    キャンセル

+1

オペレーション的には、最初にIEが開いているかチェックして、1枚でも開いていたら「閉じます」のメッセージの後すべて自動的に閉じてから処理を開始するほうがわかりやすいような気がします。
できるのかはわかりませんが、とりあえず仕様的観点からの回答でした。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/27 14:30

    ありがとうございます。
    私も全部閉じてから新規に開いてログインから開始って感じにしたかったのですが
    ログインは各自でやっておきたいというご希望でしたので
    そこのところは抵抗できず…( ˘•ω•˘ )

    キャンセル

  • 2018/03/27 14:32

    お客さん都合なんですね。
    心中お察しします。

    キャンセル

  • 2018/03/27 14:34

    ありがとうございます…
    現場のかたのこだわりってよくわかんなくてむつかしいですね…

    キャンセル

+1

ループ内に処理を突っ込んでいますが、このような時にはループを外に出しましょう。

まず目的のページを見つけるためだけの関数を作ります。
この関数を仮に FindPages と名付けます。
その中ではまず空の配列を作り、次いでループを使って見つかったページを配列に追加します。
ループ終了したら作った配列を戻り値として返します。

呼び出し側はまず FindPages を呼び出して配列を取得します。
その配列の要素数が 0 であったらページが開かれていないのでエラー処理をします。
2 以上なら複数開かれているのでエラー処理をします。
1 なら該当ページは一つだけ開かれているので、そのページに対して処理をします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/27 17:26

    Sub entryDenpyo()

    Dim sh As Object '起動中のShellWindow一式を格納する
    Dim win As Object '各ShellWindowを格納する
    Dim ie As InternetExplorer 'ShellWindowから見つけたIEを格納する
    Dim document_title As String 'IEのドキュメントタイトルを格納する
    Dim inputbutton As HTMLAnchorElement 'ボタンとかを探すときに要素を格納する
    Dim i As Long 'イテレータ
    Dim endRow As Long: endRow = ThisWorkbook.Worksheets("Sheet1").Cells(Rows.Count, "A").End(xlUp).Row 'Sheet1の最終行


    '*-- 起動中のShellWindow一式を変数shに格納 --*
    Set sh = CreateObject("Shell.Application")
    MsgBox sh.Windows.Count
    Set win = FindPages(sh)
    If win.Count = 1 Then
    Set ie = win(1)
    Else
    MsgBox ("伝票番号入力画面を1個だけ開いて、あとは閉じてください。")
    Exit Sub
    End If

    '*-- シートの伝票番号の数だけ繰り返す --*
    For i = 1 To endRow Step 1
    '*-- 伝票番号を入れて登録ボタンを押す --*
    ie.document.getElementsByName("denpyoNo")(0).Value = ThisWorkbook.Worksheets("Sheet1").Cells(i, 1).Value
    For Each inputbutton In ie.document.getElementsByTagName("input")
    If inputbutton.Value = "登録" Then
    inputbutton.Click
    Exit For
    End If
    Next
    Do While ie.Busy Or ie.readyState <> READYSTATE_COMPLETE
    DoEvents
    Loop
    Next i

    '*-- いろいろ解放 --*
    Set sh = Nothing
    Set ie = Nothing

    End Sub


    Function FindPages(ByVal shs As Object) As Collection

    Dim win As Object '各ShellWindowを格納する
    Dim document_title As String 'IEのドキュメントタイトルを格納する
    Dim ie As InternetExplorer 'ShellWindowから見つけたIEを格納する
    Dim clIE As New Collection

    For Each win In shs.Windows
    'ドキュメントタイトル取得失敗を無視(処理継続)--*
    On Error Resume Next

    If TypeName(win.document) = "HTMLDocument" Then
    document_title = ""
    document_title = win.document.Title
    On Error GoTo 0

    '*-- タイトルで探す --*
    Set ie = win
    If InStr(document_title, "伝票番号入力") > 0 Then
    clIE.Add ie '合致したページをコレクションに格納
    Set FindPages = clIE
    End If
    End If
    Next

    End Function


    こんなかんじですか?(むつかしい…)
    そして、こういうときにコードはここに書けばよいのでしょうか?
    もっと適切な書く場所があったらごめんなさい…

    キャンセル

  • 2018/03/27 17:38

    質問を編集して追記という形にすればいいと思います。
    コメントを流し読みだけしましたが、流れは合ってると思うので実際にやってみてから追記してください。
    アルゴリズムの説明は足りましたか?
    理解できたなら実装は難しくないはずですが。

    キャンセル

  • 2018/03/28 11:02

    足りました!
    追記もしてみました。
    こうやって追記すればいいんですね。ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る