В VBA, как перечислить именованные записи диапазона в соответствии с их положением на листе

Я назвал диапазоны, расположенные один под другим на листе.

В событии инициализации пользовательской формы (которое содержит список) я добавляю записи в список, когда каждая запись является именем одного именованного диапазона.

К настоящему времени мне удалось загрузить список с записями в алфавитном порядке именованных диапазонов, поэтому имена, начинающиеся с "а", находятся вверху списка, а "z" - внизу.

Я хочу, чтобы записи были в том порядке, в котором они отображаются на листе, поэтому именованный диапазон, отображаемый ближе к A1, будет отображаться в верхней части списка, а именованный диапазон в A1 будет второй записью и так далее до последней названной диапазон в рабочем листе (внизу рабочего листа), который, конечно, будет последней записью.

Кто-нибудь может найти элегантный способ сделать это?

2 ответа

Попробуй это:

Private Sub UserForm_Initialize()
    Dim rCell As Range
    Dim nLoop As Name

    With CreateObject("scripting.dictionary")
        For Each rCell In ActiveSheet.UsedRange.Resize(, 1).Cells
            For Each nLoop In ThisWorkbook.Names
                If Not Intersect(Range(nLoop.RefersTo), Range(rCell.Address)) Is Nothing Then
                    If Not .Exists(nLoop.Name) Then
                        Me.ListBox1.AddItem nLoop.Name
                        .Add (nLoop.Name), Nothing
                        Exit For
                    End If
                End If
            Next
        Next rCell
    End With

End Sub

Я не уверен, что это элегантное решение, но это простое решение.

В приведенном ниже коде предполагается, что имена диапазонов находятся в ячейках A1, A2, A3 и т. Д. Sheet2 и что список заканчивается пустой ячейкой. Также предполагается, что в столбцах B, C и т. Д. Ничего не нужно. Вам придется корректировать код в соответствии с реальной ситуацией.

Sub GetNameDetails()

  Dim Inx As Integer
  Dim NameCrnt As String
  Dim Pos As Integer
  Dim RangeCrnt As String
  Dim RowCrnt As Integer

  RowCrnt = 1
  With Sheets("Sheet2")
    Do While True
      ' This loop is repeated for every cell in column A until it
      ' encounters a blank cell 
      NameCrnt = .Cells(RowCrnt, 1).Value
      If NameCrnt = "" Then Exit Do
      For Inx = 1 To Names.Count
        ' This matches the names in Sheet 2 with the named ranges.
        ' Names that cannot be found in the Names collection are ignored. 
        If Names(Inx).Name = NameCrnt Then
          RangeCrnt = Names(Inx).RefersTo          ' Extract full address of range 
          RangeCrnt = Mid(RangeCrnt, 2)            ' Discard =
          RangeCrnt = Replace(RangeCrnt, "$", "")  ' Remove $s
          Pos = InStr(RangeCrnt, "!")
          ' Save sheet name
          .Cells(RowCrnt, 2).Value = Mid(RangeCrnt, 1, Pos - 1)
          RangeCrnt = Mid(RangeCrnt, Pos + 1)      ' Discard sheet name
          .Cells(RowCrnt, 3).Value = RangeCrnt     ' Save full address of range
          Pos = InStr(RangeCrnt, ":")
          If Pos <> 0 Then
            RangeCrnt = Mid(RangeCrnt, 1, Pos - 1) ' Discard end of range if any
          End If
          .Cells(RowCrnt, 4).Value = .Range(RangeCrnt).Row
          .Cells(RowCrnt, 5).Value = .Range(RangeCrnt).Column
          Exit For
        End If
      Next
      RowCrnt = RowCrnt + 1
    Loop
  End With
End Sub

В результате получается таблица из пяти столбцов:

Col 1 = Range name  (unchanged)
Col 2 = Sheet name
Col 3 = Range
Col 4 = Top row of range
Col 5 = Left column of range

После сортировки по столбцам 4 и 5 таблица будет в той последовательности, которую вы ищете.

Другие вопросы по тегам