简体   繁体   English

VBA-具有函数和循环的数组计算

[英]VBA - Array calculation with Function and Loops

在此处输入图片说明 I am writing a program in VBA that is acting as a Workforce Management Tool. 我正在VBA中编写一个充当劳动力管理工具的程序。 In this particular problem I am trying to take a set of numbers (widgets produced and widget errors) and create a total reject rate --> (Widgets ErrorsA / (Widgets ProducedA + Widget ErrorsA). Each row needs to have it's own reject rate pasted at the end of the row. 在这个特定的问题中,我尝试获取一组数字(产生的小部件和小部件错误)并创建总拒绝率->(小部件错误A /(小部件产生的A +小部件错误A)。每一行都必须具有自己的拒绝率粘贴在行的末尾。

The data is set up like this: ProductA ErrorA ProductB ErrorB | 数据设置如下:ProductA ErrorA ProductB ErrorB | RejectRate date1 Name1 Team1 4 2 4 0 0.16% 拒绝日期1名称1团队1 4 2 4 0 0.16%

I need to be able to do this calculation through automation. 我需要能够通过自动化进行此计算。 I have very very basic knowledge with Arrays and with help from another post was able to create 1 array before which is in my code. 我对Arrays有非常非常的基础的知识,并且在另一篇文章的帮助下能够在我的代码中创建1个数组。 Working off of that however I have been unsuccessful in figuring out how to store these variables in order to do the necessary calculations. 但是,要解决这个问题,我一直没能弄清楚如何存储这些变量以进行必要的计算。

Could somebody help please? 有人可以帮忙吗?

The steps seem to be: Hold the first production number in a variable x, hold the second production number in a variable y and run the equation (y/(x+y). Hold the answer in an array. Then step 2 over to the next pair and repeat. At the end, average all the numbers that are stored in the array and paste it at the end of the row. 步骤似乎是:将第一个产品编号保存在变量x中,将第二个产品编号保存在变量y中,然后运行公式(y /(x + y)。将答案保存在数组中。然后将步骤2移至最后,对数组中存储的所有数字求平均值,然后将其粘贴到行的末尾。

Do this for each row. 对每一行执行此操作。

We also need to keep in mind that mathematically we cannot divide by zero, and in these numbers there will be zeros in the production variable to contend with (the rejects being zero should not be an issue). 我们还需要记住,从数学上讲,我们不能将其除以零,并且在这些数字中,生产变量中将存在零以应对(拒绝数为零不应该成为问题)。

Here is my code. 这是我的代码。 I have made a note to the area that I am stuck on. 我已经记下了我所卡住的区域。 Thanks! 谢谢!

Sub InsertColumnsAndFormulasUntilEndOfProductivityTable_MakeProductivityNumbers()

With Sheet6
    Set EmployeesRange = .Range("A1", .Range("B1").End(xlDown))
End With

With Sheet1
    Set ActivityRange = .Range("A1", .Range("B1").End(xlDown))
End With

'insert column (For i = 1...) and then vlookup (FormulaRange1.Formula...)
With Sheet4
    y = .Cells(.Rows.Count, 1).End(xlUp).Row
    Dim j As Long
    x = (.Cells(1, .Columns.Count).End(xlToLeft).Column) * 2
    Startrow = 2
    StartColumn = 2
    j = ActiveCell.Row


    For i = 1 + StartColumn To (x + 1) Step 2
        .Columns(i).EntireColumn.Insert
        Set FormulaRange1 = .Range(.Cells(Startrow, i), .Cells(y, i))

           If i = 3 Then
                'insert title for usernames and then vlookup
                Cells(Startrow - 1, i).Value = Cells(Startrow - 1, i - 1).Value & "'s Team"
                FormulaRange1.FormulaR1C1 = "=VLookup(R[0]C[-1],'" & EmployeesRange.Parent.Name & "'!" & EmployeesRange.Address(1, 1, xlR1C1) & ", 2, False)"

            ElseIf i <= x Then
                'insert title for activities and then vlookup lock row 1
                Cells(Startrow - 1, i).Value = Cells(Startrow - 1, i - 1).Value & " Cycle Time"
                FormulaRange1.FormulaR1C1 = "=VLookup(R1C[-1],'" & ActivityRange.Parent.Name & "'!" & ActivityRange.Address(1, 1, xlR1C1) & ", 2, False)"
            Else
                'Sum totals of productivity per person per day
                Cells(Startrow - 1, i - 1).Value = "Totals"
                For j = 2 To y
                Set dataRange2 = .Range(.Cells(j, StartColumn + 2), .Cells(j, i))
                Cells(j, i - 1).Value = CalcProductivity(dataRange2)
                Next

           End If
    Next
    'THIS IS WHERE PROBLEMS START
                i = x + 1
                Cells(Startrow - 1, i).Value = "Reject Rates"
                For j = 2 To y
                Set dataRange2 = .Range(.Cells(j, StartColumn + 2), .Cells(j, i))
                Cells(j, i + 1).Value = RejectRates(dataRange2)
                Next






End With
End Sub

Public Function RejectRates(dataRange As Range) As Double

    Dim dataArray As Variant
    Dim i As Long, t As Long
    Dim runningSum2 As Double


    dataArray = dataRange

    runningSum = 0#

    For i = 1 To UBound(dataArray, 2) Step 4
        runningSum2 = runningSum2 + (dataArray(1, i + 3) / (dataArray(1, i + 1) + dataArray(1, i + 3)))
    Next
    RejectRates = runningSum2

End Function


Public Function CalcProductivity(dataRange As Range) As Double
    '--- input range is 'n' pairs of activity,cycle data.
    '    productivity is calculated by the sum of all activity * cycle pairs
    Dim dataArray As Variant
    Dim i As Long, t As Long
    Dim runningSum As Double


    dataArray = dataRange     'copy to memory array for speed

    runningSum = 0#

    For i = 1 To UBound(dataArray, 2) Step 2
        runningSum = runningSum + (dataArray(1, i) * dataArray(1, i + 1))
    Next
    CalcProductivity = runningSum

End Function

I'm not entirely sure I understand what you're doing, but I think you want a running average reject rate going down the rows? 我不能完全确定我了解您的操作,但是我想您希望运行的平均拒绝率下降吗?

If this is right, then you could use a formula to do this 如果这是正确的,那么您可以使用公式来执行此操作

Assuming Product A count in col A, errorA in col B, Product B in col C, Error B in col D Running Average reject rate for prod A in col E would be 假设第A行的产品A计数,第B行的errorA,第C行的产品B,第D行的错误B在运行E中产品A的平均拒绝率将为

=SUM($B$2:B2)/(SUM($A$2:$B2))

and then simply copy this formula down. 然后简单地将该公式复制下来。

Note here, that I've locked the first cells, but as you copy down, the range will get larger, so you end up with a running average. 请注意,我已经锁定了第一个单元格,但是当您向下复制时,范围会变大,因此最终得到的是移动平均值。

Sadly, though, I'm still guessing that this is what you're looking for... 可悲的是,我仍在猜测这就是您要寻找的东西...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM