I've had a similar problem before and from this forum I found out that if you instantiate using something like
Dim xlApp as Excel.Application
Set xlApp = new Excel.Application
then you get the problems you are experiencing (must be a bug - a circular reference or something)
However, if you use a function like this (which also takes advantage of the fact that there may be an instance of excel already running) then I think your problem will go away
Function xlAppMyReturnExcelApp() As Excel.Application
'this works using the create/get object thing
'this is better than referring to excel.workbooks or whatever directly because
'that way is not gauranteed to release excel correctly
On Error Resume Next
Set xlAppMyReturnExcelApp = GetObject(, "Excel.Application"

If Err.Number = 429 Then
Set xlAppMyReturnExcelApp = CreateObject("Excel.Application"

Else
Err.Raise Err.Number
End If
End Function
So basically your calling code would look like this
Dim xlApp as excel.application
Set xlApp = xlAppMyReturnExcelApp
There doesn't seem to be anything wrong with your closing code, but it might help to close up like this
xlApp.ActiveWorkbook.Close
xlApp.Quit
Set xlSheet = Nothing
Set xlBook = Nothing
Set xlApp = Nothing
Since then you are releasing the objects in the reverse order they were created
Hope this solves your problem
Mark