web-dev-qa-db-fra.com

Comment modifier l'étendue de la plage nommée

Lorsque je crée une plage nommée via le gestionnaire de noms, je peux spécifier spécification Workbook ou [worksheet name]. Mais si vous souhaitez ensuite changer de portée, la liste déroulante est grisée. Existe-t-il un moyen, dans le gestionnaire de noms ou, de préférence, dans VBA de modifier l'étendue d'une plage nommée existante?

Par exemple:

  • testName fait référence à 'sheet1'!A1:B2 avec le classeur scope. Comment pourrais-je changer cela en
  • testName fait référence à 'sheet1'!A1:B2 avec la portée de 'sheet1'?
16
Stevil

Vous pouvez télécharger le complément gratuit du gestionnaire de noms développé par Jan Karel Pieterse et moi-même à partir de http://www.decisionmodels.com/downloads.htm Cela permet à de nombreuses opérations de nommer le gestionnaire de noms Excel 2007. ne peut pas gérer, y compris la modification de la portée des noms.

En VBA:

Sub TestName()
Application.Calculation = xlManual
Names("TestName").Delete
Range("Sheet1!$A$1:$B$2").Name = "Sheet1!TestName"
Application.Calculation = xlAutomatic
End Sub
13
Charles Williams

J'ai trouvé la solution! Copiez simplement la feuille avec vos variables nommées. Puis supprimez la feuille d'origine. La feuille copiée aura désormais les mêmes variables nommées, mais avec une portée locale (portée = la feuille copiée). 

Cependant, je ne sais pas comment passer des variables locales aux variables globales.

9
Astrid Marie

Vérifiez ces deux sous-fichiers qui s'inversent et inversez la portée (feuille de calcul en classeur ou inversement) de toutes les plages nommées qui font référence à une plage de la feuille active.

 Option Explicit
'---------------------------------------------------------------------------------------
' Procedure : RescopeNamedRangesToWorkbook
' Author    : JS20'07'11
' Date      : 11/18/2013
' Purpose   : Rescopes the parent of worksheet scoped named ranges to the active workbook
' for each named range with a scope equal to the active sheet in the active workbook.
'---------------------------------------------------------------------------------------

Public Sub RescopeNamedRangesToWorkbook()
Dim wb As Workbook
Dim ws As Worksheet
Dim objName As Name
Dim sWsName As String
Dim sWbName As String
Dim sRefersTo As String
Dim sObjName As String
Set wb = ActiveWorkbook
Set ws = ActiveSheet
sWsName = ws.Name
sWbName = wb.Name

'Loop through names in worksheet.
For Each objName In ws.Names
'Check name is visble.
    If objName.Visible = True Then
'Check name refers to a range on the active sheet.
        If InStr(1, objName.RefersTo, sWsName, vbTextCompare) Then
            sRefersTo = objName.RefersTo
            sObjName = objName.Name
'Check name is scoped to the worksheet.
            If objName.Parent.Name <> sWbName Then
'Delete the current name scoped to worksheet replacing with workbook scoped name.
                sObjName = Mid(sObjName, InStr(1, sObjName, "!") + 1, Len(sObjName))
                objName.Delete
                wb.Names.Add Name:=sObjName, RefersTo:=sRefersTo
            End If
        End If
    End If
Next objName
End Sub
'---------------------------------------------------------------------------------------
' Procedure : RescopeNamedRangesToWorksheet
' Author    : JS20'07'11
' Date      : 11/18/2013
' Purpose   : Rescopes each workbook scoped named range to the specific worksheet to
' which the range refers for each named range that refers to the active worksheet.
'---------------------------------------------------------------------------------------

Public Sub RescopeNamedRangesToWorksheet()
Dim wb As Workbook
Dim ws As Worksheet
Dim objName As Name
Dim sWsName As String
Dim sWbName As String
Dim sRefersTo As String
Dim sObjName As String
Set wb = ActiveWorkbook
Set ws = ActiveSheet
sWsName = ws.Name
sWbName = wb.Name

'Loop through names in worksheet.
For Each objName In wb.Names
'Check name is visble.
    If objName.Visible = True Then
'Check name refers to a range on the active sheet.
        If InStr(1, objName.RefersTo, sWsName, vbTextCompare) Then
            sRefersTo = objName.RefersTo
            sObjName = objName.Name
'Check name is scoped to the workbook.
            If objName.Parent.Name = sWbName Then
'Delete the current name scoped to workbook replacing with worksheet scoped name.
                objName.Delete
                ws.Names.Add Name:=sObjName, RefersTo:=sRefersTo
            End If
        End If
    End If
Next objName
End Sub
7
JS20'07'11

voici comment je fais la promotion de tous les noms de feuilles de calcul en noms globaux. YMMV

For Each wsh In ActiveWorkbook.Worksheets
For Each n In wsh.Names
    ' Get unqualified range name
    Dim s As String
    s = Split(n.Name, "!")(UBound(Split(n.Name, "!")))
    ' Add to "Workbook" scope
    n.RefersToRange.Name = s
    ' Remove from "Worksheet" scope
    Call n.Delete
Next n
Next wsh
3
codeManJones

créez le nouveau nom à partir de zéro et supprimez l'ancien.

2
Dick Kusleika

Une autre méthode consiste à "pirater" le fichier Excel pour 2007 ou une version ultérieure, bien que vous fassiez attention à cela, et à conserver une copie de sauvegarde de l'original:

Commencez par enregistrer la feuille de calcul Excel en tant que fichier .xlsx ou .xlsm (non binaire). renommez le fichier en .Zip, puis décompressez. Accédez au dossier xl de la structure Zip et ouvrez le fichier workbook.xml dans Wordpad ou un éditeur de texte similaire. Les plages nommées se trouvent dans les balises defineName. La portée locale est définie par localSheetId = "x" (les ID de feuille peuvent être trouvés en appuyant sur Alt-F11 dans Excel, avec la feuille de calcul ouverte, pour accéder à la fenêtre VBA, puis en regardant dans le volet Projet). Les plages cachées sont définies par hidden = "1", il suffit donc de supprimer le hidden = "1" pour afficher, par exemple.

Tapez maintenant la structure du dossier en veillant à préserver son intégrité, puis renommez-la en .xlsx ou .xlsm.

Ce n'est probablement pas la meilleure solution si vous devez modifier l'étendue ou masquer/afficher un grand nombre de plages définies, bien que cela fonctionne correctement pour effectuer une ou deux petites modifications.

2
Vaskor Basak

Cela doit encore être affiné, mais cela fonctionne avec toutes les références simples, sans tuer les noms locaux existants.

Type GlobalNamesToLocalNames_Type
   Name As String
   Sheet As String
   Ref As String
End Type

Sub GlobalNamesToLocalNames(Optional Void As Variant)
   Dim List() As GlobalNamesToLocalNames_Type
   Dim Count As Long
   Dim Name As Name
   Dim Dat() As String
   Dim X As Long

   ' count the size
   For Each Name In ActiveWorkbook.Names
      Count = Count + 1
   Next
   ReDim List(Count - 1)
   Count = 0

   ' Collecect all name data
   For Each Name In ActiveWorkbook.Names
      With List(Count)
         ' Pick up only the name
         If InStr(Name.Name, "!") > 0 Then
            Dat = Split(Name.Name, "!")
            .Name = Dat(1)
         Else
            .Name = Name.Name
         End If
         ' pick up the sheet and refer
         Dat = Split(Name.RefersTo, "!")
         .Sheet = Mid(Dat(0), 2)
         .Ref = Dat(1)
         ' make local sheet name
         .Name = .Sheet & "!" & .Name
      End With
      Count = Count + 1
   Next

   ' Delete all names
   For Each Name In ActiveWorkbook.Names
      Name.Delete
   Next

   'rebuild all the names
   For X = 0 To Count - 1
      With List(X)
         If Left(.Ref, 1) <> "#" Then
            ActiveWorkbook.Names.Add Name:=.Name, RefersToLocal:="=" & .Sheet & "!" & .Ref
         End If
      End With
   Next
End Sub
1
Peter

Le code de JS20'07'11 est vraiment incroyable, simple et direct. Une suggestion que je voudrais donner est de mettre un point d'exclamation dans les conditions:

InStr(1, objName.RefersTo, sWsName+"!", vbTextCompare)

Cela empêcherait l'ajout d'un NamedRange dans une feuille incorrecte. Exemple: si le NamedRange fait référence à une feuille nommée Plan11 et que vous avez une autre feuille nommée Plan1, le code peut causer des dégâts lorsque vous ajoutez des plages si vous ne le faites pas t n’utilisez pas le point d’exclamation.

METTRE &AGRAVE; JOUR

Une correction: il est préférable d'utiliser une expression régulière pour évaluer le nom de la feuille. Une fonction simple que vous pouvez utiliser est la suivante (adaptée par http://blog.malcolmp.com/2010/express-expressions-Excel-add-in , activez Microsoft VBScript Regular Expressions 5.5):

Function xMatch(pattern As String, searchText As String, Optional matchIndex As Integer = 1, Optional ignoreCase As Boolean = True) As String
On Error Resume Next
Dim RegEx As New RegExp
RegEx.Global = True
RegEx.MultiLine = True
RegEx.pattern = pattern
RegEx.ignoreCase = ignoreCase
Dim matches As MatchCollection
Set matches = RegEx.Execute(searchText)
Dim i As Integer
i = 1
For Each Match In matches
    If i = matchIndex Then
        xMatch = Match.Value
    End If
    i = i + 1
Next
End Function

Donc, vous pouvez utiliser quelque chose comme ça:

xMatch("'?" +sWsName + "'?" + "!", objName.RefersTo, 1) <> ""

au lieu de

InStr(1, objName.RefersTo, sWsName+"!", vbTextCompare)

Cela couvrira les variations de {Plan1 _ et 'Plan1' (lorsque la plage se rapporte à plusieurs cellules).

CONSEIL: évitez les noms de feuille avec des guillemets simples ('), :).

0
Helio Junior

Pour moi, cela fonctionne que lorsque je crée nouvelle étiquette de nom pour la même plage depuis le Gestionnaire de noms cela me donne la possibilité de changer de portée;) le classeur est fourni par défaut et peut être remplacé feuilles.

0
Yani

Ces réponses ont été utiles pour résoudre un problème similaire tout en essayant de définir une plage nommée avec une étendue Workbook. Le "ah-ha!" pour moi, c’est utiliser la collection de noms qui est relative au classeur entier!partager pour d'autres avec des questions similaires.

' Local / Worksheet only scope
Worksheets("Sheet2").Names.Add Name:="a_test_rng1", RefersTo:=Range("A1:A4")

' Global / Workbook scope
ThisWorkbook.Names.Add Name:="a_test_rng2", RefersTo:=Range("B1:b4") 

Si vous consultez votre liste de noms lorsque la Feuille2 est active, les deux plages sont présentes, mais passez à une autre feuille et "a_test_rng1" n'est pas présent.

Maintenant, je peux créer avec plaisir une plage nommée dans mon code avec la portée que je juge appropriée. Pas besoin de perdre son temps avec le gestionnaire de noms ou un plug-in. 


De plus, le gestionnaire de noms dans Excel Mac 2011 est un gâchis, mais j’ai découvert qu’il n’existait pas d’étiquettes de colonnes vous indiquant ce que vous regardiez lorsque vous consultez votre liste de plages nommées, s’il existe une feuille en regard du nom. , ce nom est limité à feuille de calcul/local. Voir la capture d'écran ci-jointe.

 Excel Mac 2011 Name Manager

Crédit complet à cet article pour avoir assemblé les pièces.

0
Zephyr Mays