0

我正在尝试编写(我的第一个)自定义函数,该函数本质上将循环通过报告来总结未来 1、3、6 个月(等)的机器成本

该函数返回值,但是,这些值是不正确的,并且在包含自定义函数的单元格上更成问题会更改使用自定义函数的周围单元格的值。

我处理的代码在这里:

Option Explicit

Dim months As Integer 'a month is considered as 30 days
Dim cost As Long
Dim FleetData As Range
Dim rowCounter As Long
Dim lastRow As Long
Dim firstRow As Long
Dim component As Range
Dim dateOfAction As Range
Dim totalApprox As Range
Dim dateHorizon As Date 'Date to which the user wants to total the maintenance cost for

Private Function totalCosts(xMonths As Range)
'Dim totalCosts As Long
Application.Volatile

dateHorizon = Date + (30 * months)

firstRow = [A10].Row
rowCounter = firstRow
lastRow = Range("A65000").End(xlUp).Row
Set FleetData = [A10:S14]

If IsNumeric(xMonths.Value) Then months = xMonths.Value Else
If IsDate(xMonths.Value) Then months = (xMonths.Value - Date) / 30
cost = 0
    Do While rowCounter < lastRow
        Set component = Range(Cells(rowCounter, 1), Cells(rowCounter, 19))
        Set dateOfAction = Cells(rowCounter, 7)
        Set totalApprox = Cells(rowCounter, 12)
        If dateOfAction <= dateHorizon Then
            cost = cost + totalApprox
        End If
        totalCosts = cost
        rowCounter = rowCounter + 1
    Loop

End Function

我使用的数据是:

DateOfAction totalApprox 
5/07/2014    $30,068.62 
24/05/2005   $6,300.00 
5/07/2012    $29,742.00
5/07/2012    $4,360.28
27/12/2012   $5,555.89

单击单元格似乎会改变值,但没有可识别的顺序。

已经用谷歌搜索并查看了这里,但到目前为止似乎没有任何问题可以解决问题。

任何帮助将不胜感激!

4

1 回答 1

1

一些提示和检查事项:

  1. 不要使用模块范围的变量(除非您需要与其他模块共享这些变量。即使那样,通常也有更好的方法)
  2. 除非你真的需要,否则不要使用 Volatile(我认为你在这种情况下不会这样做)
  3. 将所有范围作为参数传递给函数
  4. 如果您必须使用直接范围引用,请记住非限定引用,例如Range(...和引用活动工作表Cell(...上的范围。如果您的数据表未激活,此 UDF 将返回意外结果。改用类似的东西。但我再说一遍,将范围引用作为参数传递给函数好得多。Worksheets("Sheet1").Range(...
  5. 您的代码在设置变量months之前引用它。
  6. 如果您从单元格中调用公式中的 UDF ,则尝试设置单元格值(如 中totalCosts = cost将不起作用。这在您提供的链接中明确说明(您不能直接制作 VBA UDF 的第一点:列表)。另一方面,如果您从 a 调用 UDFSub并将该 Sub 作为宏运行,它将起作用。

如果您提供数据布局的完整详细信息以及您希望如何使用 UDF,我可以提供更具体的建议。

于 2012-05-24T08:44:53.857 回答