我将MS Access查询导出到模板,进行一些格式化,然后将模板另存为新名称。当这一切都完成后,我有一个孤立的MS Excel进程,当再次调用该函数时,它会干扰。我认为这是我使用范围的方式或最后清理问题的问题。
此外,我是一名新手编码员,所以如果有人有任何提示和技巧,我可以利用这些提示和技巧使我更好,我总是乐于接受。
在Andre的评论之后更新了代码 在Rory的评论之后更新了代码
Public Function OpenOrders(strSupplier As String)
'Excel file variables
Dim xlapp As Excel.Application
Dim wb As Excel.Workbook
Dim ws As Excel.Worksheet
Dim xlsLRow As Long
Dim xlsLCol As Long
'Access variables
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL As String
'Set up access objects
strSQL = "SELECT * FROM qryOpenOrderReport WHERE [Supplier Cd] = '" & strSupplier & "';"
Set db = CurrentDb
Set rs = db.OpenRecordset(strSQL)
'Set up excel connection
Set xlapp = CreateObject("Excel.Application")
Set wb = xlapp.Workbooks.Open(Application.CurrentProject.Path & "\Open Order Template.xlsx")
Set ws = wb.Worksheets(1)
xlapp.Visible = True
'Make sure the form is clear
xlsLRow = ws.UsedRange.Rows(ws.UsedRange.Rows.Count).row
xlsLCol = ws.UsedRange.Columns(ws.UsedRange.Columns.Count).Column
ws.Range("A2", ws.Cells(xlsLRow, xlsLCol)).ClearContents
'Copy recordset to worksheet
ws.Cells(2, 1).CopyFromRecordset rs
rs.Close
'Copy formats down and autofit
xlsLRow = ws.UsedRange.Rows(ws.UsedRange.Rows.Count).row
xlsLCol = ws.UsedRange.Columns(ws.UsedRange.Columns.Count).Column
xlapp.CutCopyMode = False
ws.Range(ws.Cells(2, 1), ws.Cells(2, xlsLCol)).Copy
ws.Range(ws.Cells(3, 1), ws.Cells(xlsLRow, xlsLCol)).PasteSpecial (xlPasteFormats)
ws.UsedRange.Columns.AutoFit
'Clean up
xlapp.DisplayAlerts = False
Set ws = Nothing
wb.SaveAs Application.CurrentProject.Path & "\Open Orders\" & strSupplier & ".xlsx"
wb.Close True
Set wb = Nothing
xlapp.Quit
Set xlapp = Nothing
End Function
答案 0 :(得分:3)
您的Cells
来电的所有都需要更改为ws.Cells
。这就是导致孤儿进程的原因。
答案 1 :(得分:1)
我的猜测是,在进行清理时,您仍然有ws
的有效引用,这会阻止Excel退出。
我建议按此顺序进行:
'Clean up
xlapp.DisplayAlerts = False
Set ws = Nothing
wb.Close True, strSupplier
Set wb = Nothing
xlapp.Quit
Set xlapp = Nothing
ws.Range("A2", "XFD1048576").ClearContents
似乎有点激进:) - 您可以使用.UsedRange
。
附加说明:
打开记录集后,您永远不会处于rs.EOF
为假,但rs.BOF
为真的情况。因此没有必要测试rs.BOF
。
将循环更改为Do While
,If Not (rs.EOF And rs.BOF) Then
变得多余:
Set rs = db.OpenRecordset(strSQL)
Do While Not rs.EOF
' ...
rs.MoveNext
Loop
答案 2 :(得分:1)
您必须对Excel的对象非常具体,打开它们并以相反的顺序关闭。这是一个有效的骨架:
Dim xls As Excel.Application
Dim wkb As Excel.Workbook
Dim wks As Excel.Worksheet
Dim rng As Excel.Range
Set xls = New Excel.Application
Set wkb = xls.Workbooks.Open("c:\test\workbook1.xlsx")
Set wks = wkb.Worksheets(1)
Set rng = wks.<somerange> ' Cells or whatever.
' Do stuff.
' Clean up.
Set rng = Nothing
wks.Name = "My New Name"
wkb.Close True
Set wks = Nothing
Set wkb = Nothing
xls.Quit
Set xls = Nothing
不要将wkb.Sheets用于工作表。