if( ) 函数的基础逻辑判断基础写法多条件判断复杂逻辑判断基础用法案例参考使用 substring() 函数自定义打卡进度条基础写法案例一、基础打卡进度条制作案例二、用 Relation & Rollup 制作进度条更多进度条样式参考系列尾声
在上一篇文章中,我们简单介绍了使用
dateBetween() 函数来制作倒数日的用法:
但有些时候我们可能会想,如果距离截止日期只剩最后一天,那么用「还有」这种说法,是否就显得不那么紧急和严肃了?

或者还有一种可能,随着时间的推进,
dateBetween 计算得出的结果有可能变为负数,这样一来再用「还有 XXX 天」这种表述就变得不够正确了
理想的情况是,我们会希望 Formula 能够根据时间长短的不同,自动变换关于时间的形容词,如果能再加个表示状态的 Emoji 就更好了,就像下图这样:

要想实现这种效果,我们就需要用到 Formula 的
if() 函数,它的基础写法是 if(A,B,C),即如果满足 A 的条件就执行 B,否则执行 C。if( ) 函数的基础逻辑判断
修订注明:Formula 2.0 更新了更好用的 ifs() 函数
基础写法
这个函数需要包含三项参数,每个参数之间用英文逗号隔开,其基本写法是 :
if(条件判断,符合判断则执行1,不符合则执行 2)。例如我们可以这么写
if(1<2,1,2),因为 1<2 的判断是正确的,所以返回了结果 1。
所以在上一篇文章的客户联络表案例中,我们就可以设置为:当时间间隔大于等于 90 天,则 if 函数返回文本
需要联络,否则就返回文本 无需联络,具体写法如下:
请注意,上图中因为我们需要返回的结果是字符串,所以需要为这些文本加上英文引号。
再举一个例子,我们可以使用
if() 函数来判断截止日期是否过期,如果过期则用「已过 XX 天」表示,如果未过期则用「还有 XX 天」:
将这个函数拆开,便于大家观察它的结构和写法

多条件判断
案例一、计算绩效工资
前面我们讲到的 if 函数都只有一层的条件判断,然后根据判断的结果选择两个不同的值,但很多时候我们往往需要做出多层的判断,所以我们需要引入一个在 Formula 2.0 更新中新增的函数 ifs()。
在下面的例子中,如果使用一般的 if() 函数,则需要为每一种情况写一个 if,不仅繁琐还很容易遗漏最后的括号:

但在 ifs() 函数下,我们只需要写一个总的
ifs(),然后列出不同的条件和结果即可:
这样一来设置好「绩效工资」这个公式字段后,当我们更改每个人的「年终评级」这个字段,最终的绩效工资就会相应地有所变化:

if 的另一种写法
前面我们介绍了
if() 函数的基础写法是:if(condition, true_value, false_value),不过在有些博主分享的模板中你可能还会看到另一种写法:condition?ture_value:false_value
在这种写法中,问号之前的是需要判断的条件,问号之后则是「当判断为真」时需要执行的动作,冒号之后的则是「当判断为假」时需要执行的动作。
这个用法也可以用于多条件判断的书写,例如
(1 > 2) ? 1 : ((2 > 3) ? 1 : 3) ,最终输出结果 3。
这种写法可能比较少见,如果你遇见了的话,查看这类嵌套公式有几个技巧:
- 先找到问号,问号之前的就是需要判断的条件
- 再找到冒号,冒号之前的就是符合判断后需要返回的第一个参数
- 冒号之后的则是不符合判断时需要返回的第二个参数,或者继续进行的第二层、第三层的判断条件
复杂逻辑判断
前面我们仅介绍了类似
1>2 或者 字段 1==字段 2 这类简单的判断,正确则为 true,错误则为 false
或者在 if()函数中介绍的也仅是单个条件的判断,例如
(1 > 2) ? "正确" : "错误" :
但很多时候我们需要判断的情况是复杂的,所以接下来要介绍
and() 、or() 以及 not() 这三个逻辑运算符,它们将能更好地适配更多类型的条件判断场景。基础用法
and( ) 函数
语法:
and(A,B)用法:只有当 A 和 B 都为 true 时,才返回 true,否则 false
例如在下图中,左边函数的两个判断都是正确,所以布尔值为 true;右边函数只有一个正确,所以布尔值为 false:

or()函数
语法:
or(A,B)用法:只要 A 或 B 其中有一个是 true,
or()就返回 true
not() 函数
语法:
not()用法: 用于取反操作,如果结果为 true,则返回 false

结合上述三个新增函数,我们试着来构建一个项目管理数据库。
案例参考
在下面的数据库案例中,一共有 12 个项目,每个项目各都含有「任务状态」、「优先级」、「到期时间」以及「执行人」这四个字段:

我们首先使用
and() 和 or() 函数筛选出已经逾期的任务,并且我们对「逾期」的定义如下- 任务状态是
Not started或者是In progress
- 任务到期时间是
今天或者今天之前
这个需求所对应的公式写法如下:
将这个公式逐层拆开
第一步,用
or()函数判断,只要任务状态符合其中之一即为 true:or(prop("任务状态") == "Not started", prop("任务状态") == "In progress")第二步,用
dateBetween() 和 now() 函数计算「今天日期」与「到期时间」的差值,当差值大于等于 0 时即表示任务今日到期,或者任务已超时;第三步,用
and() 判断第一步和第二步,当两者同时符合判断(true)时,就返回 true(打钩)
以上只是使用布尔值所做的简单判断,如果搭配
if() 函数,则可以为任务设置更加个性化的任务提醒标语:
其具体公式如下:
但这时你可能会发现,我们为了筛选出所有状态为
Not started 或者 In progress 的项目,用到了 or() 函数,使得这部分的公式判断变得比较冗长:or(prop("任务状态") == "Not started", prop("任务状态") == "In progress")所以我们还可以用
not() 函数来执行取反的操作,那些状态不包含「Done」的项目,就是我们需要筛选的项目,具体写法如下:
使用 substring() 函数自定义打卡进度条
接下来就要介绍最后一个函数
substring() ,它的应用场景非常多,例如任务进度条、年度进度条等,我想应该有相当一部分立志于学习 Formula 的读者,都会对这个功能感兴趣。这个函数可以让我们实现下图所示的动态进度条的效果:

基础写法
这个函数的基础写法有两种,分别如下:
substring(text,number)
substring(text,number,number)
它的基本原理是,从你给到的字符串中截取出特定长度的内容,例如
substring(“eryinote”,1,5) 表示对 “eryinote” 这个字符串进行截取,截取方式为从左开始删除到第 1 位,然后保留到第 5 位的内容:
substring("eryinote",2,4)表示对 “eryinote” 这个字符串进行截取,截取方式为从左开始删除到第 2 位,然后保留到第 4 位的内容:
或者你也可以只填写一个数字,例如
substring(eryinote,3)表示从最左侧开始,删除到第三位的内容,然后保留剩下所有内容:
需要注意的是,上图中的字符串是自己手打的,所以还需要用英文输入法下的双引号
"" 圈起来,否则将会报错。除了手打的文字可以被
substring()截取,Notion 自带的其他字符串类型的字段也可以被截取,例如 Select 中的字段:
或者使用
formatDate() 函数将日期转换为字符串后,也可以被 substring() 函数截取:
基于以上用法,如果我们能够将
▣▣▣▣▣▣▣▣▣▣ 截取成以下长度:- ▣▣▣▣▣▣▣▣▣▣
- ▣▣▣▣▣▣▣▣▣
- ▣▣▣▣▣▣▣▣
- ▣▣▣▣▣▣▣
- ▣▣▣▣▣▣
这样不就能够构建可动态变化的进度条了吗?接下来让我们实际操作一遍。
案例一、基础打卡进度条制作
在我们先前制作的打卡进度表中,我们成功制作了会随着 Checkbox 的勾选状态而自动计算的打卡进度百分比,如果你已经忘了这部分内容的话,可以回顾《Notion 函数基础入门》的第二篇文章。

现在我们可以把这个能够自动更新的「打卡百分比」,放进
substring() 函数的数字部分,这样一来就可以制作能够动态变化的进度条了:注意,这里之所以要将
prop("百分比进度")乘以 10 ,是因为计算得出的百分比总是小于 1 ,而小于 1 的参数将无法让 substring 截取到任何字符串。
不过上面的效果依然跟我们平时熟悉的进度条不太一样,如果换成下面这样子是不是就好多了:

具体公式写法如下:
可以看到这个公式是用加号
+ 将两个 substring() 函数的字符串拼接在了一起。我们以「百分比进度为 60%」为例,拆解一下两个函数各自的作用:substring("▣▣▣▣▣▣▣▣▣▣", 0,6):保留从 0 位到第 6 位的字符串,以 6 个实心格「▣▣▣▣▣▣」对应 60% 的进度条
substring("▧▧▧▧▧▧▧▧▧▧",6):删除从 0 位到第 6 位的所有空心格,剩下 4 个空心格「▧▧▧▧」
- 最后将 6 个实心格与 4 个空心格进行拼接, 就得到了我们需要的完整进度条
最后我们再在进度条的末尾加上具体的百分比,就更像那么一回事了:

案例二、用 Relation & Rollup 制作进度条
理论上只要数据库中的某个字段是在动态变化的,那么你就可以将这个动态变化的字段转换为数字,然后再放到
substring() 函数中去做进度条。接下来我们先适当回顾一下在《Relation&Rollup》这篇文章中提到过的 Rollup 的动态统计功能。在下图中,我使用 Rollup 功能统计了每个项目所关联的子任务的完成情况,并以百分比的形式显示出来:

如此一来当我们调整子任务的任务状态(Status)时,Rollup 就能即时更新「已完成任务」的百分比进度:
接下来新增一个 Formula 字段,使用
substring() 函数,然后将 Rollup 所得百分比乘以 10,即可获得正确的百分比进度条:
接下来不论我们是为项目新增任务,还是将已有任务的 Status 改为
Complete 状态,都能让这个进度条自动发生变化:
更多进度条样式参考
Notion Formula 进度条的自由度不仅体现在功能实现层面,它的呈现效果也足够丰富多彩,理论上任何字符串或者 Emoji 都可以放进
substring() 函数中,如下图所示:▓▓▓▓▓▓▓▓▓▓ & ░░░░░░░░░░

✦✦✦✦✦✦✦✦✦✦ & ✧✧✧✧✧✧✧✧✧✧

⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ & ⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀

⌧⌧⌧⌧⌧⌧⌧⌧⌧⌧ & □□□□□□□□□□

▰▰▰▰▰▰▰▰▰▰ & ▱▱▱▱▱▱▱▱▱▱

你也可以点击这个模板链接进行浏览和复制。
最后需要注意的是,如果你在进度条中截取的是 Emoji 表情,那么每个 Emoji 的长度是两个字符,也就是说,如果你使用
substring("😄😄😄😄😄😄😄😄😄😄", 0, 6) 这个函数的话,截取出来的将只有 3 个笑脸:
所以如果你需要截取的是 6 个笑脸,就需要使用
substring("😄😄😄😄😄😄😄😄😄😄", 0, 6*2) ,也就是需要将 6 乘以 2 ,这个要点在书写动态进度条的时候需要特别注意,只有将动态变化的数字乘以 2 才能得出正确的进度条结果。系列尾声
一共 3 篇的 Notion 函数基础入门到这里就算完结了,希望能对新手读者起到我所预期的入门指导作用。可以预见的是,这个基础系列必然无法覆盖到所有人的问题或需求,因为就像乐高积木一样,Formula 所能应用到的场景大概是没有上限的,所以一句正确的废话是「举一反三真的很重要」。
并且更重要的一点是,在使用 Formula 之前最好先问一下自己,你的需求是不是真的必须用到 Formula,有没有可能通过新建视图、Filter 以及 Sort 等功能更容易实现?等到一般的功能真的无法满足你的需求,再去研究 Formula 的用法也不迟。
以下内容于 01 月 07 日更新
关于 Formula 2.0 新增的功能和细节更新
本文基于 Formula 2.0 新增的功能和细节,进行了部分细节上的修订和优化
建议先阅读本栏目关于 Formula 2.0 的这篇介绍文章:《功能追踪 01》,了解 Notion 函数的最新写法
以下内容于 2023 年 11 月 12 日更新
关于 Formula 功能的内容更新
关于 Formula 2.0 功能介绍的文章 《功能追踪 01:详细解读 Notion Formula 2.0,这 10+ 个新特性 & 新函数让 Notion 更强大更好用》已发布,在本文修订前,可以先行阅读该文章。
以下内容于 2023 年 09 月 08 日更新
关于 Notion 近期的 Formula 功能更新
Notion 近期对 Formula 进行了巨量的更新优化,包括操作界面、部分函数写法均可能有所变动,但本文整体的使用思路是可以沿用的,您依然可以参考和学习。为了不耽误正篇的更新进度,我将在第五章更新结束后,尽快对本文内容进行修改调整。







