1

here's my original post VBA Excel instance doesn't close when opened from MS Access - late binding it was answered and i didn't realize that the xlsm file still isn't closed when I accepted the answer.

The reason why this is such a huge problem, is because when there's an open ghost .xlsm file, the next .xlsm file that opens doesn't run the startup macro. so, all my automations are failing because the previous .xlsm is sitting in memory.

So, I have many automations scheduled to run. They're all similar in a way that an MS Access program is run, then, from the MS Access program the .xlsm is opened, then the MS Access program emails the results. More than 1 automation can be running at the same time, so, sometimes when the .xlsm is opened, there might be other excel files open, or other .xlsm files, or none at all.

What's happening is that, for some reason, using the code below, the .xlsm file doesn't close fully. It's not visible in the taskbar and the only reason I know that it's still opened somewhere is by going into the VBA Projects window (see the screenshot below).

Here's a screenshot that shows whats on my taskbar and what's in the VBA Projects. enter image description here

And, for some reason, when the file is sitting like this, ghosted, the next .xlsm file doesn't run the startup macro. If i kill Excel, and then open the .xlsm file, the startup macro runs fine.

Here's the code I'm using

This is what opens the excel file from MS Access

Set ExcelApp = CreateObject("Excel.Application")
Set ExcelWbk = ExcelApp.Workbooks.Open(CurPath & "CurrentProjects.xlsm", True)
ExcelApp.Visible = False
ExcelApp.Quit
Set ExcelWbk = Nothing
Set ExcelApp = Nothing

This is the startup macro. This is placed in the THIS WORKBOOK module.

Private Sub Workbook_Open()
    CreateReporting
End Sub

Here's the code in the excel file

Option Explicit

Public Sub CreateReporting()

    Dim MonthlyPath As String, CurPath As String, ProjectDate As String, FullName As String, CurLastRow As Long, CurRowNum As Long
    Dim i     As Range, CurCell As Variant, CurRange As Range
    Dim wbkM  As Workbook, wbkNewFile   As Workbook, wksReportDates As Worksheet, wksCopyFrom   As Worksheet, wksCopyTo   As Worksheet, wks3  As Worksheet
    Dim rngCopyFrom As Range, rngCopyTo As Range

    CurPath = ThisWorkbook.Path & "\"
    
    With ThisWorkbook.Sheets("QReportDates")
        MonthlyPath = .Range("A2").Value
        ProjectDate = .Range("B2").Value
    End With
    
    FullName = ProjectDate & " Current Projects.xlsx"

    Set wbkM = Workbooks("CurrentProjects.xlsm")
    Set wksReportDates = wbkM.Sheets("QReportDates")
 
    If Dir(MonthlyPath, vbDirectory) = "" Then
        MkDir (MonthlyPath)
    End If

    Set wbkNewFile = Workbooks.Add
    wbkNewFile.SaveAs MonthlyPath & FullName

    Set wbkNewFile = Workbooks(FullName)

    wbkM.Sheets("TEMPLATEReporting").Copy after:=wbkNewFile.Sheets(1)
    wbkNewFile.Sheets(2).Name = "Current Projects"

    With wbkNewFile
        .Sheets("Sheet1").Delete
    End With

    Set wksCopyFrom = wbkM.Sheets("QCurrentProjects")
    Set wksCopyTo = wbkNewFile.Sheets("Current Projects")
                                                           
    With wksCopyFrom
        CurLastRow = .Cells(Rows.Count, "A").End(xlUp).Row
        Set rngCopyFrom = .Range("A2:K" & CurLastRow)
    End With
                         
    With wksCopyTo
        Set rngCopyTo = .Range("A2:K" & CurLastRow)
    End With
                        
    rngCopyTo.Value = rngCopyFrom.Value
    
    For Each i In wksCopyTo.Range("F2:F" & CurLastRow)
        With Worksheets(1)
            .Hyperlinks.Add Anchor:=Range("F" & i.Row), Address:=Range("F" & i.Row), TextToDisplay:=Range("C" & i.Row).Value
        End With
    Next
      
    wbkNewFile.Save
    wbkNewFile.Close
    Set wbkNewFile = Nothing
    Set wksCopyTo = Nothing
    Set rngCopyTo = Nothing
    Set wksCopyFrom = Nothing
    Set rngCopyFrom = Nothing
     
    wbkM.Worksheets("QReportDates").Delete
    wbkM.Worksheets("QCurrentProjects").Delete
    wbkM.Save
    wbkM.Close
    
    Set CurCell = Nothing: Set CurRange = Nothing: Set wbkM = Nothing: Set wbkNewFile = Nothing: Set wksReportDates = Nothing:  Set wksCopyFrom = Nothing: Set wksCopyTo = Nothing
End Sub

Note that in this version I'm closing the .xlsm file from excel

wbkM.Close

But I also tried closing it from MS Access and removing the wbkM.Close from Excel. Same result.

Set ExcelApp = CreateObject("Excel.Application")
Set ExcelWbk = ExcelApp.Workbooks.Open(CurPath & "CurrentProjects.xlsm", True)
ExcelApp.Visible = False 
ExcelWbk.Close 
ExcelApp.Quit    
Set ExcelWbk = Nothing
Set ExcelApp = Nothing
lalachka
  • 403
  • 5
  • 16
  • 36
  • In MS Access code, you do not close the Excel workbook. Plus, you do not run the Excel macro. – Parfait Jan 28 '21 at 14:11
  • Am I not closing it in excel? But I tried both ways, I tried leaving your line in ms access and removing the wbkm.close from excel. Same. And the macro is called in THISWORKBOOK, I didn't post that part. But it works fine, it opens automatically and runs and just doesn't close and sits in memory. Then the next macro doesn't auto run. However, if I kill excel from task manager and open that workbook, the macro runs on startup – lalachka Jan 28 '21 at 14:15
  • Please edit your post with step by step process between Access/Excel. At the very beginning what is opened or closed? I assume MS Access is opened with *all* Excel workbooks and app closed. – Parfait Jan 28 '21 at 14:21
  • done, please look now :) – lalachka Jan 29 '21 at 06:11
  • I feel this is more a processing than programming issue. Your text explanation does not explicitly explain what spawns what process. Usually MS Access is the better automation tool. Have it run/spawn/initialize the others and close their operations (Excel workbook, Outlok email, etc.). Try restarting machine, only open Access, have Access open Excel workbook, run macro, close workbook. For this approach, remove `Workbook_OnOpen` event and have Access deliberately run macro: `ExcelApp.Run "ThisWorkbook.CreateReporting"` (assuming macro resides behind `ThisWorkbook` sheet). – Parfait Jan 30 '21 at 19:18
  • Thank you. Will try. Yes, everything is done from access, except the startup macro, will try that as well. As for only opening one program, that's not going to work. I always have many dbs and excel files open. Besides automations running at different times, I'm also working on that computer. But I will try running the macro and closing the file from access. That might do it. Thank you! – lalachka Jan 30 '21 at 19:21
  • You also have an unqualified reference toward bottom `With Worksheets(1) ... End With`. Where does this worksheet reside? This may have side effects with many open workbooks. And even with `Range` in `Hyperlink` formula. There is no period qualifier – Parfait Jan 30 '21 at 19:21
  • I will fix that reference but that's definitely not the problem. My other macros don't have this part and they all have the same issue of ghosting – lalachka Jan 30 '21 at 19:22
  • 1
    Actually one reason the underlying workbooks hang for macro is a prompt waiting for user such as warning workbook will replace existing. For this, inside macro try turning off [`DisplayAlerts`](https://learn.microsoft.com/en-us/office/vba/api/excel.application.displayalerts) and end turning it back on. Even turn off [`ScreenUpdating`](https://learn.microsoft.com/en-us/office/vba/api/excel.application.screenupdating) for efficiency. – Parfait Jan 30 '21 at 19:35
  • Thank you! I think my other macro has it, but will check!! – lalachka Jan 30 '21 at 19:37
  • hey, it works now!! i know what did it, but opening the macro from access and closing the workbook from access fixed it all, huge thank you!!! do you want to post an answer? youve given so much useful info, i really appreciate it!! i posted my code for reference but feel free to post an answer, i will accept it! – lalachka Feb 03 '21 at 02:55

1 Answers1

1

with @Parfait's help (or really, him fixing this for me in 3 threads), it all now works perfect. posting the code for reference

this is what opens the xlsm file, runs the macro and then closes the xlsm file

Set ExcelApp = CreateObject("Excel.Application")
Set ExcelWbk = ExcelApp.Workbooks.Open(CurPath & MainProjectName & ".xlsm", True)
ExcelApp.Visible = False
ExcelApp.Run "MainProcedure"
ExcelWbk.Close
ExcelApp.Quit
Set ExcelWbk = Nothing
Set ExcelApp = Nothing

using this code, i no longer have ghost xlsm files

lalachka
  • 403
  • 5
  • 16
  • 36