Você está na página 1de 11

Pressure Vessel Engineering Ltd.

provides: ASME Vessel Code Calculations - Finite Element


Analysis (FEA) - Solid Modeling / Drafting - Canadian Registration Number (CRN) Assistance

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.

Excel Names collection


Introduction:
(Read the Excel VBA help file reference: Names Collection Object for more information)
Names can be used in spreadsheets instead of the A1 style references. The results are easier to read, but there are
some catches

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.

Multiple Uses of the same names:


Often an excel workbook has more than one sheet, with the same names repeated. (The original sheet with names
has been copies to make multiple instances of the same name).

2 more copies have been made of sheet 1

Insert/names/paste only shows the first occurrence of each variable name

Excel Names collection Rev 1.doc - Page 2 of 11

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.

Excel Names collection Rev 1.doc - Page 3 of 11

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 in a new book the names have been 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.

More than one name in a cell:


A cell can have more than 1 name. The names are shown alphabetically.

Excel Names collection Rev 1.doc - Page 4 of 11

Cell A1 has names a and b the name a shows in the name box; names are shown in alphabetical order.

Problems with names:


Sometimes the names do not work as expected. If you reference to a value on another sheet, but already have that
name on the sheet you are working on, Excel will use the value on the sheet you are currently on.

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:

Excel Names collection Rev 1.doc - Page 5 of 11

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.

Problems with names (2):


If a cell that contains a name range is deleted, the name is not removed from the names collection; it is left in with a
#ref instead of a location.

Two sheets with duplicate range names a, b and d

List from the names collection

Cell with variable d stored in it is deleted

The names collection keeps the variable name, but sets the location to #ref

Excel Names collection Rev 1.doc - Page 6 of 11

Insert / name / paste list with Sheet 1 active

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:

Excel Names collection Rev 1.doc - Page 7 of 11

Problems with names (3):


Although the DeleteDeadNames routine is useful, it sometimes removes legitimate duplicate names If there are
two occurrences of a name, one legit, the other with a #ref, it sometimes removes the legitimate reference, leaving
the #ref variable in the list! The .delete method cannot be reliably used.
Sub DeleteNames3DoesNotWork()
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, "#REF") Then
Debug.Print strNm, strRefTo, Pointer
ActiveWorkbook.Names(Pointer).Delete
End If
Next Pointer
End Sub
This routine removes the names by their index number. It deletes fewer wrong entries, but still is not reliable for
removal of duplicated names. Even when referred to by their index number, the wrong entry sometimes gets
removed. This removes wrong names about 1/10 as often as the previous 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

Total entries in names collection = 841


Total bad entries = 119
Removed bad entries = 125
Clearly something is going wrong during execution
Sub DeleteNames6DoesNotWork()
Dim n As Name
Dim strNm As String
Dim strRefTo As String
Dim Pointer As Long
Dim Counter As Long
Dim aBadNames() As Long

Debug.Print "Total entries in names collection = ";


ActiveWorkbook.Names.Count
'
Find the bad entries, save by pointer index
For Pointer = ActiveWorkbook.Names.Count To 1 Step -1
strRefTo = ActiveWorkbook.Names(Pointer).RefersTo
If InStr(1, strRefTo, "#REF") Then
Counter = Counter + 1
ReDim Preserve aBadNames(1 To Counter)
aBadNames(Counter) = Pointer
End If
Next Pointer
Debug.Print "Total bad entries = "; Counter
'
Remove the bad names by stored pointer entries
For Pointer = 1 To UBound(aBadNames)
Debug.Print
ActiveWorkbook.Names(aBadNames(Pointer)).Name;
ActiveWorkbook.Names(aBadNames(Pointer)).RefersTo
ActiveWorkbook.Names(aBadNames(Pointer)).Delete
Next Pointer
End Sub
Version 6 above. First time it is run it removes 119 names. The second time 6 names. All six of which have
duplicate use, and the wrong version of which was originally removed. If a different sheet is active during the name
removal, no wrong names are removed. The correct removal of bad names depends on which sheet is active in
the workbook. Wrong names will be removed from the active sheet only.
Workaround: add a blank sheet to the workbook being cleaned. Run the macro. Remove the blank sheet.
Number of wrong names removed = 0. The macro below does this. It also indicates if any good variable names
were removed. Save your file before running this macro! This is the version of the macro that I currently use.
Sub DeleteNames9(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, "#REF") Then
Debug.Print "Bad", strNm, strRefTo, Pointer
ActiveWorkbook.Names(Pointer).Delete
Excel Names collection Rev 1.doc - Page 9 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

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 DeleteNames11(NumPass1)
Call DeleteNames11(NumPass2)
If NumPass2 > 0 Then
Call DeleteNames11(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
Remember: always save your work before running a macro like these!
Laurence Brundrett
Pressure Vessel Engineering Ltd.
Sept 8 2008

Excel Names collection Rev 1.doc - Page 11 of 11

Você também pode gostar