单个单元中的最大function数

当我尝试添加几个格式函数到下面的公式时,我收到一个错误消息,说明你input了太多的参数为这个函数,但我只是试图添加一个文本函数的格式化,它只有两个参数。 不知道为什么它抛出这个错误。 是否有最大数量的function可以input到一个单元格? 下面的公式。

PS我试图把它放在一个代码框,但它只是在一个连续的string运行,所以这可能是更好的。

公式的目的:该公式旨在根据用户填入的数据生成聊天消息,范围从AQ列。 数据以行的forms出现,并不适用于虚拟主机。 它会打印出这样的声明:“你买100 / kbbl WTI美国V15 40.00电话@ 1.00,你卖出30 / KBb WTI V15期货@ 41.00; ClearPort BLOCK,谢谢”这句话出现在每一行在。

所使用的长度和具体用语因用户input的内容而不同(因此下面的暴行)。

=“您”&$ D21&“”&IF($ A21 =“NG”,TEXT($ E21 * $ G $ 13,“#,## 0”),$ E21)&IF($ B21 =“APO”,“如果($ A21 =“NG”,“/ MMBtu”,IF($ A21 =“FO 3.5%”,“/ kt”,“/ kbbl”))&IF($ A21 =“NG”,“天然气亨利枢纽“,$ A21)&”“&$ B21&”“&$ C21&”“&$ F21&”“&$ G21&”@“&$ H21&”,“如果(ISBLANK($ K21),IF(ISBLANK ($ O21),“LIVE”,“You”&$ N21&“&IF($ A21 =”NG“,TEXT($ O21 * $ G $ 13,”#,## 0“),$ O21)&IF($ B21 =“APO”,“/ mo”,IF($ A21 =“NG”,“/ MMBtu”,IF($ A21 =“FO 3.5%”,“/ kt”,“/ kbbl”)) $ A21 =“NG”,“天然气亨利枢纽”,$ A21)&“”&$ C21&“”和IF($ B21 =“美式”,“期货”,如果(B21 =“APO” IF($ B21 =“European”,IF($ A21 =“NG”,“Penultimate Future”,“Swap”))))&“@”&TEXT($ P21,“#,## 0.00 ##”) ($ A21 =“NG”,TEXT($ J21 * $ G $ 13,“#,## 0”),$ J21)&IF($ B21 =“APO”,“/如果($ A21 =“NG”,“/ MMBtu”,IF($ A21 =“FO 3.5%”,“/ kt”,“/ kbbl”))&IF($ A21 =“NG”,“天然气Henry Hub“,$ A21)&”“&$ B21&”“&$ C21&”“&$ K21&”“&$ L21&”@“&$ M21&IF(ISBLANK($ O21),”,LIVE“,”你“&$ N21&”“&IF($ A21 =”NG“,TEXT($ O21 * $ G $ 13,”#,## 0“),$ O21)&IF($ B21 =”APO“,”/ mo“ ,IF($ A21 =“NG”,“/ MMBtu”,IF($ A21 =“FO 3.5%“,”/ kt“,”/ kbbl“))和IF($ A21 =”NG“,”天然气Henry Hub“,$ A21)&”“&$ C21&”“&IF($ B21 = (B21 =“APO”,“掉期”,IF($ B21 =“欧洲”,IF($ A21 =“NG”,“倒数第二未来”,“掉期”)))) “@”&$ P21))&“; “&IF($ Q21 =”i“,”ICE BLOCK“,”ClearPort BLOCK“)和”Thank You“

如果有一个应该迁移到UDF的excel公式,我想就是这样。

同样,我认为公式的复杂性导致了不平衡的括号误差。

我有一个小的VBA子程序,将打破这样的复杂公式,并添加空白和缩进。 这不是完美的,但它做的工作。

 Sub beautifier() strCodeIn = Sheet1.Range("A1") indent = 1 i = 1 Do Until IsError(Mid(strCodeIn, i, 1)) strChar = Mid(strCodeIn, i, 1) If InStr(1, "(&,", strChar) > 0 Then If indent = 0 Then indent = 1 If i > Len(strCodeIn) Then Exit Do If InStr(1, "(", strChar) > 0 Then indent = indent + 1 strCodeIn = Left(strCodeIn, i) & vbCrLf & String(indent, Chr(9)) & Right(strCodeIn, Len(strCodeIn) - i) i = i + indent ElseIf InStr(1, ")", strChar) > 0 Then If indent <> 0 Then indent = indent - 1 strCodeIn = Left(strCodeIn, i - 1) & vbCrLf & String(indent, Chr(9)) & Right(strCodeIn, Len(strCodeIn) - (i - 1)) i = i + indent + 3 ElseIf i > 5000 Then Exit Do Else: i = i + 1 End If Loop Dim clipboard As MSForms.DataObject Set clipboard = New MSForms.DataObject clipboard.SetText strCodeIn clipboard.PutInClipboard Sheet1.Cells(1, 2).Value = strCodeIn End Sub 

将您的公式粘贴在Tab Sheet1 ,没有等号的单元格A1 ,然后运行子程序。 它会将结果粘贴到剪贴板中,以便您可以将其放到一个好的文本编辑器中,突出显示与Notepad ++相匹配的括号。 你会得到:

 "You "& $D21& " "& IF( $A21= "NG", TEXT( $E21*$G$13, "#, ##0" ), $E21 )& IF( $B21="APO", "/mo ", IF( $A21="NG", "/MMBtu ", IF( $A21="FO 3.5%", "/kt ", "/kbbl " ) ) )& IF( $A21="NG", "Natural Gas Henry Hub", $A21 )& " "& $B21& " "& $C21& " "& $F21& " "& $G21& " @ "& $H21& ", "& IF( ISBLANK( $K21 ), IF( ISBLANK( $O21 ), "LIVE", "You "& $N21& " "& IF( $A21="NG", TEXT( $O21*$G$13, "#, ##0" ), $O21 )& IF( $B21="APO", "/mo ", IF( $A21="NG", "/MMBtu ", IF( $A21="FO 3.5%", "/kt ", "/kbbl " ) ) )& IF( $A21="NG", "Natural Gas Henry Hub", $A21 )& " "& $C21& " "& IF( $B21="American", "Futures ", IF( $B21="APO", "Swaps ", IF( $B21="European", IF( $A21="NG", "Penultimate Future", "Swap" ) ) ) )& " @ "& TEXT( $P21, "#, ##0.00##" ), "You "& $I21& " "& IF( $A21="NG", TEXT( $J21*$G$13, "#, ##0" ), $J21 )& IF( $B21="APO", "/mo ", IF( $A21="NG", "/MMBtu ", IF( $A21="FO 3.5%", "/kt ", "/kbbl " ) ) )& IF( $A21="NG", "Natural Gas Henry Hub", $A21 )& " "& $B21& " "& $C21& " "& $K21& " "& $L21& " @ "& $M21& IF( ISBLANK( $O21 ), ", LIVE", ", You "& $N21& " "& IF( $A21="NG", TEXT( $O21*$G$13, "#, ##0" ), $O21 )& IF( $B21="APO", "/mo ", IF( $A21="NG", "/MMBtu ", IF( $A21 ="FO 3.5%", "/kt ", "/kbbl " ) ) )& IF( $A21="NG", "Natural Gas Henry Hub", $A21 )& " "& $C21& " "& IF( $B21="American", "Futures", IF( $B21="APO", "Swaps", IF( $B21="European", IF( $A21="NG", "Penultimate Future", "Swap" ) ) ) )& " @ "& $P21 ) )& "; "& IF( $Q21="i", "ICE BLOCK, ", "ClearPort BLOCK, " )& " Thank You" 

这里可能有很多问题。 例如,你可以在第43行看到IF()公式

  IF( ISBLANK( $K21 ), 

没有closures的括号( value if false参数,也没有value if false ,但不应该抛出错误)。 或者它也可以,在这里它不属于..

无论如何,这应该可以帮助你诊断问题,也许可以做一个更有效的重写(或转换为UDF)

根据JNevill的build议,创build了一个UDF,而不是使用上面公布的可怕公式。 UDF接受一个范围对象参数。 下面的代码

 Function BUILDCHATCONFIRM(tradeDataRange As Range) As String Dim chatConfirmString As String, firstLegBuySell As String, secondLegBuySell As String, futureLegBuySell As String, iceClearingDesignation As String, cmeClearingDesignation As String, nasdaqClearingDesignation As String, contractMonth As String, productType As String Dim nattyGasMultiplier As Long, firstLegQuantity As Long, secondLegQuantity As Long, futureLegQuantity As Long nattyGasMultiplier = 10000 cmeClearingDesignation = "; ClearPort BLOCK, Thank You" iceClearingDesignation = "; ICE BLOCK, Thank You" nasdaqClearingDesignation = "; NASDAQ BLOCK, Thank you" firstLegBuySell = tradeDataRange.Item(4).Value secondLegBuySell = tradeDataRange.Item(9).Value futureLegBuySell = tradeDataRange.Item(14).Value contractMonth = tradeDataRange.Item(3).Value productType = tradeDataRange.Item(1).Value firstLegQuantity = tradeDataRange.Item(5).Value secondLegQuantity = tradeDataRange.Item(10).Value futureLegQuantity = tradeDataRange.Item(15).Value 'Accounts for natty multiplier when building natty confirms If productType = "NG" Then productType = "Natural Gas Henry Hub" firstLegQuantity = firstLegQuantity * nattyGasMultiplier secondLegQuantity = secondLegQuantity * nattyGasMultiplier futureLegQuantity = futureLegQuantity * nattyGasMultiplier End If 'Builds future leg if just a futures trade or a blank cell If Len(firstLegBuySell) = 0 Then If Len(futureLegBuySell) = 0 Then chatConfirmString = "Nothing" GoTo SkipToEnd Else If Application.Caller.Column = 20 Then If futureLegBuySell = "Buy" Or futureLegBuySell = "buy" Then futureLegBuySell = "Sell" Else futureLegBuySell = "Buy" End If End If chatConfirmString = "You " & futureLegBuySell & " " & Format(futureLegQuantity, "#,#00") & DetermineProductMeasurementType(productType, tradeDataRange.Item(2).Value, contractMonth) & " " & productType & " " & contractMonth & " " & DetermineFuturesType(productType, tradeDataRange.Item(2).Value) & " @ " & Format(tradeDataRange.Item(16).Value, "#,#00.00##") End If 'Builds option and subsequent hedge confirms detected by a Len > 0 first buy/sell leg Else If Application.Caller.Column = 20 Then Call ChangeDirectionForSellSide(firstLegBuySell, secondLegBuySell, futureLegBuySell) 'First option leg built chatConfirmString = "You " & firstLegBuySell & " " & Format(firstLegQuantity, "#,#00") & DetermineProductMeasurementType(productType, tradeDataRange.Item(2).Value, contractMonth) & " " & productType & " " & tradeDataRange.Item(2).Value & " " & contractMonth & " " & tradeDataRange.Item(6).Value & " " & tradeDataRange.Item(7).Value & " @ " & Format(tradeDataRange.Item(8).Value, "###.00##") 'tests for existence and builds second option leg If Len(secondLegBuySell) <> 0 Then chatConfirmString = chatConfirmString & ", You " & secondLegBuySell & " " & Format(secondLegQuantity, "#,#00") & DetermineProductMeasurementType(productType, tradeDataRange.Item(2).Value, contractMonth) & " " & productType & " " & tradeDataRange.Item(2).Value & " " & contractMonth & " " & Format(tradeDataRange.Item(11).Value, "#,##0.00##") & " " & tradeDataRange.Item(12).Value & " @ " & Format(tradeDataRange.Item(13).Value, "###.00##") Else 'Do nothing move on to futures leg End If 'Builds futures leg If Len(futureLegBuySell) <> 0 Then chatConfirmString = chatConfirmString & ", You " & futureLegBuySell & " " & Format(futureLegQuantity, "#,#00") & DetermineProductMeasurementType(productType, tradeDataRange.Item(2).Value, contractMonth) & " " & productType & " " & contractMonth & " " & DetermineFuturesType(productType, tradeDataRange.Item(2).Value) & " @ " & Format(tradeDataRange.Item(16).Value, "#,##0.00##") Else chatConfirmString = chatConfirmString & ", LIVE" End If End If 'determines clearing designation string closure Select Case chatConfirmString Case "Nothing" 'Do nothing pass "nothing" string through Case Else If tradeDataRange.Item(17).Value = "c" Or tradeDataRange.Item(17).Value = "C" Then chatConfirmString = chatConfirmString & cmeClearingDesignation ElseIf tradeDataRange.Item(17).Value = "i" Or tradeDataRange.Item(17).Value = "I" Then chatConfirmString = chatConfirmString & iceClearingDesignation ElseIf tradeDataRange.Item(17).Value = "n" Or tradeDataRange.Item(17).Value = "N" Then chatConfirmString = chatConfirmString & nasdaqClearingDesignation Else chatConfirmString = chatConfirmString & cmeClearingDesignation End If End Select SkipToEnd: BUILDCHATCONFIRM = chatConfirmString End Function Function DetermineProductMeasurementType(ByVal productType As String, ByVal assetType As String, ByVal assetTerm As String) As String 'Determines if it is a multimonth structure If InStr(1, assetTerm, "-") > 0 Or assetType = "APO" Then DetermineProductMeasurementType = "/mo" GoTo SkipToEndDetermineProduct ElseIf Left(assetTerm, 1) = "Q" And Len(assetTerm) = 4 Then DetermineProductMeasurementType = "/mo" GoTo SkipToEndDetermineProduct End If 'Analysis of Type for single month contracts If assetType = "American" Or assetType = "European" And productType <> "Natural Gas Henry Hub" And productType <> "FO 3.5%" Then DetermineProductMeasurementType = "/kbbl" ElseIf assetType = "American" Or assetType = "European" And productType = "Natural Gas Henry Hub" Then DetermineProductMeasurementType = "/MMBtu" ElseIf productType = "FO 3.5%" Then DetermineProductMeasurementType = "/kt" Else DetermineProductMeasurementType = "/kbbl" End If SkipToEndDetermineProduct: End Function Function DetermineFuturesType(ByVal productType As String, ByVal optionType As String) As String 'Determines futures type by option type and expiry Select Case optionType Case "American" DetermineFuturesType = "Futures" Case "APO" DetermineFuturesType = "Swaps" Case "European" If productType = "Natural Gas Henry Hub" Then DetermineFuturesType = "Penultimate Futures" Else DetermineFuturesType = "Swaps" End If Case Else DetermineFuturesType = "Futures" End Select End Function Sub ChangeDirectionForSellSide(ByRef firstBuySellLeg As String, ByRef secondBuySellLeg As String, ByRef futureBuySellLeg As String) 'Changes direction of buy/sell legs for sell side column If firstBuySellLeg = "Buy" Or firstBuySellLeg = "buy" Then firstBuySellLeg = "Sell" ElseIf firstBuySellLeg = "Sell" Or firstBuySellLeg = "sell" Then firstBuySellLeg = "Buy" Else 'Do nothing End If If secondBuySellLeg = "Buy" Or secondBuySellLeg = "buy" Then secondBuySellLeg = "Sell" ElseIf secondBuySellLeg = "Sell" Or secondBuySellLeg = "sell" Then secondBuySellLeg = "Buy" Else 'Do nothing End If If futureBuySellLeg = "Buy" Or futureBuySellLeg = "buy" Then futureBuySellLeg = "Sell" ElseIf futureBuySellLeg = "Sell" Or futureBuySellLeg = "sell" Then futureBuySellLeg = "Buy" Else 'Do Nothing End If End Sub