以下、(1)社内サイトからダウンロードしたExcelファイルを開く、(2)開いたエクセルファイルを取得するコードです(動作はOK)。
(★)のDoEvents
とSleep 100
の部分について、
DoEvents
のみだと、「ブックは取得できませんでした」となるSleep 100
を入れると、正常動作する
のですが、この挙動の違いを**DoEvents
とSleep
関数の仕組みの違いから理解**をしたく。
以下いろいろ調べたところの、私の推測です。
補足等、詳しくご説明頂ける方がいれば是非よろしくお願いいたします。
私の推測
ブックを開く処理と、本コードの実行は、同じプロセス(Excel)であるが、スレッドが異なる。
ブックを開く処理を実施するためには、制御をVBA→OSに移す必要がある。
DoEvents
で、制御をVBA→OSに移すが、ココによると、DoEvents
は0.02秒しか、制御を移せない。
したがって、追加で直後に、Sleep 100
を入れることで、0.1秒Sleep
させる。
Sleep
関数は、「処理を停止」する関数なので、この関数を入れることで、別スレッド(ブックを開く)が実行できる?
(どこを読んでも、「処理を停止させる」程度の説明なのでここの理解がぼんやりしています)
コード
VBA
1・ 2・ 3(省略) 4・ 5・ 6'(1)社内サイトからダウンロードしたExcelファイルを開く 7Dim o As IUIAutomation 8Dim e As IUIAutomationElement 9Set o = New CUIAutomation 10Dim h As LongPtr 11h = ie.hwnd 12h = FindWindowEx(h, 0, "Frame Notification Bar", vbNullString) 13If h = 0 Then Exit Sub 14 15Set e = o.ElementFromHandle(ByVal h) 16Dim iCnd As IUIAutomationCondition 17Set iCnd = o.CreatePropertyCondition(UIA_NamePropertyId, "ファイルを開く") 18 19Dim Button As IUIAutomationElement 20Dim InvokePattern As IUIAutomationInvokePattern 21 22While InvokePattern Is Nothing 23DoEvents 24Set Button = e.FindFirst(TreeScope_Subtree, iCnd) 25Set InvokePattern = Button.GetCurrentPattern(UIA_InvokePatternId) 26Wend 27InvokePattern.Invoke '『開く』ボタンを押すコード 28 29 30'(2)自動で開かれたワークブックオブジェクトを取得する 31Dim wb As Workbook 32Dim isFound As Boolean 33isFound = False 34 35Dim i As Long 36For i = 1 To 10000 37 For Each wb In Workbooks 38 If wb.Name = "ダウンロードして開いたブック名.csv" Then 39 Set new_wb = Workbooks("ダウンロードして開いたブック名.csv") 40 isFound = True 41 Exit For 42 End If 43 Next 44 If isFound Then 45 Exit For 46 Else 47 DoEvents (★) 48 Sleep 100 49 End If 50Next 51 52If Not isFound Then 53 MsgBox "開いたブックを取得できませんでした。" 54 Exit Sub 55End If 56 57Debug.Print wb.Name & "取得できました"
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/28 03:55
2020/12/28 15:57 編集
2020/12/28 04:20
2020/12/28 11:23
2020/12/28 11:40