Доступ к VBA (открыть файл Excel и закрыть): отключить «файл теперь доступен» - PullRequest
0 голосов
/ 22 января 2019

Я использовал следующий код Access VBA, чтобы открыть четыре разные книги Excel в цикле, когда мне нужно отредактировать данные Excel, а затем обновить таблицу Access с помощью набора записей.

xl.Application.DisplayAlerts = False
Set wb = xl.Workbooks.Open(fileName, ReadOnly = True, editable = True, notify = False)
Set ws = wb.Sheets("Sheet1")
Set ws2 = wb.Worksheets.Add
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & fileName & ";Extended Properties=""Excel 8.0;HDR=YES;IMEX=1;"";"

*****Другие коды ******

wb.Close savechanges:=False
Set wb = Nothing
Set xlc = Nothing
Set ws = Nothing
Set ws2 = Nothing
Set xl = Nothing
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing

Однако, несмотря на то, что я закрываю файл excel без сохранения для всех четырех файлов, я все равно получаю следующее уведомление после полного цикла.enter image description here
с Set wb = xl.Workbooks.Open(fileName, ReadOnly = True, editable = True, notify = False), я все еще не смог отключить уведомление.

PS.Я не получил уведомление о чтении и записи для всех четырех файлов, обычно одного или двух, что меня действительно смутило.

Есть какие-либо рекомендации по решению проблемы?

Заранее спасибо за всепомощь!

1 Ответ

0 голосов
/ 25 января 2019

Вы не можете вручную управлять сборкой мусора в VBA, но вы можете структурировать свои данные так, чтобы сборка мусора была более предсказуемой.Первое, что я рекомендую, это поместить код взаимодействия Excel в свою собственную процедуру, которая вызывается из вашего основного цикла.Причина в том, что когда процедура заканчивается, сборка мусора происходит.В следующий раз, когда цикл вызовет процедуру открытия, вы будете работать со свежим набором дескрипторов объектов, вместо того, чтобы перерабатывать объекты, как вы это делаете в настоящее время.Если вы делаете это таким образом, вам никогда не придется устанавливать ваши объекты в ничто, потому что они уничтожаются, поскольку они выходят из области видимости в конце процедуры.Просто убедитесь, что вы всегда используете локальные переменные.

Чтобы сделать это без повторного закрытия и открытия Excel, вам нужно получить дескриптор работающего в данный момент экземпляра Excel.Это предусмотрено процедурой GetExcelApp, приведенной ниже.

ПРИМЕР:

Private Sub YourMainLoop()
    For Each fileName in fileNames
        ProcessExcelData fileName
    Next fileName
End Sub

Private Sub ProcessExcelData(ByVal fileName as String)
    Dim xl As Object
    Set xl = GetExcelApp
    xl.Application.DisplayAlerts = False
    Set wb = xl.Workbooks.Open(fileName, ReadOnly = True, editable = True, notify = False)
    Set ws = wb.Sheets("Sheet1")
    Set ws2 = wb.Worksheets.Add
    cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & fileName & ";Extended Properties=""Excel 8.0;HDR=YES;IMEX=1;"";"
    ' Process the data, blah blah blah
    wb.Close savechanges:=False
    rs.Close
    cn.Close
End Sub

Public Function GetExcelApp() As Object
' Returns open excel instance.
'   If it doesn't exist, creates one to return
On Error GoTo ErrHandler
Const ERR_APP_NOTRUNNING As Long = 429    

    Set GetExcelApp = GetObject(, "Excel.Application")

CleanExit:
    Exit Function
ErrHandler:
    If Err.number = ERR_APP_NOTRUNNING Then
        Set GetExcelApp = CreateObject("Excel.Application")
        Resume CleanExit
    Else
        ShowErrorMessageBox
    End If
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...