Различные результаты для простых операций, выполненных с диапазонами или массивами - PullRequest
0 голосов
/ 29 ноября 2018

Я работаю с VBA в течение очень долгого времени, и у меня есть достаточно опыта с этим.Тем не менее, иногда это все равно поражало его причудливостью ... Чтобы создать файл с некоторыми доступными функциями для всех моих коллег по работе, я решил делать все расчеты по сценарию.Для этого я заполняю массив данными double:

Dim DT01() As Double: ReDim DT01(1 To N03) As Double
Dim R As Long: R = 1: Dim N As Long: Dim P As Double
For x = 1 To N01
    N = SH01.Cells(x + 4, 15).Value: P = SH01.Cells(x + 4, 14).Value
    For y = 1 To N: DT01(R) = P: R = R + 1: Next y
Next x

Массив DT01 довольно длинный (N03 = 495258), и предыдущая подпрограмма заполняет массив так, как я планировал.Я даже сделал следующее:

For x = 1 To 495258
    SH01.cells(x, 1).FormulaR1C1 = DT01(x)
Next x

, чтобы проверить, не допустил ли я ошибку в скрипте для заполнения массива.Этот фрагмент кода правильно записывает первый столбец листа SH01 с правильными значениями массива.

Если я вычислю сумму столбца, я получу 292547224.4, что является правильным значением.Однако, если я использую Application.Sum(DT01) на VBA, я получу 1535172.8.Когда я увидел это, я попытался рассчитать другие вещи, и результаты всегда были разными:

'On Excel:
    =AVERAGE(A1:A495258) = 598,6
'On VBA:
    Application.Average(DT01) = 42.1

'On Excel:
    =MAX(A1:A495258) = 3622.7
'On VBA:
    Application.Max(DT01) = 186.8    

'On Excel:
    =COUNT(A1:A495258) = 495258
'On VBA:
    Application.Count(DT01) = 36506

Когда я увидел последний результат, я сразу понял, что должен был спросить кого-то об этом ... Кто-нибудь знаетчто тут происходит??

ОБНОВЛЕНИЕ:

Я пытался вычислить сумму массива с loop через все его термины:

Dim SIGMA As Double: SIGMA = 0
For x = 1 To UBound(DT01)
    SIGMA = SIGMA + DT01(x)
Next x

и яполучил правильный результат (292547224.4), так почему я до сих пор получил 1535172.8 с Application.Sum(DT01)?

1 Ответ

0 голосов
/ 29 ноября 2018

Это не идеальный ответ, поэтому кто-то может проявить себя приличной документацией.Я считаю, что SUM для массива в VBA работает только до длины 36506 (начиная с 1).

Однако вы можете записать массив значений в диапазон, а затем передать эту ссылку на диапазон в Application.Sum и получитьправильные значения.

Option Explicit
Public Sub test()
    Dim rng As Range, c As Range, i As Long
    Set rng = Range("A1:A495258") 'A1 has value 1, A2 has 2 etc.

    Debug.Print "Application.Sum(rng) " & Application.Sum(rng)   '<==  122640490911
    Debug.Print " Application.Sum(Application.Transpose(rng.Value)) " & Application.Sum(Application.Transpose(rng.Value))   '<== 666362271

    Dim arr3()
    ReDim arr3(1 To 495258)
    For Each c In rng
        i = i + 1
        arr3(i) = c.Value
    Next

    Debug.Print " Application.Sum(arr3) with  arr3(1 To 495258) " & Application.Sum(arr3)
    Debug.Print "Application.WorksheetFunction.Sum(arr3) " & Application.WorksheetFunction.Sum(arr3)
End Sub

Или напишите свою собственную функцию 1d sum:

Option Explicit

Public Sub test()
    Dim arr3(), c As Range, rng As Range, i As Long
    Set rng = Range("A1:A495258")
    ReDim arr3(1 To 495258)
    For Each c In rng
        i = i + 1
        arr3(i) = c.Value
    Next
    Debug.Print SumArray(arr3)
End Sub

Public Function SumArray(ByVal arr As Variant) As Variant ' double
    Dim i As Long
    For i = LBound(arr, 1) To UBound(arr, 1)
        SumArray = SumArray + arr(i)
    Next
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...