11

I get a "type mismatch" error in this code:

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

My sheet's CodeName is 'sheet1'.

Can someone please help me remove the error?

Wolfie
  • 27,562
  • 7
  • 28
  • 55
user007
  • 159
  • 2
  • 2
  • 15
  • what do you mean bu sheet's code name ? do youmean a variable representing the sheet's name ? can you explain by giving an example ? – Shai Rado Jan 05 '17 at 05:44
  • Every sheet has a code name like sheet1 , sheet2 etc When you rename a sheet eg: sheet1 to "abc" The code name remains same. – user007 Jan 05 '17 at 06:17
  • I mean the Index name. How to use now? – user007 Jan 05 '17 at 06:52
  • 10
    @ShaiRado Careful giving corrections with the wrong info! There **is also** a `CodeName` property which is different from the `Name` and `Index`. As user007 describes, it remains as sheet1, sheet2, ... and is the name *not* in brackets in the VBA Project Explorer panel. See documentation here https://msdn.microsoft.com/en-us/library/office/ff837552.aspx – Wolfie Jan 05 '17 at 09:15
  • 1
    Would like to add my experience with the codename property as a few posts above there was stated that it is read-only. For me it is not read-only, even in runtime if I use Worksheet.[_CodeName]. Being able to set this for any sheet, solutions can be developed more generic and may help the OP. – dusfor63 Oct 21 '18 at 17:33
  • In case it saves anyone confusion, ?ActiveWorkbook.VBProject.VBComponents(ActiveWorkbook.Sheets("mysheet").codename).Name returns the "codename's name" which is not the "sheet's name" even though both properties are .Name, e.g. "Sheet3" while the visible sheet name is Mysheet. And ?ActiveWorkbook.Sheets("mysheet").Name of course gives "mysheet" This can be confusing if you delete Sheet2, then rename something to Sheet2, etc. – MicrosoftShouldBeKickedInNuts Nov 06 '18 at 22:59
  • See also [Code Name: Sheet1](https://rubberduckvba.wordpress.com/2019/12/19/code-name-sheet1/) – ComputerVersteher Feb 06 '20 at 13:23
  • In addition to detailed info in the accepted answer (thanks to @Wolfie) and as it pertains to the question, one can use: `Worksheets(Sheet1.Index)`, Sheet1 being the codename of the desired sheet. Cheers – Jalal Aug 31 '21 at 19:01

5 Answers5

37

1) Refer to sheet by Index:

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

The `Index' is dependent on the "order of sheets in the workbook". If you shuffle your sheets order, this may not refer to the same sheet any more!

2) Refer to sheet by Name:

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

This is the .Name property of a worksheet, and is the name visible in the Excel worksheet tab and in brackets in the VBA Project Explorer.

3) Refer to sheet by CodeName:

You suggested you actually wanted to use the .CodeName property of a worksheet. This cannot be reference within brackets like the above two examples, but does exist contrary to some answers above! It is assigned automatically to a sheet on creation, and is "Sheet" then the next unused number in the previously created CodeNames.

The advantage of using CodeName is that it doesn't depend on the sheet order (unlike the Index) and it doesn't change if a user changes the Name simply by renaming the sheet in Excel.

The disadvantage is the code can be more convoluted or ambiguous. Since CodeName is read-only [1] this cannot be improved, but does ensure the above advantages! See the referenced documentation for more details.

First way of using it: directly...

With Sheet1
    '<stuff here>
End With

Second way of using it: indirectly, may offer more clarity or flexibility, shows how to use the CodeName property of a worksheet...

By looping over sheets and reading the CodeName property, you can first find either the Index or Name property of your desired sheet. Then your can use this to reference the sheet.

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

Wolfie
  • 27,562
  • 7
  • 28
  • 55
  • 7
    This was very informative and clearly written. However, I thought it might be good to clarify: `CodeName` is read-only **only during run time.** I feel that that is an important distinction. While in development mode, the `codeName` can be _manually_ changed in the properties window for any existing sheet. (Accessed via the view tab in the VBA developer window.) This would allow a coder to give a sheet they use constantly a more informative `codename` instead of the default "Sheet#". – Mistella Feb 14 '18 at 18:49
  • I believe that "the next unused number" might be restated or just interpreted as "the next unassigned number" (i.e., next non-previously-assigned), although one might call it semantics. If you delete Sheet2 then insert a sheet it will name the new one Sheet3 or Sheet4 or whatever is the next that has never been assigned, rather than naming it Sheet2 (the deleted name which is currently "unused"). The operative word could be "next" which seems to mean 'next higher than the highest previously assigned'. BTW, for a naming adventure, delete sheet2 and rename sheet1 to sheet2 then insert sheets :) – MicrosoftShouldBeKickedInNuts Nov 06 '18 at 23:16
  • @Mic My meaning was "unused" = "unused ever in this workbook", I think this is easily as clear as using "unassigned" which I would interpret the same... but I get your point. – Wolfie Nov 07 '18 at 08:37
  • 1
    The `Worksheet.CodeName` property is read only, as long as your project has access to the vb code model it can be changed by accessing `VBProject.VBComponents()`, as detailed e.g. here: https://stackoverflow.com/questions/31472829/change-sheet-code-name – eirikdaude Nov 26 '20 at 11:20
  • Additionally it doesn't automatically take the name "Sheet" then the next unused number in the previously created CodeNames, if you for example copy a sheet with a codename different than Sheet#, it will take that worksheet's codename followed by the next unassigned number. Overall good answer except for these nitpicks though :-) – eirikdaude Nov 26 '20 at 11:23
5

You can use sheet codenames directly in your code as if they were declared variables:

Sub UsingSheetCodeName()
    With Sheet1   
       .[a1] = Sheet1.Name
    End With
End Sub
Mark Fitzgerald
  • 3,048
  • 3
  • 24
  • 29
3

There are 3 different properties which could be used to refer to a worksheet:

  • .Name as Worksheets("SomeNameHere") in Worksheets("SomeNameHere").Range("A1")
  • .Index as Worksheets(2) in Worksheets(2).Range("A1")
  • .CodeName as Sheet3 in Sheet3.Range("A1")

To see the difference, run the code below and take a look at the immediate window 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

If the Name and the CodeName of the worksheet are not changed, they would be the same.

  • CodeName:

enter image description here

  • Name:

enter image description here

Vityata
  • 42,633
  • 8
  • 55
  • 100
1

CodeName is actually read-write at run-time when accessing the property trough 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"
-1
Codename.select

DataImport(sheet1)

note DataImport is the "codename" which I gave it in the property window of the VBA Editor and the name in brackets is the name that appears on the Tab.

ergo

DataImport.select selects the sheet by codename in VBA

sbgib
  • 5,580
  • 3
  • 19
  • 26