当我尝试向下面的公式添加一些格式化函数时,我收到一条错误消息,指出您为此函数输入了太多参数,但我只是尝试添加文本函数以进行格式化,这只是简单的两个论点。不知道为什么它会抛出这个错误。是否有最多可以输入单个单元格的函数?下面的公式。
P.S。我试着将它放入一个代码框中,但它只是在一个连续的字符串中运行,所以这可能更好。
公式的目的:此公式用于根据用户填写的数据生成聊天消息,范围从A-Q列开始。数据以行的形式出现,对于vlookup imo来说是不可行的。它将打印出这样的声明“你买100 / kbbl WTI美国V15 40.00电话@ 1.00,你卖30 / kbbl WTI V15期货@ 41.00; ClearPort BLOCK,谢谢”这句话出现在每个相应行的S列填写英寸
所使用的长度和具体用语取决于用户输入的内容(因此下面的暴行)。
=“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 =“美国”,“期货”,IF($ B21 =“APO”,“掉期”,IF($ B21 =“欧洲”,IF($ A21 =“NG”,“倒数第二个未来”,“交换”))))&“@”& TEXT($ P21,“#,## 0.00 ##”),“你”& $ 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”,“天然气” 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 =“美国”,“期货”,IF($ B21 =“APO”,“掉期”,IF($ B21 =“欧洲”,IF($ A21 =“NG”) ,“倒数第二个未来”,“交换”))))&“@”& $ P21))&“; “& IF($ Q21 =”i“,”ICE BLOCK“,”ClearPort BLOCK“)&”谢谢你“
答案 0 :(得分:4)
如果有一个excel公式应该迁移到UDF,我认为就是这样。
同样,我认为公式的复杂性导致括号错误的不平衡。
我有一个小的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
将公式粘贴在标签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
),
哪个没有右括号(也没有value if false
参数,尽管不应该抛出错误)。或者也许它确实存在,并且在这里有一个额外的关闭的parantheses它不属于..
无论如何,这应该可以帮助您诊断问题,并且可以更有效地重写(或转换为UDF)
答案 1 :(得分:1)
根据JNevill的建议,创建一个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