【问题标题】:Turning an excel formula into a VBA function将 Excel 公式转换为 VBA 函数
【发布时间】:2013-11-09 21:58:24
【问题描述】:

我对编程有点陌生,最初只是想改进电子表格,但它已经超出了在 excel 中使用基本功能的范围。我有一个表格,我正在查看一个函数以在第一列中查找建筑编号,然后查看其他两个相应列中的开始和结束日期,以确定它是否应该填充日历工作表上的特定块。出现此问题是因为同一建筑物编号可能会在不同日期出现多次,我需要找到与正确日期匹配的条目。

我能够创建一个有效但复杂的公式来找到第一个实例,并了解到我可以在错误语句中再次添加该公式的嵌套 if,只需稍作更改。我可以继续这样做,但它变得非常大而且很麻烦。我正在尝试找到一种方法为公式创建一个函数,其中包含一个变量,该函数将查看它已经使用了多少次,因此它会继续在表格中搜索适合参数的答案。

这是我目前的公式:

=IFERROR(IF(AND(DATE('IF SHEET (2)'!$F$7,MATCH('IF SHEET (2)'!$C$2,'IF SHEET (2)'!$C$2:'IF SHEET (2)'!$N$2,0),'IF SHEET (2)'!C$4)>=VLOOKUP("2D11"&1,A2:F6,4,0),DATE('IF SHEET (2)'!$F$7,MATCH('IF SHEET (2)'!$C$2,'IF SHEET (2)'!$C$2:'IF SHEET (2)'!$N$2,0),'IF SHEET (2)'!C$4)<=VLOOKUP("2D11"&1,A2:F6,4,0)),IF(VLOOKUP("2D11"&1,A2:F6,3,0)="2D11",VLOOKUP("2D11"&1,A2:F6,6,FALSE)),"NO ANSWER"),"ERROR")

你看到2D11&amp;1 是我需要变量 1 的地方,所以它是“它在函数 +1 中使用的次数”然后我可以循环它,这样它会一直检查直到它用完2D11 或找到匹配的。我之前没有发布过,我正在通过大量的试验和错误来做到这一点,所以如果您需要更多信息,请发布并说出来,我会尽力提供。

因此,与其让某人尝试理解我发布的荒谬公式,我会尝试通过说明我需要完成的内容并尝试了解如何将其转换为 VBA 函数来使其更简单。所以我有点看几个步骤:

  1. 将 A 列中建筑物名称的第一个实例与
    匹配 输出单元格所在行的建筑物名称。
  2. 日期是否与输出单元格相关 >= 第一个条目的开始日期(用户在 D 列中输入)。
  3. 日期是否与输出单元格相关联
  4. 如果第 1、2 和 3 部分都为真,则为建筑物的第一个实例输入单元名称(位于 F 列)。
  5. 如果第 1、2 或 3 部分为 False,则循环查看第 1 列下建筑物名称的下一个实例。

希望这比公式更清楚,因此我能够获得帮助,因为由于对 VBA 的了解不足,我仍然很困惑。

【问题讨论】:

  • 这是一种公式,如果您从施工开始就使用它,就可以最好地理解这种公式(我从经验中知道)。您是否从建筑物编号、开始日期和完成数据开始? “找出它是否应该填充特定的块......”是什么意思?
  • 我刚刚发现由于冗余,它的一部分可以被删除。该公式不再需要 IF(VLOOKUP("2D11"&1,A2:F6,3,0)="2D11",因为该部分用于检查名称是否正确但不再需要。尽管删除它你还必须在 FALSE 之后删除一个 )。
  • 所以我想一个更好的解释是 A 列的建筑物编号,后面有一个计数它在 C 列中出现的次数。B 列和 C 列都是下拉框,B 列是区域,所以在这种情况下是 2D 块。然后,C 列有一个下拉列表,具体取决于该区块中建筑物的区块。 D、E 和 F 列是供用户填写的方框。 D 列的开始日期是被占用的开始日期,E 列的结束日期是被占用的日期。 F 列是他们进入谁将占用建筑物的地方。希望对一些人有所帮助。
  • 如果你提供你的样品表和你需要的东西会更好,而不是那个永远不知道它是如何工作的长公式..
  • 请将您的 cmets 添加为问题更新,以便它们可以正确格式化并因此被理解。

标签: excel vba


【解决方案1】:

这是一个简单的解决方案...

Building_name = ???
Date = ???

Last_Row = Range("A65536").End(xlUp).Row

For i = 1 To Last_Row
   if cells(i,1).value = Building_Name Then
       if date >= cells(i,4).value Then
           if date <= cells(i,5).value Then
               first instance = cells(i,6).value
           end if 
       end if
    end if
next

你应该在最后添加一个测试以避免表中没有第一个实例的情况

【讨论】:

    【解决方案2】:

    如果我理解正确,您的表 T1 由 3 列组成:T1.building、T1.start date、T1.end date。 然后你有 3 个参数:P1=建筑,P2=开始日期,P3=结束日期。 您需要在表 T1 中找到“适合”输入参数日期的第一个条目,即:

    • P1=T1.building
    • P2
    • P3>=T1.结束日期

    如果是这样,您可以像这样定义自定义函数

    Public Function MyLookup(Key As Variant, DateMin As Variant, DateMax As Variant, LookUpTable As Range, ResultColumn As Integer) As Range
      Dim iIndx As Integer
      Dim KeyValue As Variant
      Dim Found As Boolean
    
      On Error GoTo ErrHandler
    
      Found = False
      iIndx = 1
      Do While (Not Found) And (iIndx <= LookUpTable.Rows.Count)
          KeyValue = LookUpTable.Cells(iIndx, 1)
          If (KeyValue = Key) And _
              (DateMin <= LookUpTable.Cells(iIndx, 2)) And _
              (DateMax >= LookUpTable.Cells(iIndx, 3)) Then
                  Set MyLookup = LookUpTable.Cells(iIndx, ResultColumn)
                  Found = True
          End If
          iIndx = iIndx + 1
      Loop
      Exit Function
    ErrHandler:
      MsgBox "Error in MyLookup: " & Err.Description
    End Function
    

    这可能不是世界上性能最高的代码,但我认为它可以解释。

    你可以下载this工作示例

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-25
      • 1970-01-01
      相关资源
      最近更新 更多