Excel VBA: # ЗНАЧЕНИЕ! Ошибка с некоторыми выбранными диапазонами - PullRequest
0 голосов
/ 26 июня 2018

Привет, в последнее время я изучал Excel VBA и макросы для забавы, но я столкнулся с проблемой с тренировочным упражнением, которое я прохожу ... У меня есть функция, которая начала создавать #VALUE! ошибка с некоторыми выбранными диапазонами, и я немного запутался, как это исправить. Функция выполняет различные вычисления в зависимости от того, какая ячейка заполняется автоматически. Функция ниже:

Function CalculateStuff(myRange As Range) As Double
   Application.Volatile

   Dim numRows As Long
   numRows = myRange.Rows.Count

   Dim whatColumn As Long
   whatColumn = Application.Caller.Column - myRange.Column

   Dim i As Long
   Dim thing As Double
   Dim mainThing As Double

   Select Case whatColumn
      Case 0
         CalculateStuff = WorksheetFunction.Sum(myRange.Columns(1))
      Case 1
         CalculateStuff = WorksheetFunction.SumProduct(myRange.Columns(1), myRange.Columns(2))
      Case 2
         CalculateStuff = WorksheetFunction.SumProduct(myRange.Columns(1), myRange.Columns(3)) / WorksheetFunction.Sum(myRange.Columns(1))
      Case 3
         CalculateStuff = WorksheetFunction.SumSq(myRange.Columns(4))
      Case 4
         For i = 1 To numRows
            thing = myRange(i, 1) * WorksheetFunction.SumSq(myRange(i, 3), myRange(i, 5))
            mainThing = mainThing + thing
         Next i
         CalculateStuff = mainThing
    End Select

End Function

И затем я использую его в подпрограмме для заполнения формулы активной ячейки и автозаполнения справа от активной ячейки. Подпрограмма выглядит следующим образом:

Sub RunCalculateStuff()
   Dim initialRange As Range
   Set initialRange = Application.InputBox("Please select the cells in the first column you would like to use...", Type:=8)

   Dim finalRange As Range
   Dim i As Long
   i = 0
   For Each initialCell In initialRange
      If i = 0 Then
         Set finalRange = ActiveSheet.Range(initialCell, initialCell.Offset(0, 4))
         i = i + 1
      Else
         Set finalRange = Application.Union(finalRange, ActiveSheet.Range(initialCell, initialCell.Offset(0, 4)))
         i = i + 1
      End If
   Next

   ActiveCell.Formula = "=CalculateStuff(" + finalRange.Address + ")"

   ActiveCell.AutoFill Destination:=ActiveSheet.Range(ActiveCell, ActiveCell.Offset(0, 4))
End Sub

Подпрограмма работает, позволяя пользователю выбрать ячейки в первом столбце, который он хотел бы использовать, затем проходит по этим ячейкам и захватывает ячейки со смещением (0, 4) и добавляет этот диапазон к общему количеству. спектр. Этот диапазон затем подается на эту функцию, и он идет.

Вот где # ЗНАЧЕНИЕ! возникает ошибка ... Это происходит только тогда, когда выбранные ячейки не являются последовательными ... Под этим я подразумеваю, если я выбираю диапазон AA1: AA4 с начальным полем get, он работает просто отлично. Если я выбираю диапазон AA1, AA2, AA3, AA4 по отдельности, он работает просто отлично. Но если я выберу диапазон AA1, AA3, я получу # ЗНАЧЕНИЕ! Ошибка. У меня такое ощущение, что это как-то связано с пропуском строк, но я действительно не понимаю, почему, поскольку я делаю Союз в своем собственном диапазоне. Кроме того, происходит сбой, когда я просто пытаюсь суммировать первый столбец диапазона в самом первом вычислении, а затем - в остальных. Скриншоты ниже, что я имею в виду.

Рабочий диапазон:

Working Range

Сломанный диапазон:

Broken Range

Заранее спасибо за помощь! Я действительно ценю это.

1 Ответ

0 голосов
/ 27 июня 2018

Мне показалось, что это работает. Публикация на случай, если вам не повезло, или если вам нужно вдохновение. Обратите внимание, что я не проверял ошибки, чтобы убедиться, что все элементы вашего ввода являются диапазонами.

Function CalculateStuff2(ParamArray Rngs()) As Double

    Dim i As Integer
    Dim col As Long
    Dim tmpRng As Range
    Dim tmpDbl As Double
    Dim divisor As Double
    Dim IsCase2 As Boolean
    Dim numRows As Long, r As Long

    For i = LBound(Rngs()) To UBound(Rngs())
        Set tmpRng = Rngs(i)
        col = Application.Caller.Column - tmpRng.Column
        numRows = tmpRng.Rows.Count

        Select Case col
            Case 0
                tmpDbl = tmpDbl + WorksheetFunction.Sum(tmpRng.Columns(1))
            Case 1
                tmpDbl = tmpDbl + WorksheetFunction.SumProduct(tmpRng.Columns(1), tmpRng.Columns(2))
            Case 2
                IsCase2 = True
                tmpDbl = tmpDbl + WorksheetFunction.SumProduct(tmpRng.Columns(1), tmpRng.Columns(3))
                divisor = divisor + WorksheetFunction.Sum(tmpRng.Columns(1))
            Case 3
                tmpDbl = tmpDbl + WorksheetFunction.SumSq(tmpRng.Columns(4))
            Case 4
                For r = 1 To numRows
                    tmpDbl = tmpDbl + tmpRng(r, 1) * WorksheetFunction.SumSq(tmpRng(r, 3), tmpRng(r, 5))
                Next r
        End Select
    Next i

    If IsCase2 Then
        CalculateStuff2 = tmpDbl / divisor
    Else
        CalculateStuff2 = tmpDbl
    End If
End Function
...