Excel перечисляет именованный диапазон на листе и получает значение - PullRequest
3 голосов
/ 27 октября 2010

Как получить список именованных диапазонов, существующих в конкретной рабочей таблице, которые начинаются с определенной строки (например, весь именованный диапазон, начинающийся с итогового значения) и получающих значение?Я пытаюсь сделать Sub Total и Grand Total стоимости проживания на основе даты.Я назначу уникальное имя для каждой промежуточной суммы на основе группы дат.Затем у меня есть кнопка, которую нужно нажать, когда она завершит вычисление итоговой суммы на основе именованного диапазона, который я назначил уникально для каждой промежуточной суммы.

Ниже приведен код, который я написал для общего итога:

Sub btnTotal()

    Dim Total, LastRowNo As Long

    LastRowNo = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count

    Total = 0

    For Each N In ActiveWorkbook.Names
        Total = Total + IntFlight.Range(N.Name).Value
    Next N

    IntFlight.Range("$P" & LastRowNo).Select
    Selection.NumberFormat = "$* #,##0.00;$* (#,##0.00);$* ""-""??;@"
    With Selection
        .Font.Bold = True
    End With

    ActiveCell.FormulaR1C1 = Total

End Sub

Примечание: IntFlight из "Total = Total + IntFlight.Range (N.Name) .Value" являетсяname of my worksheet.

Единственная проблема с приведенным выше кодом, это то, что все именованные диапазоны существуют в книге.Мне просто нужно найти именованный диапазон, существующий в одном конкретном листе, который начинается с заданной строки и номера строки (total26: означает промежуточный итог из строки 26), а затем захватывает значение, которое будет суммировано как общий итог.

Есть идеи, как это сделать?Потратил 2 дня, чтобы найти ответ.

Спасибо огромное заранее.

РЕДАКТИРОВАТЬ 1 (Решение, предоставленное Чарльзом Уильямсом с помощью Велисария):

Вот что я сделал с кодом Чарльза Уильямса:

Option Explicit
Option Compare Text

Sub btnIntFlightsGrandTotal()

    Dim Total, LastRowNo As Long
    LastRowNo = FindLastRowNo("International Flights")

    Dim oNM As Name
    Dim oSht As Worksheet
    Dim strStartString As String

    strStartString = "IntFlightsTotal"
    Set oSht = Worksheets("International Flights")

    For Each oNM In ActiveWorkbook.Names
        If oNM.Name Like strStartString & "*" Then
            If IsNameRefertoSheet(oSht, oNM) Then
                Total = Total + Worksheets("International Flights").Range(oNM.Name).Value
            End If
        End If
    Next oNM

    IntFlights.Range("$P" & LastRowNo).Select
    Selection.NumberFormat = "$* #,##0.00;$* (#,##0.00);$* ""-""??;@"
    With Selection
        .Font.Bold = True
    End With

    ActiveCell.FormulaR1C1 = Total

End Sub

Function FindLastRowNo(SheetName As String) As Long

    Dim oSheet As Worksheet
    Set oSheet = Worksheets(SheetName)

    FindLastRowNo = oSheet.UsedRange.Row + oSheet.UsedRange.Rows.Count

End Function

Спасибо всем за помощь.Теперь мне нужно придумать собственную версию этого скрипта.

Ответы [ 2 ]

4 голосов
/ 27 октября 2010

Вот некоторый код, который проверяет, начинается ли Заданное имя со строки и ссылается на диапазон в пределах используемого диапазона данного рабочего листа и рабочей книги.

Option Explicit
Option Compare Text
Sub FindNames()
    Dim oNM As Name
    Dim oSht As Worksheet
    Dim strStartString As String

    strStartString = "Total"
    Set oSht = Worksheets("TestSheet")

    For Each oNM In ActiveWorkbook.Names
        If oNM.Name Like strStartString & "*" Then
            If IsNameRefertoSheet(oSht, oNM) Then

                MsgBox oNM.Name
            End If
        End If
    Next oNM
End Sub

Function IsNameRefertoSheet(oSht As Worksheet, oNM As Name) As Boolean
    Dim oSheetRange As Range

    IsNameRefertoSheet = False
    On Error GoTo GoExit

    If Not oSht Is Nothing Then
        If Range(oNM.Name).Parent.Name = oSht.Name And _
           Range(oNM.Name).Parent.Parent.Name = oSht.Parent.Name Then
            Set oSheetRange = oSht.Range("A1").Resize(oSht.UsedRange.Row + oSht.UsedRange.Rows.Count - 1, oSht.UsedRange.Column + oSht.UsedRange.Columns.Count - 1)
            If Not Intersect(Range(oNM.Name), oSheetRange) Is Nothing Then IsNameRefertoSheet = True
            Set oSheetRange = Nothing
        End If
    End If

    Exit Function
GoExit:
End Function
0 голосов
/ 27 октября 2010

Следующая функция выведет все имена и их итоги в вашу рабочую книгу.

Я думаю, что это основной блок, необходимый для запуска вашего кода.

Sub btnTotal()

    For Each N In ActiveWorkbook.Names
           MsgBox N.Name + " " + CStr(Application.WorksheetFunction.Sum(Range(N)))
    Next N
End Sub

Редактировать

Отвечая на ваш комментарий:

Определите ваши имена следующим образом:

alt text

Тогда (и только тогда) работает следующий код:

Sub btnTotal()

  For Each N In ActiveSheet.Names
     If (InStr(N.Name, "!Total") <> 0) Then
         MsgBox N.Name + " " + CStr(Application.WorksheetFunction.Sum(Range(N)))
     End If
  Next N
End Sub

Если вы неправильно определяете область имен, вам потребуется много дополнительной работы в вашем коде.

Редактировать Поскольку вы забыли упомянуть, что вы все еще работаете с Excel 2003, здесь вы найдете надстройку для управления определением имен в этой версии.См. Крышку экрана ниже

alt text

HTH

...