Escolar Documentos
Profissional Documentos
Cultura Documentos
Comment: This article applies to the 2003 and earlier versions of Excel - it has not been
checked against the latest version. This material is provided for educational purposes - use
it at your own risk.
Simple excel spreadsheet with 3 named ranges: a, b and d (the variable c can not be used it defines a column)
Excel stores the name definitions in the names collection.
This VBA routing loops through the names collection
Option Explicit
Sub ListNames()
Dim nms As Variant
For Each nms In ActiveWorkbook.Names
Debug.Print nms.Name;
Debug.Print nms.RefersTo
Next nms
End Sub
The results for the above spreadsheet:
Disclaimer: This document is provided for educational purposes only. Pressure Vessel Engineering
Ltd. is not liable for its use.
The command Insert / names / paste produces a similar list. Note: sometimes the list created this way is missing
variable names found on other sheets in the same workbook.
The List names macro shows the full listing. The names a, b and d have been used 3 times each. Excel tracks
them by including the sheet that they are located on in the stored variable name. So far everything is working well.
If we add another sheet and access the values of a, b and d, the values from sheet 1 will be used the first sheet
to own the names.
When an attempt is made to add a named range a to sheet4, excel refers back to sheet 1 instead. To add a range a
to sheet 4, the sheet needs to be moved into its own workbook, the name added, and then the sheet gets moved back.
If there are links created during this process, then this cannot be done.
Links exist back to the original spreadsheet, the variables a, b and d cannot be added to Sheet 4.
Sheet 4 has been abandoned; a new sheet 5 is created which will have the same three variable names. Sheet 5 is first
moved to a new workbook, and then the names are added.
Sheet 5 has been moved back to the original workbook. The names have been successfully re-used.
Successful re-use of names a, b and d by exporting the sheet before adding the names to the list.
Cell A1 has names a and b the name a shows in the name box; names are shown in alphabetical order.
An attempt has been made to access a on sheet 1. There already is a range name a on the current sheet, so that
value is used instead.
Workaround:
By clicking the formula bar first when accessing the named range, the formula is anchored to the a range name on
sheet1, instead of using the value found on sheet 5, the sheet trying to access the range.
Note: If this method is used to access a variable name that is not duplicated on the current sheet, then an error will
sometimes result the cell needs to be accessed by clicking #2 above without clicking #1 first.
The names collection keeps the variable name, but sets the location to #ref
Insert / name / paste list with Sheet 2 active now the unused variable name shows.
The paste list command is not very useful for removing unused variable names!
This is a typical routine to remove dead names in a workbook. It looks through the names collection to find #ref
refers to, however, the .delete method does not work. It removes the first copy of the range name, not necessarily
the range name with the #ref. When there only is one copy of each variable name then it works. This is typical of
name collection routines found on the internet. Do not use!
Sub DeleteDeadNamesDoesNotWork()
Dim n As Name
Dim strRefersTo As String
'
Loop through the Names collection in this workbook
'
Remove dead names
For Each n In ActiveWorkbook.Names
With n
strRefersTo = UCase(.RefersTo)
If InStr(1, strRefersTo, "#REF") Then
'
Dead cell reference found - offer user a
chance to delete
If MsgBox("Delete " & .Name & " ? " & vbCrLf &
"Refers to " & .RefersTo, vbYesNo + vbQuestion) = vbYes Then
.Delete
End If
End If
End With
Next
End Sub
After running the DeleteDeadNamesDoesNotWork routine:
...missing code...
Debug.Print "Total bad entries = "; Counter
Counter = 0
For Pointer = ActiveWorkbook.Names.Count To 1 Step -1
strNm = ActiveWorkbook.Names(Pointer).Name
strRefTo = ActiveWorkbook.Names(Pointer).RefersTo
If InStr(1, strRefTo, "#REF") Then
ActiveWorkbook.Names(Pointer).Delete
Counter = Counter + 1
End If
Next Pointer
Debug.Print "Removed bad entries = "; Counter
End Sub
A slight variation on the above macro. Results:
Excel Names collection Rev 1.doc - Page 8 of 11
NumberDeleted = NumberDeleted + 1
End If
Next Pointer
End Sub
Sub DeleteNames10Works()
Dim strBlankSheetName As String
Dim NumPass1 As Long
Dim NumPass2 As Long
Dim NumPass3 As Long
'
Insert active blank sheet
'
Prevents wrong duplicated names from being deleted
ActiveWorkbook.Sheets.Add
strBlankSheetName = ActiveWorkbook.ActiveSheet.Name
Call DeleteNames9(NumPass1)
Call DeleteNames9(NumPass2)
If NumPass2 > 0 Then
Call DeleteNames9(NumPass3)
MsgBox "WARNING - the program has deleted " & NumPass2 +
NumPass3 & " valid names"
Else
MsgBox "The program has sucessfully deleted " & NumPass1
& " bad names"
End If
'
Delete blank sheet
Sheets(strBlankSheetName).Select
Application.DisplayAlerts = False
ActiveWindow.SelectedSheets.Delete
Application.DisplayAlerts = True
End Sub
Similarly, this is the routine I use to remove dead links from sheets:
Sub DeleteNames11(NumberDeleted As Long)
Dim n As Name
Dim strNm As String
Dim strRefTo As String
Dim pointer As Long
Debug.Print "Total entries in names collection = ";
ActiveWorkbook.Names.Count
For pointer = ActiveWorkbook.Names.Count To 1 Step -1
strNm = ActiveWorkbook.Names(pointer).Name
strRefTo = ActiveWorkbook.Names(pointer).RefersTo
If InStr(1, strRefTo, "[") Then
Debug.Print "Bad", strNm, strRefTo, pointer
ActiveWorkbook.Names(pointer).Delete
NumberDeleted = NumberDeleted + 1
End If
Next pointer
End Sub
Sub DeleteLinks12()
Dim strBlankSheetName As String
Dim NumPass1 As Long
Excel Names collection Rev 1.doc - Page 10 of 11