这里有一个我知道会工作的方法。但是,有一些并发症。
这里是它是如何做:
- 把电子表格中的数据在一个单独的工作簿。此工作表应在打开时执行刷新查询,然后在数据更新后关闭。
- 创建一个批处理文件来调用“数据”Excel文件。
- 在不同的工作簿中,创建供用户调用的过程(宏)。此过程将调用批处理文件,该文件随后调用Excel文件。由于您直接调用批处理文件而不是Excel,所以Excel过程将继续执行,因为命令外壳程序的释放非常快,并在另一个线程中打开另一个Excel文件。这使您可以继续在主Excel文件中工作。
这里有一些并发症:
- 我包括一个方法来提醒数据已udpated用户。在工作簿不可访问时,有时可能会尝试检查数据是否已更新,这迫使用户尝试更新值。我加入了一个叫做我的时间的方法,它暂停了代码的执行,所以它只检查每隔那么多秒。
- 更新后的工作表将在新窗口中弹出,因此用户需要点击其原始工作表并继续工作。如果你熟悉Windows脚本,你可以学会隐藏这个(我还没有学过)。
这里有一些文件和代码。一定要阅读代码中的评论,了解为什么有些东西在那里。
文件: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实时加载安装。如果您安装了Office Live加载项,它将在退出时引发异常。
文件:C:\ RunExcel.bat
接下来,我们要创建一个批处理文件,将打开我们刚才提出的Excel文件。从批处理文件中调用Excel文件而不是直接从使用Shell的其他Excel文件中调用Excel文件的原因是,因为在其他应用程序关闭之前(至少在使用Excel.exe "c:\File.xls"
时)Shell才会继续。但是,批处理文件运行其代码,然后立即关闭,从而允许调用它的原始代码继续。这是什么让你的使用继续在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调用到与原始文件不同的线程中。这使您可以在原始文件中工作,并在其他文件已更新时仍能收到警报。
祝你好运!
好吧,我想我花了太多时间试图找到可能有效的解决方案。看到我下面的附加答案(这是一个奇怪的长答案)。 – 2009-11-12 17:38:42