使用IF,ISnumber和Find

时间:2015-10-25 19:17:50

标签: excel-vba excel-formula vba excel

我正在尝试将IF与ISnumber和Find一起使用,但是由于某些错误,它在VBA中无效,而且它也很长,所以这就是为什么它会发生变化。

实际公式

  =IF(ISNUMBER(FIND("CS&L",C3)),"CS&L",IF(ISNUMBER(FIND("EMPLX",C3)),"Employee Cross Charges",IF(ISNUMBER(FIND("EOCINV",C3)),"EOC Specific Recharges (Inventory Related)",IF(ISNUMBER(FIND("EOCNINV",C3)),"EOC Specific Recharges (Non - Inventory Related)",IF(ISNUMBER(FIND("EXPAT",C3)),"Expats",IF(ISNUMBER(FIND("GLBSC",C3)),"Global Service Charges",IF(ISNUMBER(FIND("INFSY",C3)),"Information Systems",IF(ISNUMBER(FIND("TRDDL",C3)),"International Trade Deals",IF(ISNUMBER(FIND("IREXP",C3)),"Intra-Region Expats",IF(ISNUMBER(FIND("MGMTF",C3)),"Management Fees (Below OC)",IF(ISNUMBER(FIND("MANUF",C3)),"Manufacturing",IF(ISNUMBER(FIND("MARKT",C3)),"Marketing",IF(ISNUMBER(FIND("OVERH",C3)),"Overheads",IF(ISNUMBER(FIND("PROCUR",C3)),"Procurement",IF(ISNUMBER(FIND("PCTGR",C3)),"Product Category Reviews",IF(ISNUMBER(FIND("RD&Q",C3)),"RDQ",IF(ISNUMBER(FIND("RESTR",C3)),"Restructuring / Project",IF(ISNUMBER(FIND("ROYAL",C3)),"Royalties",IF(ISNUMBER(FIND("STRAT",C3)),"Strategy",IF(ISNUMBER(FIND("TRDMK",C3)),"Trademarks","Others"))))))))))))))))))))

创建宏后,获得更改即获得错误

Sub Macro1()
'
' Macro1 Macro
'

'
    Range("B2").Select
    Selection.ClearContents
    ActiveCell.FormulaR1C1 = _
        "=IF(ISNUMBER(FIND(""CS&L"",R[1]C[1])),""CS&L"",IF(ISNUMBER(FIND(""EMPLX"",R[1]C[1])),""Employee Cross Charges"",IF(ISNUMBER(FIND(""EOCINV"",R[1]C[1])),""EOC Specific Recharges (Inventory Related)"",IF(ISNUMBER(FIND(""EOCNINV"",R[1]C[1])),""EOC Specific Recharges (Non - Inventory Related)"",IF(ISNUMBER(FIND(""EXPAT"",R[1]C[1])),""Expats"",IF(ISNUMBER(FIND(""GLBSC"",R" & _
        "),""Global Service Charges"",IF(ISNUMBER(FIND(""INFSY"",R[1]C[1])),""Information Systems"",IF(ISNUMBER(FIND(""TRDDL"",R[1]C[1])),""International Trade Deals"",IF(ISNUMBER(FIND(""IREXP"",R[1]C[1])),""Intra-Region Expats"",IF(ISNUMBER(FIND(""MGMTF"",R[1]C[1])),""Management Fees (Below OC)"",IF(ISNUMBER(FIND(""MANUF"",R[1]C[1])),""Manufacturing"",IF(ISNUMBER(FIND(""MAR" & _
        "C[1])),""Marketing"",IF(ISNUMBER(FIND(""OVERH"",R[1]C[1])),""Overheads"",IF(ISNUMBER(FIND(""PROCUR"",R[1]C[1])),""Procurement"",IF(ISNUMBER(FIND(""PCTGR"",R[1]C[1])),""Product Category Reviews"",IF(ISNUMBER(FIND(""RD&Q"",R[1]C[1])),""RDQ"",IF(ISNUMBER(FIND(""RESTR"",R[1]C[1])),""Restructuring / Project"",IF(ISNUMBER(FIND(""ROYAL"",R[1]C[1])),""Royalties"",IF(ISNUMBE" & _
        "STRAT"",R[1]C[1])),""Strategy"",IF(ISNUMBER(FIND(""TRDMK"",R[1]C[1])),""Trademarks"",""Others""))))))))))))))))))))"
    Range("B3").Select
End Sub

2 个答案:

答案 0 :(得分:1)

您可以继续使用工作表功能。公式只是将标记/缩写翻译成更长的术语,或者"其他"如果不明我会将翻译公式与这样的数据分开:
1)在该工作表的某处创建一个2列表,第1列包含令牌,第2列包含相应的术语:

CS&L    CS&L
EMPLX   Employee Cross Charges
EOCINV  EOC Specifiic Recharges (Inventory Related)

为了便于使用,请将该范围(例如,X1:Y3)命名为"术语"。
2)然后,在您的表格中,使用一个查找短标记并返回较长期限的公式 - VLOOKUP()

=IF(ISNV(VLOOKUP(C3,terms,2,FALSE)),"other",VLOOKUP(C3,terms,2,FALSE))

它看起来有点复杂,因为它需要两次评估查找以检查未知令牌。但是,与您的第一个公式相反,公式本身不包含任何数据。翻译表的大小也不受限制。

<强>附录
如果短期不是单元格中的唯一文本,则上述公式将始终返回错误;它只比较整个单元格的内容(C3)。我认为你在评论中提到了这一点。

为了模仿FIND完全使用它:

={INDEX(longterms,MAX(MAX(IF(ISERROR(SEARCH(shortterms,C3)),0,1)*ROW(shortterms)),MIN(ROW(shortterms)))-ROW(longterms)+1)}

输入此值作为矩阵公式(使用Ctrl-Shift-Enter输入) 在这里,我使用SEARCH查找文字而不查看案例 - 如果您想考虑案例,可以使用FIND
最里面的SEARCH创建了一个行号的数组(如果找到了术语)或shortterm命名范围的0(如果没有找到)。 MAX从该数组中创建一个值 此行号被INDEX作为与longterms相邻的指定范围shortterms
MIN函数仅需要将值0(如果未找到一个术语)更改为longterms的第一个条目的行号 - 这需要是&#34;其他&#34 ;文本。 所以2个命名范围看起来像:

U7: (empty) V7: other
U8: EMPLX   V8: Employee Cross Charges
U9: EOCINV  V9: EOC Specifiic Recharges (Inventory Related)

shortterms定义为$ U $ 7:$ U $ 9和longterms为$ V $ 7:$ V $ 9.

答案 1 :(得分:0)

需要注意的一些要点:

  1. 长公式难以阅读,我建议使用[Alt] + [Enter]个键合并在同一个单元格中开始一个新行,从而打破几行中的公式(见图1)

  2. FIND区分大小写,而是使用SEARCH (参见图1)

  3. 您似乎尝试录制宏以将公式作为VBA,请注意很长的公式未正确记录到VBA中。不过,您可以使用以下过程在Visual Basic立即窗口中打印ActiveCell的整个公式。

    Sub Get_Formula()
    Rem Opens Immediate Window and Clears it
    SendKeys "^g^a{DEL}": Stop
    
    With ActiveCell
        Debug.Print vbLf; vbLf; String(131, "*")
        Debug.Print "Formula in Wbk\Wsh\Cell: "; .Parent.Parent.Name; " \ "; .Parent.Name; " \ "; .Address(0, 0)
        Debug.Print ActiveCell.Formula
        Debug.Print vbLf; String(131, "*"); vbLf
    End With
    SendKeys "^g^{HOME}" ': Stop
    End Sub
    
  4. 关于公式,有几个解决方案,我将列出其中三个。

    这些公式假设与相应描述相关联的字符串列表位于B7:B28

    1. 标准Excel公式:使用与您发布的公式类似的标准长公式,只需将FIND替换为SEARCH,因为目标字可以是大写(参见图1)。长公式的问题在于它们难以阅读并且需要大量维护。在C7中输入此公式并复制到最后一条记录(参见图1)

      =IF(ISNUMBER(SEARCH("CS&L",$B7)),"CS&L",
      IF(ISNUMBER(SEARCH("EMPLX",$B7)),"Employee Cross Charges",
      IF(ISNUMBER(SEARCH("EOCINV",$B7)),"EOC Specific Recharges (Inventory Related)",
      IF(ISNUMBER(SEARCH("EOCNINV",$B7)),"EOC Specific Recharges (Non - Inventory Related)",
      IF(ISNUMBER(SEARCH("EXPAT",$B7)),"Expats",
      IF(ISNUMBER(SEARCH("GLBSC",$B7)),"Global Service Charges",
      IF(ISNUMBER(SEARCH("INFSY",$B7)),"Information Systems",
      IF(ISNUMBER(SEARCH("TRDDL",$B7)),"International Trade Deals",
      IF(ISNUMBER(SEARCH("IREXP",$B7)),"Intra-Region Expats",
      IF(ISNUMBER(SEARCH("MGMTF",$B7)),"Management Fees (Below OC)",
      IF(ISNUMBER(SEARCH("MANUF",$B7)),"Manufacturing",
      IF(ISNUMBER(SEARCH("MARKT",$B7)),"Marketing",
      IF(ISNUMBER(SEARCH("OVERH",$B7)),"Overheads",
      IF(ISNUMBER(SEARCH("PROCUR",$B7)),"Procurement",
      IF(ISNUMBER(SEARCH("PCTGR",$B7)),"Product Category Reviews",
      IF(ISNUMBER(SEARCH("RD&Q",$B7)),"RDQ",
      IF(ISNUMBER(SEARCH("RESTR",$B7)),"Restructuring / Project",
      IF(ISNUMBER(SEARCH("ROYAL",$B7)),"Royalties",
      IF(ISNUMBER(SEARCH("STRAT",$B7)),"Strategy",
      IF(ISNUMBER(SEARCH("TRDMK",$B7)),"Trademarks","Others"))))))))))))))))))))
      

      enter image description here

    2. 图。 1

      1. FormulaArray :对于您正在使用的数据,最佳做法是创建一个表来保存不同元素之间的关系(即,此处的描述简短描述)案例) user1016274 所述。但是,我特别建议在公式和VBA中使用其结构化引用的优势,在VBA中创建Excel Table ListObject (请参阅Use structured references in Excel table formulas

        在这种情况下,我在单独的工作表中创建了Excel Table,因此不会对工作簿中可能包含的其他报表和数据造成任何中断。 Excel Table名为tDescriptions (参见图2a)

        enter image description here

        图。图2a

        然后我们使用FormulaArray从表中检索关联的描述。在FormulaArray中输入此D7并复制到最后一条记录(参见图2b)

        =IF(SUM(1*NOT(ISERR(SEARCH(tDescriptions[Short.Desc],ShortLongDesc!$B7))))=0,"Others",
        INDEX(tDescriptions[Description],
        SUM((1*NOT(ISERR(SEARCH(tDescriptions[Short.Desc],ShortLongDesc!$B7))))
        *(ROW(tDescriptions)-ROW(tDescriptions[#Headers])))))
        

        enter image description here

        图。图2b

      2. 用户定义函数(UDF):虽然我们可以使用数组来保持简短描述与描述关系,但我更喜欢将其保留在创建的Excel Table中。之前的一点,因为它更容易维护。在E7中输入此公式。 (见图3)

        =Get_LongDescription(B7)
        

        enter image description here

        图。 3

        以下是UDF的代码。输入的参数可以是字符串或单元格引用,如果输入的范围包含多个单元格,则UDF将返回错误。

        Option Explicit
        
        Public Function Get_LongDescription(sText As String) As String
        Dim Lob As ListObject
        Dim lRow As Long
            Rem Set Default Result
            Get_LongDescription = "Others"
            Rem Set Objects
            Set Lob = ThisWorkbook.Sheets("ShortLongDesc(Tbl)").ListObjects("tDescriptions")
            Rem Search SHort Desc in Text
            With Lob
                For lRow = 1 To .DataBodyRange.Rows.Count
                    If InStr(LCase(sText), LCase(.ListColumns("Short.Desc").DataBodyRange.Cells(lRow).Value2)) <> 0 Then
                        Get_LongDescription = .ListColumns("Description").DataBodyRange.Cells(lRow).Value2
                        Exit For
            End If: Next: End With
            End Function