简体   繁体   中英

trying to close a workbook after it gets opened, but the loop failes to do it

Through a sub i download an excel file from a website. when the download button is clicked, it both opens the excel file and also let the file get downloaded. i dont need it to get opened so as soon as it gets opened and before srart of next subs, i need to close it. By some codes i tried to do it but I failed.

The problem is that the Do Loop i wrote, can not catch the file and hangs. It just works well when i debug it through F8. Then i thought maybe by application.wait method I can let the sub to wait till the workbook appears, like what happens in debug mode but it didnt help as well.

Also i need to add that since everytime the file gets downloaded its name changes by the webiste then i used Like operator.

Sub Test()    
    Dim wb As Workbook
    Dim wbName As String
    Dim Cnt As Integer
    
    wbName = "transactions_history_"
    
    'Application.Wait Now + TimeValue("00:00:10") ' it didnt help so i commented it
    Do
        Application.Wait Now + TimeValue("00:00:01")
        For Each wb In Application.Workbooks
            If wb.Name Like wbName & "*" Then
                Cnt = 1
                Exit Do
            End If
        Next wb
    Loop Until Cnt = 1 
    wb.Close
End Sub

Anybody has any idea? thanks.

FaneDuru, I copy here the code which downloads the workbook from the website. it worked very well until the website changed something and when the file gets downloaded it gets opened too. I need to close it to let the rest of the programms work without problem but i coudlnt manage it so far.

Sub TBC()

    ' declerations
    Dim myBrowser                             As Selenium.ChromeDriver
    Dim FindBy                                As New Selenium.by
    Dim objFSO                                As Object
    Dim objFolder                             As Object
    Dim objFile                               As Object
    Dim A, I                                  As Integer
    Dim FileName, BankFolderAddress           As String
    Dim N                                     As Byte
  
    ' initializations
    BankFolderAddress = "D:\Projects\Excel\Main Program\Bank Statements\"
    Set FindBy = New Selenium.by
    Set myBrowser = New WebDriver
    I = 0
    A = 0
        
    Sheet2.Cells.ClearContents
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFolder = objFSO.GetFolder(BankFolderAddress)
    For Each objFile In objFolder.Files 
        Sheet2.Cells(I + 1, 1) = objFile.Name
        Sheet2.Cells(I + 1, 2) = objFile.Path
        I = I + 1
    Next objFile
    If Sheet2.Cells(1, 1) <> "" Then
        For N = 1 To I
            Kill Sheet2.Cells(N, 2).value
        Next N
    End If
   
Start:
   
    myBrowser.SetProfile Environ("LOCALAPPDATA") & "\GOOGLE\CHROME\USER DATA"
    myBrowser.AddArgument "profile-directory=Default"
    myBrowser.Start "chrome"
    
    Application.DisplayAlerts = False
   
    
   'Address e website
    myBrowser.Get "https://tbconline.ge/tbcrd/login?t=false"
    myBrowser.Window.Maximize
    
    A = 0
    Do
        Application.Wait Now + TimeValue("00:00:01")
        A = A + 1
        If A = 10 Then GoTo Finish
    Loop Until myBrowser.IsElementPresent(FindBy.XPath("//button"))
      
    If myBrowser.IsElementPresent(FindBy.Css("input[formcontrolname='username']")) Then
        myBrowser.FindElementByXPath("//button").Click
    Else
        GoTo JMP
    End If

JMP:
   
   'For removing PopUps
    If myBrowser.IsElementPresent(FindBy.XPath("//div[@id='mainLoadingLayer']/ui-view/ui-view/div/div[2]/div/div/div/div/div[3]/button")) Then
        myBrowser.FindElementByXPath("//div[@id='mainLoadingLayer']/ui-view/ui-view/div/div[2]/div/div/div/div/div[3]/button").Click
    End If
   
   ' Choosing Transaction Menu
    A = 0
    Do
        Application.Wait Now + TimeValue("00:00:01")
        A = A + 1
        If A = 10 Then GoTo Finish
    Loop Until myBrowser.IsElementPresent(FindBy.XPath("//a[contains(text(),'Transactions')]"))

    If myBrowser.IsElementPresent(FindBy.XPath("//a[contains(text(),'Transactions')]")) Then
        myBrowser.FindElementByXPath("//a[contains(text(),'Transactions')]").Click
    End If

   'choosing Transaction submenu
    A = 0
    Do
        Application.Wait Now + TimeValue("00:00:01")
        A = A + 1
        If A = 10 Then GoTo Finish
    Loop Until myBrowser.IsElementPresent(FindBy.XPath("//span[contains(.,'Transactions')]"))

    If myBrowser.IsElementPresent(FindBy.XPath("//span[contains(.,'Transactions')]")) Then
        myBrowser.FindElementByXPath("//span[contains(.,'Transactions')]").Click
    End If
                
   'Clicking on Download icon
    Do
        Application.Wait Now + TimeValue("00:00:01")
    Loop Until myBrowser.IsElementPresent(FindBy.XPath("//ib-controls/div/div[2]/div[2]"))

    If myBrowser.IsElementPresent(FindBy.XPath("//ib-controls/div/div[2]/div[2]")) Then
        myBrowser.FindElementByXPath("//ib-controls/div/div[2]/div[2]").Click
    End If
              
   ' clicking on excel option to download it
    Do
        Application.Wait Now + TimeValue("00:00:01")
    Loop Until myBrowser.IsElementPresent(FindBy.XPath("//a[contains(.,'Excel')]"))

    If myBrowser.IsElementPresent(FindBy.XPath("//a[contains(.,'Excel')]")) Then
        myBrowser.FindElementByXPath("//a[contains(.,'Excel')]").Click
    End If
              
             
   'checking if the file is downloaded
    Do
        Application.Wait Now + TimeValue("00:00:02") 
    Loop Until Dir(BankFolderAddress & "transactions_history_*.xlsx") <> ""
  
   ' get the file name
    FileName = Dir(BankFolderAddress & "transactions_history_*.xlsx", vbDirectory)
    
   ' check if the downloaded file size
    Do
        Application.Wait Now + TimeValue("00:00:05") '03 bood
    Loop Until FileLen(BankFolderAddress & FileName) > 10000
  
Finish:
  
    ' close the Browser
    myBrowser.close

    ' ## I added this code to close the workbook but failed  
    ' call Test()
    
    Dim wb As Workbook
    Dim wbName As String
    Dim Cnt As Integer

wbName = FileName

Do
    Application.Wait Now + TimeValue("00:00:01")
    For Each wb In Application.Workbooks
        If wb.Name=FileName Then
            Cnt = 1
            wb.Close
            Exit Do
        End If
    Next wb
Loop Until Cnt = 1

call BankDataExtraction()    

End Sub

the problem is that if i do not stop the sub before the loop in debug mode, the downloaded workbook neither appears on the screen nor in task manager, and the loop can not catch it and close it, it hangs then. wait methode doesnt help too. I tried you code but it gave me automation error invalid syntax, while executing Set sessEx = GetObject(wbFullName).Application I passed the complete file address to it, If Not sameExSession(FileName).

If you are sure that the wbName is the name of the workbook searching for, your code must do what you need, but only if the workbook in discussion is open IN THE SAME EXCEL SESSION . I asked about the code opening it, but no clarification received. Please, use the next function to check if the workbook is open in the same session (with the workbook keeping the checking code). If its second parameter is True , it closes the workbook, even in a different session and quit that session. Many codes searches for an existing Excel session and use it, but open a new session if no such a session has been found. Others, uses a new session:

Function sameExSession(wbFullName As String, Optional boolClose As Boolean) As Boolean
   Dim sessEx As Excel.Application, wb As Workbook
  
   Set sessEx = GetObject(wbFullName).Application
   If sessEx.hwnd = Application.hwnd Then
        sameExSession = True
   Else
        sameExSession = False
        If boolClose Then
            sessEx.Workbooks(Right(wbFullName, Len(wbFullName) - InStrRev(wbFullName, "\"))).Close False
            sessEx.Quit: Set sessEx = Nothing
        End If
   End If
End Function

It can be called from your existing code in this way:

Sub Test()    
    Dim wb As Workbook, wbName As String, Cnt As Integer
    
    wbName = "transactions_history_"
    If Not sameExSession Then Exit Sub 'take care to use the workbook FULL NAME!
    Do
        Application.Wait Now + TimeValue("00:00:01")
        For Each wb In Application.Workbooks
            If wb.Name Like wbName & "*" Then
                Cnt = 1
                Exit Do
            End If
        Next wb
    Loop Until Cnt = 1 
    wb.Close
End Sub

If you do not know the workbook extension (since you do not use it in your above code), you can obtain the workbook name using:

    Dim strFullName As String, foldName As String
    foldName = "path to the folder where the workbook is downloaded"
    strFullName = dir(foldName & "\" & vbname & "*.*")
    If strFullName <> "" Then
       If Not sameExSession Then Exit Sub
    Else
        MsgBox "Strange...": Stop 'Just in case. It must be found, if foldName and vbName are correct...
    End If

It may fail if in the same folder there are more then one such a workbook having a name containing the used string. It will return the first of them, in alphabetical order. But, if such a case, you are the one who is needed to bring some clarifications... Of course, if opening in the other session is the correct assumption. In such a case a piece of code can iterate between all those workbooks having the same string in their name, to determine the last saved one .

You can be sure about this aspect (other session), manually searching for the workbook, copying its Full name and create a testing Sub which only calls the function I supplied, using the determined its full name.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM