上次对这个Actions and Recommendations进行了初步研究,因为一些问题没有得到很好的解决,又花了很多时间,终于得到了一个比较好的解决方案。小结一下。

1. 生成Actions and Recommendations下栏目最基本的有两种方法:一是通过Deployment,优点是操作简单,另外,还可以很方便地通过点击Add按钮添加项目,缺点是无法定义这些项目显示在A&R下的条件。二是通过Process Builder。官方文档上介绍的主要是这两种方法,另外还有通过Apex或者web service来建。

2.Process Builder的主要优点是比较简单直观,另外的优点主要是因为运行在System Context下,可以不受当前用户的权限限制,而且,通过它去运行某些Flow,同样也在System Context下,不受权限限制。但是,如果通过它去运行Record triggered Flow,则不是在System Context下,因为Record triggered Flow只能运行在当前用户权限下,无法修改这一设置。

Process Builder的主要缺点是:

1)除非触发条件设置得能够保证执行一次后就不可能再触发,或者开始设置成只在建新纪录时才触发,否则因为它无法检查Flow或者QuickAction是否已经存在,会在A&R下重复建项目。

2)在Process Builder下调用Apex,无法获得返回值,相当于只能调用void类型的方法。

3)不支持before saved类型的触发。

2. 另一个方法是用Flow来建,又可分为用Record triggered Flow和Auto launched flow。前者的好处主要是有个$Record变量,不需要再用一个Get Record元素去取当前SObject的信息,另外的优点是支持before saved类型的触发条件。但是缺点一是不能运行在System Context下,某些牵涉到用户权限的需求不能实现。二是$Record变量在调试Flow时反而不方便。

前者的缺点正好是后者的优点,而优点又成了后者的缺点。

而两者共同的优点是

1)可以用图形化的形式定义触发条件,比较适合编程经验少,但熟悉业务逻辑的管理员和业务分析员

2)调用Apex,可以获得返回值。

两者共同的缺点就是某些操作比较笨拙。比如遍历时,实现如下的逻辑:

bool isFound = false;

foreach (foo in bar) {

if (满足某个条件) {

isFound = true;

break;

}

}

if (isFound == true) {//后续操作

}

如果用Flow来实现就很麻烦,无法实现上面的break操作,只能全部遍历完再来判断isFound == true。

3. 不管用哪种方法,在A&R下显示项目,本质是对RecordAction对象的操作。下面谈有关的问题。第一个问题:如何避免在A&R下生成重复项?

固然可以用Flow来实现,但很麻烦,所以考虑用Apex。因为业务逻辑放在Flow里比较好,所以打算用Apex来找出已经存在的RecordAction,然后返回Flow尚未存在,需要创建的RecordAction。然后Flow里设置触发条件,再用Creat Record元素来建RecordAction。这是最初的设计。

后来发现主要缺点是Flow里的元素比较多,线条很多,看上去有点乱。但这还不是主要问题,碰到了第二个问题:如何当一个Flow执行一遍,完成之后,避免在A&R下再次生成项目?

因为Flow完成后,只要刷新页面,对应的RecordAction就会自动删除,然后就只有在RecordActionHistory里才找得到踪迹。而RecordActionHistory是所谓的Big Object,不能在触发器里直接查询,一查就报错。虽然调试Flow的时候好好的,不出错,但一旦正式运行,马上出错。

为了解决这个问题,先是发现QuickAction执行后,对应的RecordAction不会删除,就考虑用QuickAction来包装Flow。但发现QuickAction缺省是在一个模态框里显示,而Flow缺省应该是在一个Tab里显示,结果被QuickAction包装后,也执行在模态框里,界面很难看。只好又做了个Lightning  Component,用它打开另外一个Lightning Component,并显示在Tab里,在第二个Lightning Component里再去运行Flow。然后把第一个Lightning  Component加到QuickAction里,就基本做好了。显然,一层套一层,很麻烦。而且很快发现一个问题。就是QuickAction的RecordAction不会显示Complete状态(所以它不会被删掉),但这样一来,也无从得知Flow到底有没有运行完。

做了半天白做了,还好柳暗花明又一村,终于又找到一个办法,就是用future方法也即异步模式去查RecordActionHistory。

同时,修改了设计,用apex实现查找已存在的RecordAction和已经执行完毕的Flow类型的RecordAction(QuickAction类型的还是没法查),然后直接用apex创建RecordAction。这样一来,查找,创建的功能全移到apex,Flow那头只剩下定义触发条件和给apex提供输入参数的几个元素,顿时清爽了许多。

从Flow调用apex(用Process Builder也一样),需要在apex类里定义一个带@invocableMethod属性的方法,而且一个类里只能有一个方法带此属性。另外,只允许一个输入参数。如果输入参数是List<foo>,表面看来是个List,实际上只能传入一个对象,如果需要传入多个对象,有个技巧,就是把输入参数定义为List<List<foo>>,再套上一个List,就能传入多个值了。

还有前面已经提到,Flow里的PickList域,传到apex后,需要用String.valueOf()才能取值,否则报cast错误。这是Salesforce的bug。

另外,在带@invocableMethod属性的方法里可以调用带@future属性的方法,也是诸多限制。首先不允许传对象类型的参数,只能传List<String>或者多个String或其他原始类型的参数,其次@future方法只能是void类型,没有返回值,而且不能设置回调函数!,也不能在@future方法里,再去调用别的@future方法。所以没办法,只能把对象平展成字符串,传进去之后再拼装成对象。不管怎么样,好歹终于解决了第二个问题:当一个Flow执行一遍,完成之后,避免在A&R下再次生成项目。缺点主要是一是QuickAction类型的RecordAction仍然没有办法,只能通过修改QuickAction后面的Flow,在执行完毕时修改SObject里自定义的IsFlowRun域来判断Flow是否运行过了。二是用@future方法,反应稍有些慢(因为是异步,无法保证何时响应)。不过异步的Governor Limit比同步方式大很多,这方面的顾虑可以少些。而且结合Deployment,用户可以手工在A&R下添加。这样总算比较满意地解决了这个问题。

意犹未尽,又添加了一些功能,比如允许用户指定不需要查RecordActionHistory,甚至可以允许重复项。还允许当Flow的触发条件不满足时,删除对应的RecordAction。因为@invocableMethod只能传一个参数,Flow里又难以使用自定义对象,所以只好在RecordAction的Status域上做文章,自己定义Unlinked表示删除,Paused表示不需要查RecordActionHistory,Started表示允许重复项。缺省的New则表示不允许重复项,也必须查RecordActionHistory。这样,功能又增强了。

补充:

开始时把所有查RecordAction和RecortActionHistory的操作全部放在@future方法里,但在调试时发现无法删除记录,插记录时也有问题,移出来就好了。看来这个@future方法很tricky,尽量避免。最后修改为只有查RecortActionHistory的功能放在@future方法里,同时添加代码,在@future方法里再查一次RecordAction,因为@future方法执行时,说不定对象有变化,再查一次比较保险。

另外将来如要再拓展功能,也许可加一个用户自定义对象,这样在Flow里设参数就方便了,不用再利用RecordAction的Status域。现在先对付着用。

在折腾A&R的过程中,接触了一些相关技术,使用了一些相关工具,得到不少副产品,算是有所收获。

Salesforce学习笔记之Actions and Recommendations(续)的更多相关文章

  1. Salesforce学习笔记之Actions and Recommendations

    设置Actions and Recommendations(Salesforce提供的标准元素),Salesforce上的文档说有两种方法,即Deployment和Process Builder(通过 ...

  2. Caliburn.Micro学习笔记(二)----Actions

    Caliburn.Micro学习笔记目录 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions, ...

  3. Salesforce学习笔记之代码若干

    有几段试验性的代码因为公司要更新沙盒,删除了.在本地虽然还保存了副本,但怕以后刷新时误删,所以贴一份在这里,以便需要时拷贝. 1.用aura组件包装一个flow foo.cmp: <aura:c ...

  4. Salesforce学习笔记之吐槽

    迄今感到的几个不方便 1. SOQL里没有SELECT * ,只好根据参考手册和用vs code的一个插件Schema Explorer来辅助生成SELECT语句. 2. SOQL不支持注释,Deve ...

  5. Salesforce学习笔记(一)

    Force平台简介 一.Force平台应用程序的优点1.以数据为中心的应用程序(一个对象就是一个数据库表) 由于该平台以数据库为中心,它让你能够编写以数据为中心的应用程序.以数据为中心的应用程序是基于 ...

  6. C++STL标准库学习笔记(四)multiset续

    自定义排序规则的multiset用法 前言: 在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标记了出来,只不过这一次的笔记主要是我的补充 ...

  7. 58、salesforce学习笔记(五)

    Set集合 Set<String> set1 = new Set<String>(); set1.add('1'); set1.add('2'); Set<String& ...

  8. 56、salesforce学习笔记(三)

    Date类型 Datetime nowDatetime = Datetime.now(); Datetime datetime1 = Datetime.newInstance(2015,3,1,13, ...

  9. 54、salesforce学习笔记(一)

    Decimal priceDecimal = -4.50; System.debug('小数的绝对值为:'+priceDecimal.abs()); System.debug('priceDecima ...

随机推荐

  1. iOS倒计时button闪烁

    v _button.titleLabel.text = [NSString stringWithFormat:@"%d后重发",t]; [_button setTitle:[NSS ...

  2. http连接,缓存,cookie,重定向,代理

    早期的HTTP协议使用短连接,收到响应后就立即关闭连接,效率很低:   HTTP/1.1默认启用长连接,在一个连接上收发多个请求响应,提高了传输效率:   服务器会发送“Connection:     ...

  3. three.js 欧拉角和四元数

    这篇郭先生就来说说欧拉角和四元数,欧拉角和四元数的优缺点是老生常谈的话题了,使用条件我就不多说了,我只说一下使用方法. 1. 欧拉角(Euler) 欧拉角描述一个旋转变换,通过指定轴顺序和其各个轴向上 ...

  4. python的__get__方法看这一篇就足够了

    get类型函数 直接上代码: class TestMain: def __init__(self): print('TestMain:__init__') self.a = 1 if __name__ ...

  5. SpringBoot+Vue项目上手

    博客 https://gitee.com/RoadsideParty/White-Jotter-Vue?_from=gitee_search UI框架 https://at-ui.github.io/ ...

  6. MYSQL_详细基本命令

    修改新密码:use mysql:update user set password='新密码' where user='用户名':flush privileges:  更新权限 增加新用户:grant ...

  7. variable ans might not have been initialized 报错,以及初始化注意点

    他是说你没有初始化而已,一般只是个warning,如果是在不能跑,那就给他初始化一下. 注意,初始化可不是任意值哈! 就比如如果要算阶乘,你初始化就不能为0. 还有如果是比较大小这类,就不要把初始化统 ...

  8. 读书笔记《数据结构与算法JavaScript描述》第一章

    第一章JavaScript的编程环境和模型 1.2JavaScript编程实践 1.2.1 声明和初始化变量 JavaScript中的变量默认为全局变量,如果初始化未被声明的变量,该变量就成了一个全局 ...

  9. loj #6177. 「美团 CodeM 初赛 Round B」送外卖2 状压dp floyd

    LINK:#6177.美团 送外卖2 一道比较传统的状压dp题目. 完成任务 需要知道自己在哪 已经完成的任务集合 自己已经接到的任务集合. 考虑这个dp记录什么 由于存在时间的限制 考虑记录最短时间 ...

  10. luogu 1587 [NOI2016]循环之美

    LINK:NOI2016循环之美 这道题是 给出n m k 求出\(1\leq i\leq n,1\leq j\leq m\) \(\frac{i}{j}\)在k进制下是一个纯循环的. 由于数值相同的 ...