Как преобразовать формулу Excel = STDEV.S (ЕСЛИ (ЧАСТОТА (диапазон, диапазон), диапазон)) в код VBA? - PullRequest
0 голосов
/ 02 марта 2020

У меня есть формула Excel, которая работает с уже существующим диапазоном данных.

Формула Excel: =STDEV.S(IF(FREQUENCY(range,range),range)), где «диапазон» - это вышеупомянутый диапазон данных.

Моя цель - преобразовать эту формулу в код VBA.

Следующий код является моей попыткой преобразовать формулу в VBA, а также мою визуализацию процесса, чтобы попытаться понять, почему он не дает того же результата:

Private Sub CommandButton1_Click()

    Dim diffArray() As Variant
    Dim i As Integer
    Dim x As Integer
    Dim array1() As Variant, size As Integer, j As Integer
    Dim freqArray1() As Variant
    Dim freqArray2() As Variant, size2 As Integer, j2 As Integer

    'assigns the data values to array1
    size = 0
    j = 0
    ReDim array1(size)
    For i = 3 To 15
        size = size + 1
        ReDim Preserve array1(size)
        array1(j) = Cells(i, 2)
        j = j + 1
    Next i
    Cells(20, 2).Value = UBound(array1)
    Cells(21, 2).Value = LBound(array1)
    If UBound(array1) > 1 Then Cells(19, 2).Value = WorksheetFunction.StDev_S(array1)

    'setting freqArray1 to frequency(array1, array1)
    freqArray1 = WorksheetFunction.Frequency(array1, array1)
    Cells(20, 3).Value = UBound(freqArray1)
    Cells(21, 3).Value = LBound(freqArray1)
    For i = LBound(freqArray1) To (UBound(freqArray1))
        Cells(2 + LBound(freqArray1) + i, 3).Value = freqArray1(i, 1)
    Next i
    If UBound(freqArray1) > 1 Then Cells(19, 3).Value = WorksheetFunction.StDev_S(freqArray1)

    'setting freqArray2 to if(frequency(array1, array1), array1)
    size2 = 0
    j2 = 0
    ReDim freqArray2(size2)
    For i = LBound(freqArray1) To (UBound(freqArray1))
        If freqArray1(i, 1) Then
            size2 = size2 + 1
            ReDim Preserve freqArray2(size2)
            freqArray2(j2) = freqArray1(i, 1)
            j2 = j2 + 1
        End If
    Next i
    Cells(20, 4).Value = UBound(freqArray2)
    Cells(21, 4).Value = LBound(freqArray2)
    For i = (LBound(freqArray2)) To UBound(freqArray2)
        Cells(2 + LBound(freqArray2) + i, 4).Value = freqArray2(i)
    Next i

    'takes the standard deviation of if(frequency(array1, array1), array1)
    If UBound(freqArray2) > 1 Then Cells(19, 4).Value = WorksheetFunction.StDev_S(freqArray2)

End Sub

enter image description here

Используемые значения данных находятся в столбце оранжевых ячеек B (массив1). Массив частоты (array1, array1) находится в столбце желтых ячеек C. Массив if (частота (array1, array1), array1) находится в столбце D зеленых клеток. Цель состоит в том, чтобы значения в двух синих ячейках (B18 и D19) были одинаковыми.

Я не понимаю двух вещей:

  1. Почему значения в синих ячейках (B18 и D19) не совпадают?
  2. Почему изменяются индексы массивов? Один начинается с «0», следующий начинается с «1», а последний начинается с «-1»?

1 Ответ

1 голос
/ 02 марта 2020

используйте словарь для создания уникального списка и используйте его в StDev_S

Private Sub CommandButton1_Click()

    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")

    Dim rngArray As Variant
    rngArray = ActiveSheet.Range("B3:B15")

    Dim i As Long
    For i = LBound(rngArray, 1) To UBound(rngArray, 1)
        On Error Resume Next
            dict.Add rngArray(i, 1), rngArray(i, 1)
        On Error Resume Next
    Next i

    If dict.Count > 0 Then
        Dim unqArr As Variant
        ReDim unqArr(1 To dict.Count) As Variant

        i = 1

        Dim key As Variant
        For Each key In dict.Keys
            unqArr(i) = key
            i = i + 1
        Next key

        ActiveSheet.Cells(19, 4).Value = Application.WorksheetFunction.StDev_S(unqArr)
    End If


End Sub

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...