【问题标题】:Spreadsheet not found in the workbook, even if that spreadsheet exists在工作簿中找不到电子表格,即使该电子表格存在
【发布时间】:2021-08-07 03:43:06
【问题描述】:

我有这么一小段代码:

NombreLibro = Application.GetOpenFilename()
Set Libro = Workbooks.Open(NombreLibro, , False)

If Val(Application.Version) > 15 Then  'I tried this but it doesn't solve the problem
    Libro.AutoSaveOn = False
End If

With Libro
    For i = 1 To .Worksheets.Count
        If .Worksheets(i).CodeName = "Sheet1" Then 'HERE I HAVE THE PROBLEM
            (doing something)
            
        End If
    Next i
End With

即使工作簿实际上具有“Sheet1”,有时“if”也是错误的。 但是,如果我再次运行它,在代码中添加一个停止以检查发生了什么,那么这段代码将按预期工作。

我正在从公司网站下载工作簿并立即运行代码。 我的电脑中有 OneDrive。所以我想知道 OneDrive 是否正忙于上传文件,然后 Excel 无法正确访问它?

你有什么建议我可以试试?

编辑:

按照 VBasic2008 的建议(请参阅他/她的回答),我稍微更改了代码,但一直失败。然后我添加了一个调试 MsgBox:

For Each ws In Libro.Worksheets
    MsgBox "CodeName: " & ws.CodeName & vbLf _
        & "Name: " & ws.Name & vbLf & "Libro: " & Libro.Name  'I added this

    If ws.CodeName = wsCodeName Then
        wasFound = True
        Exit For ' The worksheet is found, no need to loop anymore.
    End If
Next ws

结果(显示在 MsgBox 中):

代号:'空白!!!

名称:SheetName '正确

Libro: LibroName '正确

Excel 中是否存在与 CodeNames 相关的错误?

EDIT2:(解决方法)

我从公司网站下载文件,网站上的数据在表格上,然后转换器将其下载为 Excel 格式。

我认为下载的文件不是Excel格式,CodeName没有填写。当 Excel 打开它并打开 VBA 编辑器时,Excel 会使用标准名称填写 CodeName。

在我的情况下,由于新下载的文件只有一张,我可以使用此解决方法:

For Each ws In Libro.Worksheets
    If ws.CodeName = wsCodeName Or ws.CodeName = "" Then
        wasFound = True
        Exit For 
    End If
Next ws

这将在第一次处理文件ws.CodeName = "" 和下一次处理ws.CodeName = wsCodename 时起作用

【问题讨论】:

  • codename 是工作表的一个属性,需要设置。如果您正在寻找名为“sheet1”的工作表,那么您需要遍历工作表,直到从范围中获得匹配项。
  • @spikey_richie 那部分是对的,代号是Sheet1,名字不一样。如果是这种情况,几分钟后代码将无法运行,而无需更改任何内容。

标签: excel vba


【解决方案1】:

使用工作表代号

Option Explicit

Sub testCodeName()

    Const wsCodeName As String = "Sheet1"
    
    ' Choose file (workbook, spreadsheet).
    Dim NombreLibro As Variant
    NombreLibro = Application.GetOpenFilename()
    
    ' Validate workbook.
    If NombreLibro = False Then
        MsgBox "You canceled.", vbExclamation, "Canceled"
        Exit Sub
    End If
    
    ' Open and create a reference to the workbook.
    Dim Libro As Workbook: Set Libro = Workbooks.Open(NombreLibro, , False)
    
    ' Attempt to find the worksheet.
    Dim ws As Worksheet
    Dim wasFound As Boolean
    For Each ws In Libro.Worksheets
        If ws.CodeName = wsCodeName Then
            wasFound = True
            Exit For ' The worksheet is found, no need to loop anymore.
        End If
    Next ws

    ' Validate worksheet.
    If Not wasFound Then
        MsgBox "Worksheet not found.", vbExclamation, "Not Found"
        Exit Sub
    End With
    
    ' Continue with the code
    With ws
        ' e.g. see if it's true.
        MsgBox "Worksheet found:" & vbLf _
            & "Name: " & .Name _
            & vbLf & "CodeName: " & .CodeName, vbInformation, "Success"
    End With

End Sub

【讨论】:

  • 您的代码基本上是我所拥有的,有时它不起作用(我删除了所有错误检查以使帖子更清晰)。对于实际具有该工作表的文件,我最终会出现“找不到工作表”,但并非总是如此。主要区别在于您使用的是“For Each”语句,而我正在循环使用工作表索引,因为我也需要该索引。
  • 我唯一能想到的就是区分大小写的问题,你可以试试这个:If StrComp(ws.CodeName, wsCodeName, vbTextCompare) = 0 Then。顺便说一句,为什么你需要(工作)表索引?也许您可以上传其中一个不正常的文件并发布指向它的链接。
  • 当您编写了一个功能齐全的 Sub 时(感谢您的时间,只需要更改 End With),我对其进行了测试,但对于一个大文件它失败了。然后我用调试器(同一个文件)运行它,并在If ws.CodeName = wsCodeName Then 行中添加了一个停止。这次成功了!?从那时起,Sub 始终使用该文件。所以问题不在于 vba,还有其他问题。
  • 关于索引,我后来用Libro.Worksheets(index)来参考工作表,但我更喜欢你的方式。
  • 所以我的意思是找到一种解决方法,因为我怀疑我会找到根本原因
【解决方案2】:

我有点像 VBA 菜鸟,但我不久前写了这个简单的代码来搜索工作表并将其删除:

Dim sht As Worksheet

For Each sht In ThisWorkbook.Worksheets
    If Application.Proper(sht.Name) = Application.Proper("Company Data") Then
        Sheets("Company Data").Select
        Application.DisplayAlerts = False
        ActiveWindow.SelectedSheets.Delete
        Application.DisplayAlerts = True
    End If
Next sht

也许这有帮助?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 2019-01-15
    • 2010-10-30
    • 1970-01-01
    相关资源
    最近更新 更多