自动更新外部工作簿中的值

Posted

技术标签:

【中文标题】自动更新外部工作簿中的值【英文标题】:Updating values from external workbook automatically 【发布时间】:2013-04-07 08:45:02 【问题描述】:

我有以下工作簿设置:

工作簿 A 有一个指向 x 个工作簿 B 的链接,并从中获取数据。工作簿 B 具有指向其他一些工作簿的链接并从中获取数据。

工作簿 A 是所有其他工作簿所包含内容的一种“总结”。现在,我必须打开所有工作簿 B,刷新它们并保存,然后再打开工作簿 A。如果我不这样做,工作簿 B 将不会使用工作簿 C 中的数据进行更新。

是否可以使用 .bat 或 vbs 脚本更新所有工作簿 B?或者是否可以从工作簿 A 中更新它们?

我可能会补充一点,我在这台计算机上使用 excel starter,所以最好该解决方案与它兼容。

【问题讨论】:

如果您将它们移动到单个文件夹,那么您可以使用下面的@Philip 代码,否则您将不得不使用稍微复杂的 mpdule 来查找所有这些文件的路径,然后计算它们。如果您对该模块感兴趣,请告诉我... 是的,在不同的目录中,需要使用集合或数组之类的东西来存储文件名和位置... @Philip:但是你可以使用 VBS ;) 找到了! vbaexpress.com/kb/getarticle.php?kb_id=1064 问题+1,如果可以的话,我会为名字加上+1。 【参考方案1】:

附件是一个潜在的解决方案,作为vbs,如果可用,可以从vba 运行

感谢 Sid Rout 对 RecursiveFile(objWB) 的建议编辑

警告:有可能同时打开的书太多(我在vbs 递归地狱期间达到 512)会导致内存问题 - 在这种情况下,每个主要分支都应该依次更新,然后那些工作簿在继续下一个分支之前关闭。

它的作用

    打开strFilePath 持有的工作簿 检查 1 中是否有任何链接的工作簿,如果有则打开它们(B、B1、B2 等) 代码然后在 (2) 的每个工作簿中查找任何链接,然后依次打开所有这些链接(C1 和 C2 用于 B 等) 每个打开的书名都存储在一个数组中,Arr 当所有书籍都打开时,初始工作簿将已更新,递归代码结束,除strFilePath之外的所有打开书籍都将关闭而不保存 strFilePath 然后被保存并关闭 代码整理

编辑:更新代码以修复 vbs 递归问题

Public objExcel, objWB2, lngCnt, Arr()
Dim strFilePath, vLinks
`credit to Sid Rout for updating `RecursiveFileRecursiveFile(objWB)`

Erase Arr
lngCnt = 0

Set objExcel = CreateObject("Excel.Application")
strFilePath = "C:\temp\main.xlsx"

With objExcel
    .DisplayAlerts = False
    .ScreenUpdating = False
    .EnableEvents = False
End With

Set objWB = objExcel.Workbooks.Open(strFilePath, False)
Call RecursiveFile(objWB)

For Each vArr In Arr
    objExcel.Workbooks(vArr).Close False
Next

objWB.Save
objWB.Close
Set objWB2 = Nothing

With objExcel
    .DisplayAlerts = True
    .ScreenUpdating = True
    .EnableEvents = True
    .Quit
End With

Set objExcel = Nothing
MsgBox "Complete"

Sub RecursiveFile(objWB)
    If Not IsEmpty(objWB.LinkSources()) Then
        For Each vL In objWB.LinkSources()
            ReDim Preserve Arr(lngCnt)

            'MsgBox "Processing File " & vL

            Set objWB2 = objExcel.Workbooks.Open(vL, False)
            Arr(lngCnt) = objWB2.Name
            lngCnt = lngCnt + 1
            RecursiveFile objWB2
        Next
    End If
End Sub

工作截图

【讨论】:

它进入无限循环的原因是因为如果你删除 OERN,你会看到 vLinks = objWB.LinkSources() 行失败,因为 vLinks 被之前的 For Each vL In vLinks 循环暂时锁定,因此 @ 987654333@ 将始终从第一个循环返回相同的文件。让我看看能不能找到替代方案。 干得好席德。我已经看到链接源上的临时锁定,但昨晚没有围绕它进行血清路由。非常感谢。 我得到了这个工作。非常感谢您的帮助。一些注意事项:我没有让它与 .xlsx 格式一起使用。将工作表重新保存为 .xls 并且可以正常工作。我更改了以下行:For Each vArr In Arr objExcel.Workbooks(vArr).Close FalseClose True。否则 B 表不会与更新后的值一起保存,当我打开表 A 时,它询问我是否要更新链接,它将恢复为旧值(当我第一次打开表时,将显示正确的值,但更新后它被恢复)。再次感谢,这比我预期的要多得多【参考方案2】:

是的,您可以遍历所有源 B 工作簿,在后台打开它们并将 UpdateLinks 标志设置为 True ...

strFiles=Dir(*path & \.xls*)

do
    workbooks.open strfiles, UpdateLinks:=true
    workbooks(strfiles).close savechanges:=true
    strFiles=Dir
loop while strfiles<>""

这应该给你一个开始

【讨论】:

OP 说他正在使用 Excel Starter。 VBA 不可用是 Starter 版本。 See this answer【参考方案3】:

所以,由于 VBA 不是一个选项,让我们尝试一个 VB 脚本解决方案:

dim objFSO, objExcel, objWorkbook, objFile
'
set objExcel= CreateObject("Excel.application")
'
objExcel.visible=false
objExcel.displayalerts=false
'
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = path
'
Set objFolder = objFSO.GetFolder(objStartFolder)
' get collection of files from folder
Set colFiles = objFolder.Files
' begin loop through all files returned by Files collection of Folder object
For Each objFile in colFiles
    ' sanity check, is the file an XLS file?
    if instr(objfile.name,"xls")<>0 then ' could also use right(objfile.name,4)=...
        Wscript.Echo "Opening '" objFile.Name & "' ..."
        set objWorkbook=objexcel.workbooks.open objfile.name, updatelinks:=true
        objexcel.workbooks(objfile.name).close savechanges:=true
    end if
Next
' close Excel
objexcel.quit
' kill the instance and release the memory
set objExcel=nothing

试试看,看看效果如何

这里是 VB 脚本 SDK:MSDN Library - VB Script

【讨论】:

谢谢。我会尝试让它工作并稍后报告 我不明白这是如何回答这个问题的。这将打开文件夹中的所有 excel 文件并更新链接,OP 从单个工作簿开始。 @brettdj - 好吧,这个想法是更新链接,现在用户没有明确要求打开文件夹中的所有工作簿是正确的,但是如果不是通过打开工作簿、更新链接和保存工作簿? @brettdj:当然,如果我犯了错误,或者误解了 OP 的意图,请告诉我。 @philip 您的代码会打开给定目录中的所有工作簿,并更新所有链接。 OP 请求有一个工作簿,依次链接到 B 和 C。所以a)单个文件启动更新过程b)链接的文件不一定都在一个目录中c)打开和关闭的顺序很关键(C必须更新B,B更新A等)

以上是关于自动更新外部工作簿中的值的主要内容,如果未能解决你的问题,请参考以下文章

Excel 宏,用于从工作簿中的主工作表更新其他工作表

将 HTML 表格数据导出到现有工作簿中的新工作表(如果存在),否则更新现有工作表

将多个工作簿中的数据复制并自动化到现有的主工作簿中,而不会丢失使用 python 的格式

如何根据单元格颜色获取 UDF 以在 Excel 中自动更新

xlam Excel 插件是不是可以覆盖工作簿中的子项?

excel中,将一个工作表中几列数据自动更新到另一个工作表中对应的列中?