【问题标题】:Product Array with loops带循环的产品数组
【发布时间】:2016-04-21 08:43:31
【问题描述】:

我正在构建一个电子表格,并试图获得每位员工每天的总生产力。等式很简单——>(活动 1 * 循环时间 1)+(活动 2 * 循环时间 2)..... 我有 x 数量的列(它们每次都会改变)和 y 数量的行(每天都在增长)。数据示例如下:

日期 |姓名 |第一幕| CT 1|第二幕| CT 2|生产力

2016 年 1 月 15 日 |乔纳森 | 20 | 2 | 10 | 1.5 | .....

2016 年 1 月 14 日 |比利 | 19 | 2 | 10 | 1.5 | .....

我怎样才能将 (act 1 * Ct1) + (Act 2 * Ct2) 的方程自动化到第 n 个,保持一切动态?

我觉得我需要将活动存储在一个数组中,将周期时间存储在另一个数组中,然后将这两个数组相乘。我不确定如何做到这一点,因为我对数组非常陌生,对 VBA 非常熟悉。我一直在考虑其他方法来做到这一点,但一直没有想出任何方法。

有人可以帮助我吗?完整的解释也将不胜感激。 :)

    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
    x = (.Cells(1, .Columns.Count).End(xlToLeft).Column) * 2
    Startrow = 2
    StartColumn = 2


    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"

                'THIS IS WHERE THE PRODUCTIVITY EQUATION/LOOP NEEDS TO GO!...

           End If
    Next




End With
End Sub

【问题讨论】:

  • 希望大家可以试试表格格式excel-easy.com/data-analysis/tables.html
  • 嗨 Linga,我正在尝试在 VBA 中执行所有操作 - 您的链接建议手动构建表格...我说的对吗?我也想过用复制和粘贴循环构建一个表格,但我认为有更好的方法来处理数组。 :)

标签: arrays excel vba loops


【解决方案1】:
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
                'the loop is for each row, to ensure a productivity number per person
                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




End With
End Sub

'函数求生产力数(row1*column1)+(row2*column2)...

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

【讨论】:

    【解决方案2】:

    我的建议是创建一个用户定义函数 (UDF),您可以在数据末尾输入该函数。下面的函数定义了单日/用户的数据范围,即单行。快速简单。

    我的测试数据是这样设置的:

    在“生产力”列中,每个单元格都有公式:

    =CalcProductivity(C2:J2)

    UDF 在 VBA 模块中定义如下:

    Option Explicit
    
    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, j 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 i
        CalcProductivity = runningSum
    End Function
    

    【讨论】:

    • 嗨@PeterT,感谢您的建议。它似乎对我不起作用。老实说,我有点失落。也许如果我能得到一点澄清,我可以尝试改变一些事情以使其发挥作用。 runningSum 中的# 代表什么?此外,我不理解循环中的 runningSum 方程 - 似乎是:取这一行中的第二列并将其添加到 dataArray(这是 i 的函数)[这对我来说很有意义]......和然后将该数字乘以偏移一个 [***dataArray(1, i +1)] 的数据数组。但是我们是否持有第二个 dataArray?
    • 顺便说一句,这就是我将它输入我的 vba 编辑器的方式......也许我做错了? Else Cells(Startrow - 1, i - 1).Value = "Productivity" FormulaRange1.Offset(0, -1).FormulaR1C1 = "=CalcProductivity(dataRange)" End If
    • runningSum 赋值中的# 是VBA 表示双精度浮点数的方式。如果您输入runningSum = 0.0,VBA 编辑器会将其更改为runningSum = 0#。该等式将 Activity 值 dataArray(1,i) 乘以 Cycle 值 `dataArray(1,i+1) 并将其添加到先前生产力值的总和中。因为循环步长为 2,Activity 值将始终为 (i),Cycle 值将始终为 (i+1)。
    • 我建议的解决方案绕过了您原始帖子中列出的所有代码。如果您按照上述方式复制/粘贴CalcProductivity 函数,则在与=CalcProductivity(&lt;yourstartingcell&gt;:&lt;yourendingcell&gt;) 中的数据类型位于同一行的单元格中,它会用您的总生产力值填充该单元格。
    • 好的,我明白了 - 感谢您的澄清。当我在工作表中手动输入 CalcProducitivity 时,它会显示正确的数字。当我在 VBA 中尝试它时,我不断收到一个下标我们的范围错误(运行时错误 9)。错误超过“dataArray(1, i + 1))”.... 它似乎将数字相加并将它们存储在 runningSum 中直到最后。我注意到的一件事是 Ubound 显示了 69 列,但实际上有 72 列。我该如何解决这个问题?
    猜你喜欢
    • 2019-04-25
    • 2020-12-28
    • 2012-03-16
    • 1970-01-01
    • 2022-11-05
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    相关资源
    最近更新 更多