编写VBA函数以求和"每小时成本"进入"每日费用"然后进入"每月费用"

时间:2016-04-12 23:07:27

标签: excel excel-vba vba

我正在尝试模拟家用加热装置的成本。我有3.15年的每小时数据。我计算了每小时的成本,每天的成本,每月的成本和每年的成本。我想编写两个VBA函数,一个名为CostPerDay,另一个名为CostPerMonth,以便在添加更多数据时简化过程。我附上了我的数据图片。

数据图片

enter image description here

我为每日费用写的功能是:

=SUM(OFFSET($M$18,(ROW()-18)*24,0,24,1))

我为每月费用写的函数是:

Jan-13 =SUM(OFFSET($P$18,(ROW()-18)*31,0,31,1))
Feb-13 =SUM(OFFSET($P$49,(ROW()-19)*28,0,28,1))
Mar-13 =SUM(OFFSET($P$77,(ROW()-20)*31,0,31,1))
Etc...

如果您需要整个数据范围:

Cost Per Hour - M18:M27636
Cost Per Day - P18:P1168
Cost Per Month - S18:S55
Average Cost Per Month - V18:V29

这就是我的尝试。如你所见,我是VBA的新手。在第一次尝试中,我试图使用Dim来定义数据在电子表格中的位置以及我想要计算的单元格。我卡住了因为我无法将=SUM(OFFSET($M$18,(ROW()-18)*24,0,24,1))函数插入到VBA中。然后,我试图通过将其替换为$M$18来摆脱硬编码的Cells(Match(Day,O18:O1168)+17,"P")。但它都没有奏效。

第二个我正在玩对话框,但我认为我不想使用它们。

在第三次尝试中,我试图计算每月费用。我没有,因为我没有保存它。我使用SUMIFS将月份与月份中的天数进行匹配。这可能是我最接近的尝试,但它仍然没有用。

Function CostPerDay(BeginningCostPerDay, OutputCell)
    Dim BeginningCostPerDay, OutputCell
        BeginningCostPerDay = WorksheetFunction.DSum()
        OutputCell = ActiveCell.Offset(3, -3).Activate
End Function

Function CostPerDay1()
    Dim myValue1 As Variant, myValue2 As Variant
        myValue1 = InputBox("Where do you want the data put?")
        myValue2 = InputBox("What is the beginning Cost Per Day")
            Range("myValue1").Value = myValue1
            Range("myValue2").Value = myValue2

End Function

1 个答案:

答案 0 :(得分:0)

这是您的答案。

Private Sub SumCosts(ByVal MainColumn As String, ByVal CostColumn As String, ByVal FirstDataRow As Long, Optional ByVal BracketType As Byte)
  '
  'Parameters:
  'MainColumn: the columns with dates or months.
  'CostColumn: the column that holds the costs to sum.
  'FirstDataRow: the first row where the data starts
  'BracketType: either 0 for hours or 1 for months
  '
  'This procedure assumes that in the data on the sheet
  '- every hour of every day in the hours columns
  '- every day of a month is present in the days columns
  'are present. I.e. All hours of all 31 days of January are persent
  'in the 'Date' column before the hours of February start and all days of January
  'are present in the 'Month' column before the days of February start.
  Const Hours As Byte = 24
  '
  Dim Cel As Range
  Dim I As Long
  Dim J As Long
  Dim K As Long
  Dim Rng As String
  Dim Bracket As Byte
  Dim Days As Byte
  '
  'Clean the target area, so the modle can be reused time after time.
  Set Cel = Range(MainColumn & Application.Rows.Count).Offset(0, 1)
  Rng = Split(Cel.Address, "$")(1)
  Rng = (Rng & FirstDataRow & ":" & Rng & Cel.End(xlUp).Row)
  Range(Rng).ClearContents
  '
  J = FirstDataRow
  For Each Cel In Range(MainColumn & ":" & MainColumn)
    If Cel.Value = vbNullString Then Exit For
    If Cel.Row > (FirstDataRow - 1) Then
      'Number of days in a month. Since this fluctuates the bracket fluctuates.
      Days = DateSerial(Year(Cel.Value), Month(Cel.Value) + 1, 1) - DateSerial(Year(Cel.Value), Month(Cel.Value), 1)
      Bracket = IIf(BracketType = 0, Hours, Days)  'Select the bracket to use.
      K = ((Cel.Row - 1) * Bracket) + (FirstDataRow - 1)  'Determine where to stop calculating for a given day or month.
      For I = J To K
        Cel.Offset(0, 1).Value = Cel.Offset(0, 1).Value + Range(CostColumn & I).Value  'Do the calculation.
      Next
      J = K + 1  'Next loop we must pick up where we left off.
    End If
  Next
End Sub

Public Sub LaunchCostCalculations()
  SumCosts "O", "M", 2, 0
  SumCosts "R", "P", 2, 1
End Sub

在工作表中创建一个按钮以启动LaunchCostCalculations,而Bob是您的叔叔。