VBA使Excel公式更具可读性

VBA使Excel公式更具可读性,vba,excel,excel-formula,readability,Vba,Excel,Excel Formula,Readability,我浏览了一下这个网站,但是关于让Excel公式(公式?)更具可读性的建议倾向于“使用命名范围”或“使用辅助列”。我不追求让公式更容易阅读的技术,我想创建一个宏以更可读的方式显示公式您可以跳到结尾,以获得简短的问题描述。我之所以这样说,是因为尽管我通常喜欢解释我的方法,但这次我觉得我的方法可能会分散我对问题本质的注意力。此外,我认为这个问题可以很好地提炼出来,而不需要前面的所有背景 问题背景 我在nest复杂的公式中有很多讨厌的nest,这里是我今天写的一个(见) 或作为代码: =IFERROR

我浏览了一下这个网站,但是关于让Excel公式(公式?)更具可读性的建议倾向于“使用命名范围”或“使用辅助列”。我不追求让公式更容易阅读的技术,我想创建一个宏以更可读的方式显示公式您可以跳到结尾,以获得简短的问题描述。我之所以这样说,是因为尽管我通常喜欢解释我的方法,但这次我觉得我的方法可能会分散我对问题本质的注意力。此外,我认为这个问题可以很好地提炼出来,而不需要前面的所有背景

问题背景 我在nest复杂的公式中有很多讨厌的nest,这里是我今天写的一个(见)

或作为代码:

=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")
同时,A列查看B列找到的最后一个组件,并将其从长公式中删除(使用
=SUBSTITUTE(A2,B3,“,1)
)。 因此,对于A2中的原始公式(作为文本),B2是它的第一个组件(例如
IF(
,在我的示例中),A3是A2中的公式减去B2中的第一个组件。我向下拖动以进行迭代

宏 这给了我一个列B中每个单元格中公式组件的列表。然后,我的宏决定每个组件的级别,并将组件缩进那么多单元格。级别定义为公式*或代码中“段”组件前面未关闭的开括号数。宏注释解释一下

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(◀   
    =1, 
    ARG3,   
    MIN(◀
然后将
Min
扩展到

IF(▼
    MAX(◀   
    =1, 
    ARG3,   
    MIN(▼
        ARG1,
        ARG2))

缩短的问题描述
总结如下:

  • 我在Excel中有一个公式;Excel中的公式具有一般形式的
    函数(argument1、arg2、arg3…
  • 每个参数可以是简单的(常数、文本字符串、单元格引用),也可以是复杂的(另一个公式有自己的函数和参数)
  • 我想要一个宏,它接受一个输入公式,并创建某种形式的用户界面(如我的示例中的特殊位置单元格,或其他方法),以树状方式显示函数
  • 这意味着在UI的第一层,我显示函数,第二层有函数的参数,如果参数复杂,它们将有更多的子层
  • 要访问子层,可以使用下拉箭头或其他方式展开每个函数,以显示其参数(下面的“层”)。就像Reddit帖子一样,您可以单击[+]以获得更深的一层

我使用这个网站处理长公式,它对我帮助很大

它没有您提到的UI组件,但它在“美化”输出方面做得很好


我个人认为,使用如此庞大的公式是一种非常糟糕的做法。保留一些辅助单元格,以便放置中间公式。好处是:1)可读性和可维护性(可以使用一些有意义的名称命名中间单元格)2)您很快就会发现公式的某些部分被许多单元格共享。然后,您可以在一个中间单元格中只执行一次此计算,而不是在每个公式中重复。您的工作簿将更小更快。似乎有一个免费的工具用于此目的(我还没有使用过),我同意,也不同意!我所说的辅助列是指您所描述的辅助/中间单元格。当我在公式中重复大量代码时,我会使用helper列。我选择了一个不好的例子,因为在这个例子中,我只做了一次。但大多数代码不包含任何重复。在这种情况下,尽管我需要一个解决方案,但公式是复杂的。有时有很多变量需要同时处理。我将相应地更新示例。显然,您可以将许多单元格之间的任何公式拆分,例如将B1单元格中的
=(A1+A2)/A3
拆分为
=(A1+A2)
,将B2单元格中的
=B1/A3
。这使得公式更短,也许更具可读性。但是,除非我重复公式中的代码(如
=(A1+A2)/A3+(A1+A2)^A3)
,否则我反对将公式拆分,因为它实际上妨碍了我对整个公式的理解。既然没有重复的计算,我也不认为用这种方式将其拆分会加快计算。你不能把你拥有的放在树状视图控件中,我不确定我是否理解了你所追求的,这可能是一个无休止的逻辑部分。从我的角度来看,我在设计中使用了很多helper列,如果它们有助于解释错误,那么有时会将它们保留在其中,但如果说今年的上个月,我将作为设计中的一个助手,然后在结束时将其引入公式中。例如,使用了很多helper列,但我不会将它们全部保留,但如果它们有助于解决问题,我会将它们保留在中
IF(◀
IF(▼
    MAX(◀   
    =1, 
    ARG3,   
    MIN(◀
IF(▼
    MAX(◀   
    =1, 
    ARG3,   
    MIN(▼
        ARG1,
        ARG2))