【发布时间】:2016-06-29 12:02:14
【问题描述】:
是的,我知道问题不是新问题,我已经研究了很多,但到目前为止没有任何帮助。这也是我的第一篇 stackoverflow 帖子,所以如果我做错了什么,请告诉我。 我想要做的是通过 VBA 代码一次导入多个 Excel 工作表。到目前为止,我的代码正在运行,但我的问题是任务管理器中始终存在一个 EXCEL.EXE 实例,当我想导入多个文件时会导致问题。 我已经尝试了以下线程中提出的解决方案:
VB.NET Excel Program Leaves EXCEL.EXE floating after completion
Remove Excel task from Task manager after running from Access using VBA
这是我的导入代码,我只用了几个星期的 VBA,所以请不要看得太仔细。
Public Function importExcelFiles()
Dim tablename As String
Dim spreadsheetType As String
Dim xlAppl As Excel.Application
Dim xlWB As Excel.Workbook
' **** function imports the excel file and copies data into target table *********
' choose the file to import
path = OpenFile("Select file for import", "Excel-Files" & Chr$(0) & "*.xls; *.xlsx; *.xlsm", "Excel-Files", CurrentProject.path)
If Not IsNull(path) And Not path = "" And Not path = " " Then
Set xlAppl = CreateObject("excel.application")
Set xlWB = xlAppl.Workbooks.Open(path)
spreadsheetType = acSpreadsheetTypeExcel9
Call AlternateKKS("KKS_DB", xlAppl, xlWB)
tablename = "KKS_DB"
DoCmd.TransferSpreadsheet acImport, spreadsheetType, tablename, path, false, "merged!" 'import to excel'
DoCmd.SetWarnings False
xlAppl.DisplayAlerts = False
xlWB.Close acSaveNo
xlAppl.Quit
Set xlWB = Nothing
Set xlAppl = Nothing
End If
End Function
我注意到当我取消注释 Call AlternateKKS 时它可以工作,所以可能有一些东西阻止 Excel.exe 关闭。 该函数中有相当多的代码,所以在我发布所有这些之前,我想知道我应该寻找什么可能会导致问题。它所做的基本上是将工作表读入一个数组,对数据进行一些修改并将其写回“合并”的工作表上。 我已经确定有一个 xlWB。或 xlAppl。每当我参考工作表时,我不使用 msdn 论坛上提到的 with 语句(剧透中的链接)。
PS:另一方面,我要导入的工作表称为“合并”,但由于某种原因,它只有在我放 !最后(一位同事告诉我这样做)但我们不知道为什么。
编辑:这里是所有直接引用应用程序或工作表的代码
Dim wsSource As Worksheet
Dim wsDestination As Worksheet
Public Function ReadIntoArray(name As String, ByRef xlWB As Excel.Workbook) As Variant
' Dim ret As String
g_arrayrange = GetLastCell(name, xlWB)
Set wsSource = xlWB.Sheets(name)
Call Sort(wsSource, xlWB)
ReadIntoArray = wsSource.range("A1:" & g_arrayrange).Value
End Function
Sub WriteBackArray(data() As Variant, destination As String, ByRef xlWB As Excel.Workbook)
Set wsDestination = xlWB.Sheets(destination)
wsDestination.UsedRange.ClearContents
wsDestination.range("A1").resize(UBound(data, 1), UBound(data, 2)) = data
End Sub
Function GetLastCell(name As String, ByRef xlWB As Excel.Workbook) As String 'return coordinates of last cell with data'
Dim lrw As Long
Dim lcol As Long
Dim lastCell As String
Dim rng As range
Dim sheet As Worksheet
Dim col As String
Set sheet = xlWB.Sheets(name)
Set rng = xlWB.Sheets(name).Cells
'get last row '
lrw = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).row
'get last column'
lcol = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
g_lrw = lrw
'change to string for further use as range'
lastCell = GetCellAsString(lcol, lrw)
GetLastCell = lastCell
End Function
在另一个函数中
source = xlAppl.Transpose(source)
其余代码只操作数组
【问题讨论】:
-
在您未包含在本文中的代码部分中是否有任何与 Excel 实例相关的代码。如与关闭 Excel 实例有关。你能发布 AlternativeKKS() 的代码
-
在您的应用程序中查找 anywhere,您可以在其中使用任何 Excel 对象或方法以及 WITH 代码块。这是一个众所周知的问题,除非您的代码显式声明并清除用作 with 块对象的基于自动化的对象变量(With...End With 语法),否则这些对象可能会作为“孤立”com 卡在内存中对象。然后,这将阻止其自动化服务器类的发布(因为组成对象仍然具有非零 COM 引用计数)。这将表现为您观察到的症状:尽管调用了 .Quit,但 Excel 不会关闭。
-
基于自动化的对象实例都应该这样使用: Dim objTemp as (Object/Excel.range/whatever) set objTemp = (whatever) With ObjTemp 'do stuff here End With set objTemp = Nothing你不应该做的是:使用 objExclApp.worksheets(1).range("myNamedrange") 'do stuff End With :这是一种可以为范围对象留下幻像引用的事情LINK
-
对于
wsSource或wsDestination之类的变量:您是否删除了它们的Dim语句?还是它们是全局变量?或者模块没有Option Explicit? (耶!) -
那么你必须做
Set wsSource = Nothing等一旦不再使用,否则他们将无限期地保留他们的参考。局部变量(在必要时作为参数传递给其他函数)在这方面更安全。