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

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

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

2回答

3718閲覧

自動でダウンロード後に自動で開いたExcelブックを取得する方法

koyamashinji

総合スコア45

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

0クリップ

投稿2020/12/22 12:30

編集2020/12/23 12:05

マクロを使って自動で以下を実行したいのですが、(★)の部分がどうもうまくいきません。
お知恵を貸していただきたく、考えられる原因等ありましたら指摘頂きたく。
それ以前は動作OKです。

(1)社内のサイトに行く

(2)Excelファイル(正確には拡張子.csv)をダウンロードする

(3)「ダウンロード通知バー」の「開く」を自動で押して、ダウンロードしたExcelファイルを開く

(4)自動で開かれたワークブックオブジェクトを取得する(★)


コード

・ '(1) (省略) ・ ・ '(2) (省略) ・ ・ '(3)「ダウンロード通知バー」の「開く」を自動で押して、ダウンロードしたExcelファイルを開く Dim o As IUIAutomation Dim e As IUIAutomationElement Set o = New CUIAutomation Dim h As LongPtr h = ie.hwnd h = FindWindowEx(h, 0, "Frame Notification Bar", vbNullString) If h = 0 Then Exit Sub Set e = o.ElementFromHandle(ByVal h) Dim iCnd As IUIAutomationCondition Set iCnd = o.CreatePropertyCondition(UIA_NamePropertyId, "ファイルを開く") Dim Button As IUIAutomationElement Dim InvokePattern As IUIAutomationInvokePattern While InvokePattern Is Nothing DoEvents Set Button = e.FindFirst(TreeScope_Subtree, iCnd) Set InvokePattern = Button.GetCurrentPattern(UIA_InvokePatternId) Wend InvokePattern.Invoke ・ ・ ・ '(4)自動で開かれたワークブックオブジェクトを取得する(★) Dim wb As Workbook Dim new_wb As Workbook Dim isFound As Boolean isFound = False Do Until isFound = True ■ For Each wb In Workbooks If wb.Name = "ダウンロードして開いたブック名.csv" Then Set new_wb = Workbooks("ダウンロードして開いたブック名.csv") isFound = True End If Exit For Next Loop Debug.Print (wb.Name) 'ブック名が取得できていない

追記 12/23 - Exit forの位置を修正したが取得できずフリーズする

hatena様のご指摘Exit forの位置を修正の上、再度コードを実行したところ、
呼び出し側のExcelファイルがフリーズしたままになってしまいます

(エラーは吐かないが、無限ループしている?)

但し、上記コード ■ 部分にブレークポイントを設定し、
■以降をステップイン実行すると、問題なくwb.Nameが取得できます。

気になる点としては、(3)ダウンロードファイルを開く際に
「ダウンロード通知バー」から「開く」を押している点です
(コードは、上記コードブロック中(3)に追記)

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Exit For の位置がおかしいです。

vba

1Do Until isFound = True 2 For Each wb In Workbooks 3 If wb.Name = "ダウンロードして開いたブック名.csv" Then 4 Set new_wb = Workbooks("ダウンロードして開いたブック名.csv") 5 isFound = True 6 Exit For 'ここじゃないとダメ 7 End If 8 Exit For 'ここだと1回目のループでループを抜けちゃいます。 9 Next 10Loop

ただ、Workbooks.Open で開いているなら、下記で取得できるはずです。

vba

1Workbooks.Open "ANALYSIS.XLS" 2Debug.Print ActiveWorkbook.Name

あるいは、

vba

1Dim new_wb As Workbook 2Set new_wb = Workbooks.Open("ダウンロードしたブック名.csv") 3Debug.Print new_wb.Name

追記

ループ処理の場合は、無限ループ対策を入れておいた方がいいでしょう。(試行回数を制限しておくとか)
また、別スレッドの終了(今回はブックを開く)を待つ場合は、ループ内に DoEvents を入れてOSに制御を返すようにします。

上記を考慮して、

vba

1 2'(4)自動で開かれたワークブックオブジェクトを取得する(★) 3Dim wb As Workbook 4Dim isFound As Boolean 5isFound = False 6 7Dim i As Long 8For i = 1 To 1000 '試行回数1000回 適宜調整してください。 9 For Each wb In Workbooks 10 If wb.Name = "ダウンロードして開いたブック名.csv" Then 11 isFound = True 12 Exit For 13 End If 14 Next 15 If isFound Then Exit For 16 DoEvents 17Next 18 19If Not isFound Then 20 MsgBox "開いたブックを取得できませんでした。" 21 Exit Sub 22End If 23 24Debug.Print wb.Name

DoEvents を入れるだけではうまくいかない場合、Sleep か Application.Wait での待機をいれてみてください。

【VBA入門】Sleep関数(API)やWaitメソッドで処理を止める方法 | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト

投稿2020/12/22 13:24

編集2020/12/23 04:22
hatena19

総合スコア34075

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

koyamashinji

2020/12/22 13:45 編集

ご回答誠に有難うございます。Exit forの位置でしたか。。初歩的なミスをやらかしてしまいました。 また、代替方法も提示いただきありがとうございます、そのような方法もあるのですね。参考になります。 ただ、開く際は、ダウンロード通知バーの「開く」をUIAutomationClientでいじっていますので、おそらく今回は使用できないかもしれません。 自宅ではエクセル環境がないので、また明日試してみます。
koyamashinji

2020/12/23 03:29

hatena19様 質問に追記させて頂きましたが、Exit forの位置を修正後コード実行しましたが 呼び出し側Excelがフリーズしてしまいます。 ダウンロードファイルを「開く」コードを 追記しておりますので 考えられる原因があれば、ご教示頂ければ幸いです。
koyamashinji

2020/12/23 10:54

hatena19様 追記に対するご回答誠にありがとうございます。大変助かりました。 DoEventsのみでは、いくらループ回数を増やしても取得できませんでしたが、 DoEventsの後に、Sleep 100 を入れることで、無事取得できました。 (自己解決欄には改めて正常動作を確認したコードを貼りつけます)
koyamashinji

2020/12/28 14:01

hatena19様 > DoEvents を入れるだけではうまくいかない場合、Sleep か Application.Wait での待機をいれてみてください。 今回の場合だと、DoEventsだけでなく、Sleep 100を入れないと、取得できませんでしたが、 DoEventsだけだと うまくいかないのはなぜなのでしょうか。別の質問も立てたのですが、いまいち私の理解が及ばず。。 もし宜しければ教えてください。
guest

0

hatena19様からご提示頂いたコードに基づき、(★)の部分は以下のコードで正常動作しました。

・ ・ ・ '(4)自動で開かれたワークブックオブジェクトを取得する(★) Dim wb As Workbook Dim isFound As Boolean isFound = False Dim i As Long For i = 1 To 10000 For Each wb In Workbooks If wb.Name = "ダウンロードして開いたブック名.csv" Then Set new_wb = Workbooks("ダウンロードして開いたブック名.csv") isFound = True Exit For End If Next If isFound Then Exit For Else DoEvents Sleep 100 End If Next If Not isFound Then MsgBox "開いたブックを取得できませんでした。" Exit Sub End If Debug.Print wb.Name & "取得できました"

投稿2020/12/23 10:58

koyamashinji

総合スコア45

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問