【问题标题】:Refer to sheet using codename使用代号参考工作表
【发布时间】:2020-11-27 23:35:00
【问题描述】:

我在此代码中收到“类型不匹配”错误:

With Worksheets(Sheet1)   '* Error here 
   'my code here
End With

我的工作表CodeName'sheet1'

有人可以帮我消除错误吗?

【问题讨论】:

  • bu sheet的代号是什么意思?你的意思是代表工作表名称的变量吗?可以举个例子解释一下吗?
  • 每张工作表都有一个代号,如 sheet1 , sheet2 等当您重命名工作表时,例如: sheet1 为“abc” 代号保持不变。
  • 我的意思是索引名称。现在怎么用?
  • @ShaiRado 小心纠正错误信息! 还有一个CodeName 属性,它不同于NameIndex。正如 user007 所描述的,它仍然是 sheet1、sheet2、...,并且是 VBA Project Explorer 面板中括号中的名称 not。请参阅此处的文档msdn.microsoft.com/en-us/library/office/ff837552.aspx
  • 想补充一下我对代号属性的经验,因为上面有几篇文章说它是只读的。对我来说,它不是只读的,即使在运行时,如果我使用 Worksheet.[_CodeName]。能够为任何工作表设置此项,可以开发更通用的解决方案,并可能对 OP 有所帮助。

标签: vba excel worksheet


【解决方案1】:

1) 按索引参考表格:

With Worksheets(1) 
    '<stuff here>
End With

“索引”取决于“工作簿中工作表的顺序”。如果您打乱您的床单顺序,这可能不再是指同一张床单!

2) 按名称参考工作表:

With Worksheets("Your Sheet Name") 
    '<stuff here>
End With

这是工作表的 .Name 属性,是在 Excel 工作表选项卡中可见的名称,在 VBA 项目资源管理器的括号中。

3) 按代号参考工作表:

您建议您实际上想要使用工作表的.CodeName 属性。这不能像上面两个例子一样在括号内引用,但确实与上面的一些答案相反!它在创建时自动分配给工作表,并且是“工作表”,然后是先前创建的 CodeNames 中的下一个未使用的编号。

使用CodeName 的优点是它不依赖于工作表顺序(与Index 不同)并且如果用户仅通过在Excel 中重命名工作表来更改Name,它也不会改变。

缺点是代码可能更复杂或模棱两可。由于CodeName 是只读的 [1] 这无法改进,但确实确保了上述优势!有关详细信息,请参阅参考文档。

第一种使用方式:直接...

With Sheet1
    '<stuff here>
End With

第二种使用方式:间接地,可能会提供更多的清晰度或灵活性,展示如何使用工作表的CodeName 属性...

通过遍历工作表并读取CodeName 属性,您可以首先找到所需工作表的IndexName 属性。然后您可以使用它来引用工作表。

Dim sh as WorkSheet
Dim shName as String
Dim shIndex as Long

' Cycle through all sheets until sheet with desired CodeName is found
For Each sh in ThisWorkbook.WorkSheets        
    ' Say the codename you're interested in is Sheet1
    If sh.CodeName = "Sheet1" Then            
        ' - If you didn't want to refer to this sheet later, 
        '   you could do all necessary operations here, and never use shName
        '   or the later With block.
        ' - If you do want to refer to this sheet later,
        '   you will need to store either the Name or Index (below shows both)

        ' Store sheet's Name
        shName = sh.Name            
        ' Store sheet's Index
        shIndex = sh.Index           
    End If
Next sh 

' Check if match was found, do stuff as before if it was!
If shName = "" Then
    MsgBox "Could not find matching codename"
Else 
    ' Equally to the next line, could use Worksheets(shIndex)
    With Worksheets(shName)
        '<stuff here>
    End With
End If

[1]https://msdn.microsoft.com/en-us/library/office/ff837552.aspx

【讨论】:

  • 这是非常翔实的,写得很清楚。但是,我认为澄清一下可能会更好:CodeName 是只读的仅在运行时。我觉得这是一个重要的区别。在开发模式下,codeName 可以在任何现有工作表的属性窗口中手动更改。 (通过 VBA 开发人员窗口中的视图选项卡访问。)这将允许编码人员为他们经常使用的工作表提供信息更丰富的codename,而不是默认的“Sheet#”。
  • 我相信“下一个未使用的号码”可能会被重述或只是解释为“下一个未分配的号码”(即下一个以前未分配的号码),尽管有人可能称之为语义。如果您删除 Sheet2 然后插入一张工作表,它将命名新的工作表 Sheet3 或 Sheet4 或下一个从未分配过的名字,而不是将其命名为 Sheet2(当前“未使用”的已删除名称)。操作词可能是“下一个”,这似乎意味着“下一个高于先前分配的最高值”。顺便说一句,对于命名冒险,删除 sheet2 并将 sheet1 重命名为 sheet2 然后插入 sheet :)
  • @Mic 我的意思是“未使用”=“在此工作簿中从未使用过”,我认为这与使用“未分配”一样简单,我会解释相同...但我明白了点。
  • Worksheet.CodeName 属性是只读的,只要您的项目可以访问 vb 代码模型,就可以通过访问 VBProject.VBComponents(&lt;sheet&gt;) 来更改它,详情例如这里:stackoverflow.com/questions/31472829/change-sheet-code-name
  • 此外,它不会自动采用名称“Sheet”,然后是先前创建的 CodeNames 中的下一个未使用的数字,例如,如果您复制代号不同于 Sheet# 的工作表,它将采用工作表的代号后跟下一个未分配的数字。总体而言,除了这些挑剔之外,答案很好:-)
【解决方案2】:

您可以在代码中直接使用工作表代号,就好像它们是声明的变量一样:

Sub UsingSheetCodeName()
    With Sheet1   
       .[a1] = Sheet1.Name
    End With
End Sub

【讨论】:

  • 因为你在With Sheet1语句中,你可以使用.[a1] = .Name
  • @ShaiRado,是的,你可以。我试图展示使用代号的不同方式。
【解决方案3】:

CodeName 在运行时通过 Worksheet.Parent.VBProject.VBComponents 访问属性时实际上是可读写的:

' ActiveWorksheet both .Name and .CodeName are 'Sheet 1'    
For Each oVBComponent In ActiveWorksheet.Parent.VBProject.VBComponents
    If (oVBComponent.Name = ActiveWorksheet.CodeName) Then oVBComponent.Name = "New Name"
Next oVBComponent
Debug.Print ActiveWorkSheet.Name, ActiveWorksheet.CodeName ' "Sheet1", "New Name"

【讨论】:

    【解决方案4】:

    3 种不同的属性可用于引用工作表:

    • .Name 作为Worksheets("SomeNameHere")Worksheets("SomeNameHere").Range("A1")
    • .Index 作为Worksheets(2)Worksheets(2).Range("A1")
    • .CodeName 作为Sheet3Sheet3.Range("A1")

    要查看区别,请运行下面的代码并查看立即窗口 Ctrl+G

    Sub TestMe()
        Dim wks As Worksheet
        For Each wks In ThisWorkbook.Worksheets
            Debug.Print wks.Name
            Debug.Print wks.Index
            Debug.Print wks.CodeName
            Debug.Print "-----------------------"
        Next wks
    End Sub
    

    如果工作表的NameCodeName 没有更改,它们将是相同的。

    • 代号:

    • 姓名:

    【讨论】:

      【解决方案5】:
      Codename.select
      
      DataImport(sheet1)
      

      注意DataImport是我在VBA编辑器的属性窗口中给它的“代号”,括号中的名称是出现在选项卡上的名称。

      ergo

      DataImport.select 在 VBA 中按代号选择工作表

      【讨论】:

        猜你喜欢
        • 2022-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多