计算同一列中相同文本值的标准差

时间:2015-05-31 13:41:45

标签: excel vba excel-vba standard-deviation

我正在尝试在Excel中编写一个宏来计算A列中相同文本的标准差,从而获取B列中的值并在C列中给出结果:

spreadsheet

我是通过将等式UniformGrid放入" aaa"手动完成的。但我需要自动执行此操作,因为我正在执行另一个计算和程序,这些计算和程序由宏完成。这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace MyNamespace
{
    class MyPanel : Panel
    {
        int columns;
        int rows;

        protected override Size MeasureOverride (Size constraint)
        {
            Size childConstraint = constraint;
            double maxChildDesiredWidth = 0.0;
            double maxChildDesiredHeight = 0.0;

            if (InternalChildren.Count > 0)
            {
                for (int i = 0, count = InternalChildren.Count; i < count; ++i)
                {
                    UIElement child = InternalChildren[i];

                    // Measure the child.
                    child.Measure (childConstraint);
                    Size childDesiredSize = child.DesiredSize;

                    if (maxChildDesiredWidth < childDesiredSize.Width)
                    {
                        maxChildDesiredWidth = childDesiredSize.Width;
                    }

                    if (maxChildDesiredHeight < childDesiredSize.Height)
                    {
                        maxChildDesiredHeight = childDesiredSize.Height;
                    }
                }

                columns = (int)(constraint.Width / maxChildDesiredWidth);
                rows = (int)(InternalChildren.Count / columns + 0.5);
            }
            else
            {
                columns = 0;
                rows = 0;
            }

            return new Size ((maxChildDesiredWidth * columns), (maxChildDesiredHeight * rows));
        }

        protected override Size ArrangeOverride (Size arrangeSize)
        {
            Rect childBounds = new Rect (0, 0, arrangeSize.Width / columns, arrangeSize.Height / rows);
            double xStep = childBounds.Width;
            double xBound = arrangeSize.Width - 1.0;

            childBounds.X += 0;

            foreach (UIElement child in InternalChildren)
            {
                child.Arrange (childBounds);

                if (child.Visibility != Visibility.Collapsed)
                {
                    childBounds.X += xStep;
                    if (childBounds.X >= xBound)
                    {
                        childBounds.Y += childBounds.Height;
                        childBounds.X = 0;
                    }
                }
            }

            return arrangeSize;
        }
    }
}

如果有人能给我一个想法或解决方案,那就太好了。上面的代码用于计算相同文本值的总和。有没有办法修改我的代码来计算标准差?

2 个答案:

答案 0 :(得分:2)

我走向了另一个方向并提供了伪STDEV.S.IF,其用途与COUNTIFAVERAGEIF function非常相似。

Function STDEV_S_IF(rAs As Range, rA As Range, rBs As Range)
    Dim a As Long, sFRM As String

    sFRM = "STDEV.s("
    Set rBs = rBs(1).Resize(rAs.Rows.Count, 1)
    For a = 1 To rAs.Rows.Count
        If rAs(a).Value2 = rA.Value2 Then
            sFRM = sFRM & rBs(a).Value2 & Chr(44)
        End If
    Next a

    sFRM = Left(sFRM, Len(sFRM) - 1) & Chr(41)
    STDEV_S_IF = Application.Evaluate(sFRM)
End Function
  

语法:STDEV_S_IF(&lt; criteria range&gt;,&lt; criteria&gt;,&lt; stdev.s values&gt;

在您的样本中,C2中的公式为

=STDEV_S_IF(A$2:A$20, A2, B$2:B$20)

根据需要填写。

STDEV_IF

答案 1 :(得分:1)

这是一个公式和VBA路线,为每组项目提供STDEV.S

图片显示各种范围和结果。我的输入与你的输入相同,但我不小心将它排在一点,所以它们没有对齐。

enter image description here

一些注释

  • ARRAY是您想要的实际答案。 NON-ARRAY稍后展示。
  • 我包含了数据透视表来测试方法的准确性。
  • VBA与作为UDF计算的ARRAY的答案相同,可以在您的VBA中的其他位置使用。
单元格D3中的

公式是使用CTRL + SHIFT + ENTER输入的数组公式。同样的公式在E3没有数组条目。两者都被复制到数据的末尾。

=STDEV.S(IF(B3=$B$3:$B$21,$C$3:$C$21))

由于您似乎需要VBA版本,因此您可以在VBA中使用相同的公式,并将其包装在Application.Evaluate中。这几乎是@Jeeped获得答案的方式,将范围转换为符合标准的值。

VBA代码使用Evaluate处理根据输入作为范围构建的公式字符串。

Public Function STDEV_S_IF(rng_criteria As Range, rng_criterion As Range, rng_values As Range) As Variant

    Dim str_frm As String

    'formula to reproduce
    '=STDEV.S(IF(B3=$B$3:$B$21,$C$3:$C$21))

    str_frm = "STDEV.S(IF(" & _
        rng_criterion.Address & "=" & _
        rng_criteria.Address & "," & _
        rng_values.Address & "))"

    'if you have more than one sheet, be sure it evalutes in the right context
    'or add the sheet name to the references above
    'single sheet works fine with just Application.Evaluate

    'STDEV_S_IF = Application.Evaluate(str_frm)
    STDEV_S_IF = Sheets("Sheet2").Evaluate(str_frm)

End Function

F3中的公式是与上述公式相同的VBA UDF,它作为普通公式输入(尽管作为数组输入不会影响任何内容)并被复制到最后。

=STDEV_S_IF($B$3:$B$21,B3,$C$3:$C$21)

值得注意的是.Evaluate将此正确处理为数组公式。您可以将其与输出中包含的NON-ARRAY列进行比较。我不确定Excel如何以这种方式对待它。之前有a fairly extended conversion about how Evaluate process array formulas and determines the output。这与该对话相关。

为了完整起见,这是对Sub方面的测试。我在一个模块中运行此代码,其中包含Sheet2活动以外的工作表。这强调了将Sheets("Sheets2").Evaluate用于多表工作簿的功能,因为我的Range调用在技术上被认定为不合格。包含控制台输出。

Sub test()

    Debug.Print STDEV_S_IF(Range("B3:B21"), Range("B3"), Range("C3:C21"))
    'correctly returns  206.301357242263

End Sub