尝试打开文件时出现错误 "specified network name is no longer available"
Getting error "specified network name is no longer available" as soon as I try to open file
在 VBA for excel 我使用 FileSystemObject
循环浏览文件夹中的文件,然后当我找到 excel 文件时尝试打开它并更新文件中的任何超链接。
每当我尝试在 excel 中打开文件时,我都会收到错误消息 Run-time error '2147024832 (80070040)': Automation error The specified network name is no longer available.
尝试打开文件失败,如果我在此事件后退回代码,我似乎不再能够 "see" 文件夹对象中的文件。
比如一个文件夹里有6个文件,最后一个是excel文件,ModifyFiles
函数会循环前5个文件,看是不是' t excel 个文件,然后移至下一个。最后它会正确识别excel文件并调用IsWorkBookOpen
函数,如果没有打开,则检查成功,然后继续调用UpdateLinks
过程。当它点击打开文件的行时,它需要一秒钟,就像它正在尝试访问文件一样,然后我收到上述错误消息并且无法执行打开命令。之后,如果我返回到调用过程并尝试再次循环文件,它会在 For each fileX in foldX
行给我相同的错误消息。
好像试图打开文件会中断我与服务器的连接。
有什么建议吗?
我的代码(服务器名称和共享已更改,但我检查了它们的准确性并且它们很好):
Option Explicit
Dim strLISTMOD() As String
Dim strLISTFAIL() As String
Sub Main()
Dim blnE As Boolean
Dim blnA As Boolean
Dim blnS As Boolean
With Application
blnE = .EnableEvents
blnA = .DisplayAlerts
blnS = .ScreenUpdating
.EnableEvents = False
.DisplayAlerts = False
.ScreenUpdating = False
End With
ReDim strLISTMOD(0 To 0)
ReDim strLISTFAIL(0 To 0)
FileDigger "\myserver\myshare\"
With Application
.EnableEvents = blnE
.DisplayAlerts = blnA
.ScreenUpdating = blnS
End With
End Sub
Private Function IsWorkBookOpen(ByRef strFILENAME As String)
Dim lngX As Long
Dim lngErr As Long
On Error Resume Next
lngX = FreeFile()
Open strFILENAME For Input Lock Read As #lngX
Close lngX
lngErr = Err
On Error GoTo 0
Select Case lngErr
Case 0: IsWorkBookOpen = False
Case 70: IsWorkBookOpen = True
Case Else: Error lngErr
End Select
End Function
Private Function FileDigger(strDIRECTORY As String) As String
Dim oFsoX As Scripting.FileSystemObject
Dim foldX As Scripting.Folder
Dim foldY As Scripting.Folder
Dim lngErr As Long
Set oFsoX = New Scripting.FileSystemObject
On Error Resume Next
Set foldX = oFsoX.GetFolder(strDIRECTORY)
lngErr = Err
On Error GoTo 0
If Not foldX Is Nothing Then
ModifyFiles foldX
For Each foldY In foldX.SubFolders
FileDigger = FileDigger(foldY.Path)
Next
End If
End Function
Private Sub ModifyFiles(ByRef foldDIR As Scripting.Folder)
Dim fileX As Scripting.File
For Each fileX In foldDIR.Files
If fileX.Name Like "*.xls*" Then
If Not IsWorkBookOpen(fileX.Path) Then
UpdateLinks fileX.Path
AddToList fileX.Name, True
Else
AddToList fileX.Name, False
End If
End If
Next
End Sub
Private Sub UpdateLinks(strPATH As String)
Dim lnkX As Excel.Hyperlink
Dim wshX As Excel.Worksheet
Dim wbkX As Excel.Workbook
Set wbkX = Application.Workbooks.Open(strPATH, True, False, , , , True)
For Each wshX In wbkX.Worksheets
For Each lnkX In wshX.Hyperlinks
lnkX.Address = Replace(lnkX.Address, "\oldserver\oldshare\", "\newserver\newshare\")
Next lnkX
Next
wbkX.Close True
End Sub
Private Sub AddToList(ByRef strFILENAME As String, ByRef blnMODIFIED As Boolean)
Dim strLIST() As String
If blnMODIFIED Then strLIST = strLISTMOD Else strLIST = strLISTFAIL
If Len(strLIST(0)) > 0 Then
ReDim Preserve strLIST(0 To UBound(strLIST) + 1)
strLIST(UBound(strLIST)) = strFILENAME
Else
strLIST(0) = strFILENAME
End If
End Sub
好吧,我想我已经解决了这个问题。感谢@TimWilliams - 你原来的评论确实是解决方案。我不是 100% 确定问题的根本原因 - 如果有人知道并关心解释我非常想知道 - 但问题似乎是我在完成访问之前试图访问文件包含 FileSystemObject
对象的文件夹。我不知道 FSO 对象是否保留了每个文件夹及其子文件夹或什么,但我发现如果我销毁 FSO 对象,那么我就可以访问这些文件。我最终做的是修改 FileDigger
函数,以便在尝试打开 excel 中的任何文件之前,我构建了从根目录和所有子文件夹修改的所有文件的完整列表。我使用布尔标志来标识递归 FileDigger
过程的基本情况,然后在调用 ModifyFiles
过程之前销毁 FSO 对象。
这似乎在测试中有效。我必须等到工作日结束才能在整个网络共享上 运行 它,因为我不想在人们访问该共享上的文件时产生那么多的流量。
在 VBA for excel 我使用 FileSystemObject
循环浏览文件夹中的文件,然后当我找到 excel 文件时尝试打开它并更新文件中的任何超链接。
每当我尝试在 excel 中打开文件时,我都会收到错误消息 Run-time error '2147024832 (80070040)': Automation error The specified network name is no longer available.
尝试打开文件失败,如果我在此事件后退回代码,我似乎不再能够 "see" 文件夹对象中的文件。
比如一个文件夹里有6个文件,最后一个是excel文件,ModifyFiles
函数会循环前5个文件,看是不是' t excel 个文件,然后移至下一个。最后它会正确识别excel文件并调用IsWorkBookOpen
函数,如果没有打开,则检查成功,然后继续调用UpdateLinks
过程。当它点击打开文件的行时,它需要一秒钟,就像它正在尝试访问文件一样,然后我收到上述错误消息并且无法执行打开命令。之后,如果我返回到调用过程并尝试再次循环文件,它会在 For each fileX in foldX
行给我相同的错误消息。
好像试图打开文件会中断我与服务器的连接。
有什么建议吗?
我的代码(服务器名称和共享已更改,但我检查了它们的准确性并且它们很好):
Option Explicit
Dim strLISTMOD() As String
Dim strLISTFAIL() As String
Sub Main()
Dim blnE As Boolean
Dim blnA As Boolean
Dim blnS As Boolean
With Application
blnE = .EnableEvents
blnA = .DisplayAlerts
blnS = .ScreenUpdating
.EnableEvents = False
.DisplayAlerts = False
.ScreenUpdating = False
End With
ReDim strLISTMOD(0 To 0)
ReDim strLISTFAIL(0 To 0)
FileDigger "\myserver\myshare\"
With Application
.EnableEvents = blnE
.DisplayAlerts = blnA
.ScreenUpdating = blnS
End With
End Sub
Private Function IsWorkBookOpen(ByRef strFILENAME As String)
Dim lngX As Long
Dim lngErr As Long
On Error Resume Next
lngX = FreeFile()
Open strFILENAME For Input Lock Read As #lngX
Close lngX
lngErr = Err
On Error GoTo 0
Select Case lngErr
Case 0: IsWorkBookOpen = False
Case 70: IsWorkBookOpen = True
Case Else: Error lngErr
End Select
End Function
Private Function FileDigger(strDIRECTORY As String) As String
Dim oFsoX As Scripting.FileSystemObject
Dim foldX As Scripting.Folder
Dim foldY As Scripting.Folder
Dim lngErr As Long
Set oFsoX = New Scripting.FileSystemObject
On Error Resume Next
Set foldX = oFsoX.GetFolder(strDIRECTORY)
lngErr = Err
On Error GoTo 0
If Not foldX Is Nothing Then
ModifyFiles foldX
For Each foldY In foldX.SubFolders
FileDigger = FileDigger(foldY.Path)
Next
End If
End Function
Private Sub ModifyFiles(ByRef foldDIR As Scripting.Folder)
Dim fileX As Scripting.File
For Each fileX In foldDIR.Files
If fileX.Name Like "*.xls*" Then
If Not IsWorkBookOpen(fileX.Path) Then
UpdateLinks fileX.Path
AddToList fileX.Name, True
Else
AddToList fileX.Name, False
End If
End If
Next
End Sub
Private Sub UpdateLinks(strPATH As String)
Dim lnkX As Excel.Hyperlink
Dim wshX As Excel.Worksheet
Dim wbkX As Excel.Workbook
Set wbkX = Application.Workbooks.Open(strPATH, True, False, , , , True)
For Each wshX In wbkX.Worksheets
For Each lnkX In wshX.Hyperlinks
lnkX.Address = Replace(lnkX.Address, "\oldserver\oldshare\", "\newserver\newshare\")
Next lnkX
Next
wbkX.Close True
End Sub
Private Sub AddToList(ByRef strFILENAME As String, ByRef blnMODIFIED As Boolean)
Dim strLIST() As String
If blnMODIFIED Then strLIST = strLISTMOD Else strLIST = strLISTFAIL
If Len(strLIST(0)) > 0 Then
ReDim Preserve strLIST(0 To UBound(strLIST) + 1)
strLIST(UBound(strLIST)) = strFILENAME
Else
strLIST(0) = strFILENAME
End If
End Sub
好吧,我想我已经解决了这个问题。感谢@TimWilliams - 你原来的评论确实是解决方案。我不是 100% 确定问题的根本原因 - 如果有人知道并关心解释我非常想知道 - 但问题似乎是我在完成访问之前试图访问文件包含 FileSystemObject
对象的文件夹。我不知道 FSO 对象是否保留了每个文件夹及其子文件夹或什么,但我发现如果我销毁 FSO 对象,那么我就可以访问这些文件。我最终做的是修改 FileDigger
函数,以便在尝试打开 excel 中的任何文件之前,我构建了从根目录和所有子文件夹修改的所有文件的完整列表。我使用布尔标志来标识递归 FileDigger
过程的基本情况,然后在调用 ModifyFiles
过程之前销毁 FSO 对象。
这似乎在测试中有效。我必须等到工作日结束才能在整个网络共享上 运行 它,因为我不想在人们访问该共享上的文件时产生那么多的流量。