我知道这是一种可行的方法。但是,也有一些并发症。
这是如何完成的:
- 将包含数据的电子表格放在单独的工作簿中。此工作表应在打开时执行刷新查询,然后在数据更新后关闭。
- 创建一个批处理文件来调用“数据”Excel 文件。
- 在不同的工作簿中,创建一个过程(宏)供用户调用。此过程将调用批处理文件,该文件随后调用 Excel 文件。由于您正在调用批处理文件而不是直接调用 Excel,因此 Excel 过程将继续进行,因为命令外壳被释放得如此之快,并在不同的线程中打开了另一个 Excel 文件。这使您可以继续在主 Excel 文件中工作。
这里有一些并发症:
- 我添加了一种方法来提醒用户数据已更新。存在时间问题,当工作簿不可访问时,可以尝试检查数据是否已更新,这会迫使用户尝试更新值。我包含了一个名为 my time 的方法,它会暂停代码的执行,因此它只会每隔这么多秒检查一次。
- 更新的工作表将在新窗口中弹出,因此用户需要单击其原始工作表并继续工作。如果您对 Windows 脚本感到满意,您可以学会隐藏这一点(我还没有学过)。
这里有一些文件和代码。请务必阅读代码中的 cmets,了解为什么会有一些东西。
文件:C:\DataUpdate.xls
我们将创建一个名为“DataUpdate.xls”的工作簿并将其放在我们的 C:\ 文件夹中。在 Sheet1 的单元格 A1 中,我们将添加抓取外部数据的 QueryTable。
Option Explicit
Sub UpdateTable()
Dim ws As Worksheet
Dim qt As QueryTable
Set ws = Worksheets("Sheet1")
Set qt = ws.Range("A1").QueryTable
qt.Refresh BackgroundQuery:=False
End Sub
Sub OnWorkbookOpen()
Dim wb As Workbook
Set wb = ActiveWorkbook
'I put this If statement in so I can change the file's
'name and then edit the file without code
'running. You may find a better way to do this.
If ActiveWorkbook.Name = "DataUpdate.xls" Then
UpdateTable
'I update a cell in a different sheet once the update is completed.
'I'll check this cell from the "user workbook" to see when the data's been updated.
Sheets("Sheet2").Range("A1").Value = "Update Table Completed " & Now()
wb.Save
Application.Quit
End If
End Sub
在 Excel 的 ThisWorkbook 对象中,有一个名为 Workbook_Open() 的过程。它应该如下所示,以便在打开时执行更新代码。
Private Sub Workbook_Open()
OnWorkbookOpen
End Sub
注意:如果 1) 您从命令行或 shell 访问该文件,并且 2) 您安装了 Office Live 插件,我在关闭此文件时发现了一个错误。如果您安装了 Office Live 加载项,它将在退出时引发异常。
文件:C:\RunExcel.bat
接下来,我们将创建一个批处理文件,用于打开我们刚刚制作的 Excel 文件。从批处理文件中调用 Excel 文件而不是使用 Shell 直接从其他 Excel 文件调用的原因是因为 Shell 在其他应用程序关闭之前不会继续(至少在使用 Excel.exe "c:\File.xls" 时)。但是,批处理文件运行其代码,然后立即关闭,从而允许调用它的原始代码继续执行。这将使您的用户继续在 Excel 中工作。
这个文件只需要:
cd "C:\Program Files\Microsoft Office\Office10\"
Excel.exe "C:\DataUpdate.xls"
如果您熟悉 Windows 脚本,您可以做一些花哨的事情,例如以隐藏模式打开窗口或传递文件名或 Excel 位置的参数。我使用批处理文件保持简单。
文件:C:\UserWorkbook.xls
这是用户将打开以“进行工作”的文件。他们将调用代码来更新此工作簿中的另一个工作簿,并且在更新此工作簿时他们仍然可以在此工作簿中工作。
您需要在此工作簿中的一个单元格中检查 DataUpdate 工作簿中的“更新表已完成”单元格。我在 Sheet1 中选择了单元格 G1 作为示例。
将以下代码添加到此工作簿中的 VBA 模块:
Option Explicit
Sub UpdateOtherWorkbook()
Dim strFilePath As String
Dim intOpenMode As Integer
Dim strCallPath As String
Dim strCellValue As String
Dim strCellFormula As String
Dim ws As Worksheet
Dim rng As Range
Set ws = Worksheets("Sheet1")
Set rng = ws.Range("G1")
strCellFormula = "='C:\[DataUpdate.xls]Sheet2'!A1"
'This makes sure the formula has the most recent "Updated" value
'from the data file.
rng.Formula = strCellFormula
strFilePath = "C:\RunExcel.bat"
intOpenMode = vbHide
'This will call the batch file that calls the Excel file.
'Since the batch file executes it's code and then closes,
'the Excel file will be able to keep running.
Shell strFilePath, intOpenMode
'This method, defined below, will alert the user with a
'message box once the update is complete. We know that
'the update is complete because the "Updated" value will
'have changed in the Data workbook.
AlertWhenChanged
End Sub
'
Sub AlertWhenChanged()
Dim strCellValue As String
Dim strUpdatedCellValue As String
Dim strCellFormula As String
Dim ws As Worksheet
Dim rng As Range
Set ws = Worksheets("Sheet1")
Set rng = ws.Range("G1")
strCellFormula = "='C:\[DataUpdate.xls]Sheet2'!A1"
strCellValue = rng.Value
strUpdatedCellValue = strCellValue
'This will check every 4 seconds to see if the Update value of the
'Data workbook has been changed. MyWait is included to make sure
'we don't try to access the Data file while it is inaccessible.
'During this entire process, the user is still able to work.
Do While strCellValue = strUpdatedCellValue
MyWait 2
rng.Formula = strCellFormula
MyWait 2
strUpdatedCellValue = rng.Value
DoEvents
Loop
MsgBox "Data Has Been Updated!"
End Sub
'
Sub MyWait(lngSeconds As Long)
Dim dtmNewTime As Date
dtmNewTime = DateAdd("s", lngSeconds, Now)
Do While Now < dtmNewTime
DoEvents
Loop
End Sub
如您所见,我不断更新“侦听单元格”中的公式,以查看其他单元格何时更新。更新数据工作簿后,我不确定如何在不重写所有单元格的情况下强制更新代码。关闭工作簿并重新打开它应该会刷新值,但我不确定在代码中执行此操作的最佳方法。
整个过程有效,因为您使用批处理文件将 Excel 调用到与原始文件不同的线程中。这使您可以在原始文件中工作,并且在其他文件更新时仍会收到警报。
祝你好运!