我已经浏览了网站,但是关于使Excel公式(公式?)更具可读性的建议倾向于指向使用命名区域' 或'使用帮助列' 。我不是在使公式更容易阅读的技术之后,我想创建一个宏来以更易读的方式显示公式。 您可以跳到最后以获得缩短的问题说明。我这样说是因为虽然我喜欢解释我的方法,但我觉得这次我的方法可能会分散问题的本质。此外,我认为如果没有前面提到的背景,问题可以很好地提炼出来
我有很多令人讨厌的窝窝复杂的公式,这是我今天写的一个(见Excel sample document)
或代码:
=IFERROR(IF(Latest[Weekday Num]=5,0,M13+MAX(Table3[Lunchtime],Latest[Lunchtime])-INDEX(Table4[Out],Latest[Weekday Num]))+Table3[Time remaining]-SUMIFS(Table4[Work time],Table4[Weekday Num],">"&Latest[Weekday Num],Table4[Weekday Num],"<5")+Latest[Clocked In]-S13,"Refresh csv")
虽然它很丑陋,IMO实际上构造得很好; IFS
和SUMIFS
尽可能避免公式的嵌套,存储在表中的所有命名范围,适用时使用的辅助列。然而,在某些情况下,它会返回错误的结果,并且公式 不 令人愉快。 (它不是最长的,我编译了几个a4页的代码,代码,虽然那是我无法使用vba构建帮助列的时候)
我想要一个宏,它采用这个公式并将其拆分为一种分支函数树,其中每个嵌套函数是另一个树枝 - 可能在工作簿中的单元格中拆分公式的组件
到目前为止,我尝试了以下方法:列A和B用于将公式拆分为更小的部分。 我将这些部分定义为Excel公式的功能和参数,因此公式IF(A1=1,A2,B1)
分为IF(
,A1=1,
,A2,
和B1)
。我在B栏中使用以下公式执行此操作:
=LEFT(A2,IFERROR(MAX(1,MIN(IFERROR(FIND("(",A2),LEN(A2)+1),IFERROR(FIND(")",A2),LEN(A2)+1),FIND(",",A2))),LEN(A2)))
同时,A列查看B列找到的最后一个组件,并将其从长公式(使用=SUBSTITUTE(A2,B3,"",1)
)中删除。
因此,对于A2中的原始公式(作为文本),B2是它的第一个组成部分(例如我的例子中的IF(
),A3是A2 中的公式减去的第一个组成部分在B2。我拖下来迭代。
这给了我列B中每个单元格中公式的组件列表。然后,我的宏决定每个组件的级别,并通过那么多单元格缩进组件。 级别定义为公式* 或&#39;段&#39;的组件前面的开放括号数。在我的代码中尚未关闭。宏评论解释了这一点。
Sub DispFormula()
'takes a split-up formula and indents lines appropriately
Dim CurrLev As Integer, OBrac As Integer, CBrac As Integer
Dim Segment As Range 'each part of the split up formula
LastRow = Sheets("sheet1").Cells(Rows.Count, 2).End(xlUp).Row
Set orange = Range("B2:B" & LastRow) 'all the segments make an orange
CurrLev = 0 'the "level" of the "segment" - it's level is a measure of how many layers deep the formula is nested
'if(a=1,b,c) is split into 4 components: `if(`, `a=1,`, `b,` & `c)` where `if(` is level 0 and all the other segments are level 1
OBrac = 0 'how many open brackets have happened/ precede a segment of the formula
CBrac = 0 'how many closed brackets have happened
On Error Resume Next
For Each Segment In orange
If InStr(Segment, "(") <> 0 Then
OBrac = OBrac + 1
ElseIf InStr(Segment, ")") <> 0 Then
CBrac = CBrac + 1
End If
Cells(Segment.Row, CurrLev + 3) = Segment 'copies the segment value into a column indented by a number of cells equal to the order of the segment
CurrLev = OBrac - CBrac 'current level is how many brackets have been opened - how many have been closed,
'ie. the number of brackets preceding a segment which are currently open
Next Segment
End Sub
到目前为止我已经走了多远。我真正想要的是将缩进树替换为下拉列表树。对于公式=IF(MAX(arg1,arg2)=1,arg3,MIN(arg1,arg2))
,我想分成若干段:IF(
,MAX(
,ARG1,
,ARG2)
,=1,
,{{1} },ARG3,
,MIN(
&amp; ARG1,
htn显示它们。不像这样:(就像我现在一样)
ARG2))
但是像这样:(或类似的)
IF(
MAX(
ARG1,
ARG2)
=1,
ARG3,
MIN(
ARG1,
ARG2))
当您点击IF(◀
时会变成这样:
◀
然后将IF(▼
MAX(◀
=1,
ARG3,
MIN(◀
扩展为
Min
总结:
IF(▼
MAX(◀
=1,
ARG3,
MIN(▼
ARG1,
ARG2))