Salesforce Lightning 开发(1)

学习目标

完成本单元后,您将能够:

  • 命名并描述开发Web应用程序的两种模型之间的区别。
  • 描述使用Visualforce处理构建Web应用程序的两种不同方式。
  • 使用Visualforce或Lightning组件描述构建Web应用程序的优势和折衷。
  • 列出至少三种不同的使用Lightning组件或Visualforce的方案。

提高Web应用程序用户界面的性能

在过去十年或更长的时间里,我们都看到了不断提高Web应用程序的用户体验。用户希望能够在触手可及的情况下获得响应式,功能齐全,高度互动的身临其境的体验。

我们首先在单一用途的应用程序中看到这一点Google地图等服务引入了用户界面元素的直接操作。分析应用程序带来了动态的交互式图表下钻。当用户输入无效的数据,动画,转换等时,即使是不起眼的注册或登录形式也会带有动态的错误反馈。交互性不再是新鲜事物,这是常态。

规模已经扩大。单个组件的期望已经迅速扩展到核心应用程序体验。今天,Web应用程序具有滑动菜单,动画页面转换和动态主控细节等功能。还有应用程序样式的元素,如覆盖和模式窗口。原生应用程序和Web应用程序之间的差异从来没有变小。

那么这对Salesforce意味着什么呢?

传统的Salesforce体验被称为Salesforce Classic,是以页面为中心的Web应用程序模型的一个示例。对于基本功能来说,这非常棒,但是提供用户所期望的新的,更加动态的体验是一项挑战。从根本上说,这是因为它每次与应用程序交互时都依赖于服务器生成一个新页面。

为了提供更多的互动体验,您需要客户端的JavaScript帮助。在这个以应用程序为中心的新模型中,JavaScript被用来创建,修改,转换和动画用户界面,而不是一次完全替换一个页面。这个模型是令人兴奋的,互动的,流畅的。这是新的闪电体验。

以页面为中心的模型和以应用为中心的模型都在这里。快速浏览Web足以证明大多数Web应用程序都利用了这两种方法。结合这些模型,应用程序可以为正确的用例提供正确的体验类型。

让我们花一些时间来探索Salesforce Platform为这些模型提供的不同选项。

Classic Visualforce

Visualforce是构建以页面为中心的应用程序的强大成熟平台。 Visualforce框架提供了一组强大的标签,这些标签在服务器上解析,并与标准或自定义控制器一起使用,以使数据库和其他操作易于实现。

让我们回顾一些基础知识。

UI 生成
服务器端
数据和业务逻辑
Apex标准或自定义控制器
工作流程
  1. 用户请求一个页面
  2. 服务器执行页面的底层代码,并将生成的HTML发送到浏览器
  3. 浏览器显示HTML
  4. 当用户与页面交互时,返回到第一步
优点
  • 尝试和真正的模型
  • 易于实现更高的生产力
  • 将大型应用程序自然地分割成小的,可管理的页面
  • 具有内置的元数据集成
注意事项
  • 有限的交互性(除了增加的JavaScript功能)
  • 更高的延迟,降低移动性能

Visualforce在概念上类似于其他以页面为中心的技术,如PHP,ASP,JSP和Ruby on Rails。 Salesforce丰富的元数据基础架构使Visualforce成为高效的解决方案。标准的控制器可以很容易地直接访问对象,并通过关系而不需要执行一个查询。其他元数据感知组件类似的即插即用:添加标记到一个页面,你就完成了。这些功能在平台上依然存在,并且仍然适用于许多用例。

Visualforce作为JavaScript应用程序容器

当您考虑它时,Visualforce页面只是HTML页面,服务器解析了额外的标签。因此,您可以使用一个空的Visualforce页面作为JavaScript应用程序的容器。在这种情况下,您不使用Visualforce标记来构建您的用户界面。相反,您将您的JavaScript应用程序加载到空白页面中。然后用户界面由JavaScript应用程序在客户端生成。这些应用程序通常被称为单页面应用程序或SPA,通常使用第三方框架(如AngularJS或React)构建。

让我们回顾一些基础知识。

UI 生成
客户端(主要是JavaScript)
数据和业务逻辑
远程对象或JavaScript Remoting,Apex控制器
工作流程
  1. 用户请求包含页面框架和JavaScript包含的“空白”Visualforce页面
  2. 该页面被返回到浏览器
  3. 浏览器加载JavaScript应用程序
  4. JavaScript应用程序生成UI
  5. 当用户与应用程序交互时,JavaScript会根据需要修改用户界面(返回上一步)
优点
  • 实现高度互动和身临其境的用户体验
注意事项
  • 复杂
  • 没有内置的元数据集成
  • 缺乏集成的开发人员经验。 Force.com开发者控制台不明确支持这些JavaScript应用程序。通常情况下,你必须将它们作为静态资源加载,这是一个繁琐的经验。

我们想清楚。如果你能忍受我们所描述的警告,那么今天就构建交互式应用程序是一个非常好的方法。这就是我们最初构建远程对象和JavaScript远程处理等工具包的原因。如果您是一个有信心的AngularJS或React或其他JavaScript框架开发人员,那么您的专业知识将为您带来所需的工具,为Salesforce开发应用程序。

但是,如果你愿意接受新的东西,我们认为我们对于基于网络的应用程序开发的下一个层次有一些很好的想法。

Lightning 组件

Lightning组件是用于为桌面设备和移动设备开发动态Web应用程序的新的Salesforce用户界面框架的一部分。他们在客户端使用JavaScript,在服务器端使用Apex来提供数据和业务逻辑。

我们来看一下概述。

UI 生成
客户端(JavaScript)
数据和业务逻辑
Lightning Data Services,Apex控制器
工作流程
  1. 用户请求应用程序或组件
  2. 应用程序或组件包被返回给客户端
  3. 浏览器加载该包
  4. JavaScript应用程序生成UI
  5. 当用户与页面交互时,JavaScript应用程序根据需要修改用户界面(返回上一步)
优点
  • 实现高度互动和身临其境的用户体验
  • 与Salesforce用户界面策略保持一致
  • 建立在元数据的基础上,加快发展
  • Force.com IDE和开发者控制台都支持Lightning组件,提供了集成的开发者体验
注意事项
  • 与Visualforce相比,更陡峭,学习曲线更长
  • 比Visualforce更高的复杂性 – 你正在构建一个应用程序,而不是一个页面
  • 由于Lightning组件是新的,所以仍然有一些功能不被支持
  • 有一些开箱即用的组件

我们需要与你直接相处。这些警告是不小的考虑。我们将会谈谈他们如何适用于您的组织。但!我们正在努力 – 真的很努力 – 减少这些考虑的大小。我们非常激动,尽快为您带来改进。

为工作选择合适的工具

Visualforce已经有一段时间了,它是一个成熟的,很好理解的构建应用程序的平台。它不会消失。闪电组件是块上的新生儿。它有很多事情要做,但是,你知道的。你现在对你来说是陌生人。

这是事情:你不必选择一个或另一个。

将以页面为中心和以应用程序为中心的模型看作是开发工具中的工具 – 一个并不总是比另一个好,如果你了解自己的优势和权衡,你就能从中获得最大收益。使用正确的工具来完成手头的工作。

这里有一些指导方针可以帮助你决定 – 但是请记住,你是决定者。最后,使用感觉正确的工具。另外,请记住,工具的发展。这些指导方针也将发展。

工作 建议
我正在开发闪电体验 我们强烈推荐Lightning组件。 Lightning组件搭建了闪电体验,两人手和手套配合在一起。
如果您有现有的代码或正在进行的项目,您当然可以使用Visualforce。完全支持Visualforce for Lightning Experience,但有一些限制。

但是,对于Lightning Experience,您找不到比使用母语Lightning Components更好的工具。

我正在开发Salesforce Mobile应用程序 我们推荐Lightning组件。 Visualforce特性,特别是以页面为中心的方向,对于有限的高延迟网络连接和有限的计算资源的移动应用来说可能是一个糟糕的结果。相比之下,Lightning组件专为处理这种情况而设计。
Visualforce和Lightning组件都使用类似的基于标记的标记。例如,输入字段的Visualforce标记是<apex:inputText>,而Lightning组件是<lightning:input>。

那有什么区别?那么,Visualforce会在Salesforce服务器上处理标记代码。 Lightning Components在客户端处理标记。客户端处理的优点是整个页面的HTML块不会在客户端和服务器之间来回传递。

除少数例外,Lightning组件更适合Salesforce移动开发。有些情况下需要Visualforce作为JavaScript应用程序。有关更多信息,请参阅“Lightning组件开发者指南”。

我正在用有限的客户端逻辑构建一个以页面为中心的体验 使用Visualforce页面来确保开发速度和可管理性。
我正在使用JavaScript构建交互式体验以满足用户体验要求 使用Lightning组件,但首先参考限制文件。
我致力于JavaScript框架,如AngularJS或React 将Visualforce页面用作第三方框架(如AngularJS或React)和您的应用程序的容器。
我正在启用非开发人员通过组装标准组件或自定义组件来构建应用 程序使用Lightning组件来创建可在Lightning App Builder中使用的自定义组件。
我使用JavaScript构建交互式体验,我需要第三方框架 将Visualforce页面用作第三方框架(如AngularJS或React)和您的应用程序的容器。
我添加用户界面元素 例如,假设你想添加一个标签到一个记录家里。这个任务是一个简单的拖放在Lightning应用程序生成器。使用Lightning组件创建自定义用户界面元素。
我正在为客户建立一个社区 使用社区生成器,利用Lightning组件创建一个基于Lightning的社区。
我正在为合作伙伴建立一个社区 使用社区生成器,利用Lightning组件创建一个基于Lightning的社区。
我正在揭露面向公众的未经认证的网站 使用社区生成器,利用Lightning组件创建基于Lightning的网站。
我在我的应用程序中将页面呈现为PDF 使用Visualforce。 Lightning组件不支持渲染为PDF输出。
我使用大量Visualforce页面添加到现有项目继续使用Visualforce。 考虑使用Lightforce组件为Visualforce机会性地移动元素到Lightning组件。
我致力于投资最新的技术 你跟我们在一起! 潜入闪电组件。 从Lightning Components Basics Trailhead模块开始。
我正在开始一个全新的项目 使用闪电组件。 如果你不熟悉他们,现在没有比现在更好的时间学习了!

为您的组织选择正确的工具

当你考虑选择一个工具时,重点不仅仅是手头上的工作。你也想考虑你的组织作为一个整体,你在你的组织中的角色。让我们看看一些不同的角色如何最好地利用Salesforce的开发模式。

角色 建议
ISV合作伙伴 开始在新应用程序中使用Lightning组件或在现有应用程序中使用新功能。在Salesforce Classic和Lightning Experience中将这些单位打包供订户使用。
SI 开始使用Lightning组件进行新的实现。对于正在进行的实施,请继续使用Visualforce。
专业开发人员谁是JavaScript的大师和Visualforce的经验 继续使用您的首选JavaScript框架使用Visualforce。探索闪电组件,并考虑切换线路。
公民使用标准的Visualforce组件的开发人员页面 继续使用Visualforce,但考虑检查Lightning App Builder。
指向并点击管理员 使用Lightning App Builder创建应用程序和自定义。与开发人员和合作伙伴联手构建自定义的Lightning组件。

迁移到闪电组件

这是个好消息。尽管转向Lightning Experience并加大了对Lightning组件的关注,但您的Visualforce页面仍然适用于Salesforce。无论您使用的是新界面,还是您的老朋友Salesforce Classic-Visualforce都可以使用这两个界面。您不必将任何现有的Visualforce页面转换为长时间使用它们。

但是,由于Web应用程序正在更多地利用以应用程序为中心的模式,因此我们鼓励所有Salesforce开发人员至少了解Lightning组件的基本知识。您将要在将来的开发工作中使用这些组件。

现在是您迈出第一步的最佳时机。用于Visualforce的Lightning App Builder和Lightning Components等功能可让您“将脚趾浸入水中”,并尝试在新页面或现有页面中使用Lightning组件。您可以在Lightning Experience和Salesforce Classic中使用这些嵌入式组件。这很容易,你会坚持不要试一试。

我们知道,迁移到新的开发框架是令人生畏的。但我们在这里为你。这条线索加载了您需要成功采用Lightning Experience开发的所有技巧,技巧和陷阱。

Salesforce 配置移动端(5)

学习目标

完成本单元后,您将能够:

  • 描述在移动导航菜单中显示的元素。
  • 解释智能搜索项目如何影响移动用户。
  • 自定义手机导航菜单。

指出用户在正确的方向

如果你曾经去过机场,你可能会看到一些大的路标,帮助你找到自己的方向,并找到前往某些地点的路线,例如行李提取或特定的门牌号码。

那么,我们需要视觉线索来找到我们的应用程序的方式。这就是移动导航菜单:路标。您的用户依靠它可以尽可能高效地在Salesforce移动应用程序中从一个地方到另一个地方。

因此,让我们来看看导航菜单中的元素,并讨论如何定制它们以满足用户的需求。因为毕竟,一个路标只有在把人们指向他们真正想要去的地方的时候才是有效的。

移动导航菜单

在我们进入定制选项之前,让我们熟悉导航菜单本身。默认情况下,用户在菜单中看到的内容取决于组织中可用的内容以及允许他们访问哪些标签(基于用户权限)。

在Salesforce应用程序中工作时,您可能会注意到菜单中有相当多的项目。我们不会在这里定义每一个。如果您对手机应用程序中显示的任何菜单项感到困惑,请参阅此帮助文章。

您可能还注意到,菜单中的项目被分组为几个部分。我们确实需要讨论不同的部分,因为它们对您定制菜单的方式有很大的影响。那么我们来分解一下每个部分的内容。

A diagram that calls out the three sections of the navigation menu

  1. 菜单项目: 当您自定义导航菜单时,您放置在“智能搜索项目”元素上方的任何项目。
  2. 智能搜索项目: 包含一组用户最近访问的对象。展开后,会显示用户可以访问的所有标签。尽管您可以控制这些最近项目出现在菜单中的哪个位置,但每个用户的列表都是特定于其自己的使用历史的。
  3. 应用程序部分: 包含您放置在智能搜索项目元素下的任何项目。

你可以改变什么

为您的用户改善移动体验的一个简单方法是微调导航菜单,以便他们可以更快地完成任务。当您自定义导航时,您可以添加,移除或重新排列移动菜单中的项目。 (嘿,也许我们可以称之为导航布局,哈!只是在开玩笑,没有更多的布局,我们保证。)

请记住,菜单的“最近”部分是动态的。它根据用户最近在移动应用中访问的内容而改变。因此,虽然您可以将“最近”部分移到菜单中的其他位置,但您不能控制显示在其中的项目。

关于移动导航的说明

在您定制移动导航菜单时,请记住一些重要的事项。

  • 您不能为不同类型的用户设置不同的菜单配置。
  • 如果要在移动导航菜单中包含Visualforce页面,闪电页面或闪电组件,则必须为其创建选项卡。
  • 在将Visualforce页面添加到Salesforce应用程序之前,请确保已启用移动页面。在Salesforce应用程序中彻底测试Visualforce页面,因为它们在移动应用程序中并不总是相同。请参阅资源部分了解更多信息。

自定义导航菜单

好,足够的序言!卷起你的袖子,准备好帮助DreamHouse经纪人在移动应用程序中拉链,像经验丰富的专业人士。

D’Angelo想要定制导航菜单,以便最重要的项目位于顶部。他还希望手机登录页面成为“事件”选项卡,以便经纪人可以立即看到他们的放映时间表和其他会议。

  1. 从设置中,在快速查找框中输入导航,然后选择 Salesforce1 Navigation.
  2. 重新排列所选项目,以便前五项按以下顺序排列:事件,Chatter,任务,仪表板和智能搜索项目。订单确定项目在导航菜单中的显示方式。

    注意

    列表中的第一项成为用户的移动着陆页。明智地选择第一个项目。

    请记住,智能搜索项元素下面的任何内容都会显示在导航菜单的“应用程序”部分。

  3. 现在让我们删除一些经纪人不需要看到的项目:批准和暂停流程访谈。

    A screenshot of the selected items for the navigation menu

    如果您的任何用户拥有Android设备,请勿从菜单中删除智能搜索项目。他们将无法在Salesforce for Android应用程序中获取搜索结果。

  4. 点击 Save.

在Salesforce应用程序中测试您的更改

你知道该怎么做!我们来看看改进的导航菜单在移动应用程序中的外观。

  1. 在移动设备上打开Salesforce。
  2. 点击导航菜单图标Navigation Menu Icon打开导航菜单。
  3. 拉下来刷新。

我们所有的小调整都反映在菜单中。随着最后一块定制,我们已经完成了我们的移动任务! D’Angelo可以放心地将Salesforce应用推广到DreamHouse经纪商,不久之后他们将享受到移动提供的所有生产力收益。

下一步

那么,这对D’Angelo来说是个好消息。但是你的组织呢?你如何将新发现的知识转化为行动?现在,您已经习惯了移动定制工具,接下来该做什么。

  1. 查看Salesforce Mobile App推出模块。开始开发您的移动用例并规划您的移动启动。
  2. 阅读有关Salesforce移动应用程序安全性和合规性的内容,以便从移动设备访问时确保公司的数据安全。
  3. 将Salesforce应用程序展示给用户。
  4. 了解如何使用移动应用程序做更多。 Salesforce Mobile App开发人员指南是一个很好的开始。
  5. 获取您的移动策略开发徽章,了解Salesforce如何适应您公司的整体移动策略。

这足以让你在一段时间内保持忙碌。现在在Salesforce应用程序中继续实现您自己的真棒用例。快乐定制!

Salesforce 配置移动端(4)

学习目标

完成本单元后,您将能够:

  • 解释为什么定制小型布局非常重要。
  • 创建一个新的紧凑布局。
  • 为用户分配一个紧凑的布局。

移动定制更有趣

现在,您可以快速操作黑带,我们可以继续使用下一个移动定制工具。在本单元中,我们向您介绍紧凑的布局。

在深入之前,我们只想承认整个“布局”的东西可能会令人困惑。行动布局…全局发行商布局…页面布局…紧凑的布局。为了大声哭泣,一定要有一个布局?

嗯,是。这是Salesforce如此灵活的CRM平台的一部分。你可以自定义外观的东西,我们是真的在布局的接缝爆裂。但是别担心一旦你熟悉所有的定制工具,你甚至不会再考虑这个术语。

那么什么是一个紧凑的布局?

紧凑的布局

在Salesforce移动应用程序中打开记录时,可以在页面的标题中看到关于该记录的高亮显示。紧凑的布局控制标题中出现的字段。对于每个对象,最多可以分配四个字段以在该区域中显示。

不需要为对象创建和自定义压缩布局,因为系统默认是开箱即用的。但是,我们建议使用紧凑的布局将重要的字段放入记录标题中,以帮助您的移动用户快速获取所需的信息。

我们来看一个来自DreamHouse Realty的例子。 D’Angelo一直在试验Property对象的紧凑布局,他对结果感到满意。在自定义对象的紧凑布局之前和之后,查看移动应用程序中属性标题的屏幕截图。

The header of a property record that shows the street name, price, status, and number of bedrooms summarized at the top

相当好的一个改进,对吧?如果您将关键字段放在对象的紧凑布局上,移动用户可以扫描页面标题,并一目了然地查看重要细节。

创建一个紧凑的布局

D’Angelo已经处理了属性对象的紧凑布局,但他还没有定制自己的记录头。他还希望改善联系人详细信息页面的外观,以便为联系人对象创建一个简洁的布局。然后经纪人可以尽可能快地获得有关潜在买家的信息。

  1. 从联系人的对象管理设置中,转到精简布局,然后单击新建。
  2. 在字段标签字段中,输入移动联系人布局。
  3. 将以下字段添加到布局:名称,电话,Stage,电子邮件。
    您最多可以包含10个字段,但只有四个字段会显示在移动应用程序中。另外,并不是所有的字段都出现在列表中。紧凑的布局不支持文本区域,长文本区域,富文本区域或多选选项列表。
  4. 通过选择它们并点击向上或向下来排序字段。请务必首先将对象的“名称”字段放在用户查看记录时为用户提供上下文。

    A screenshot of the selected fields for the contact compact layout

  5. 点击 Save.

将精简版式分配给用户

尽管我们创建了一个紧凑的布局,但Salesforce应用程序将继续使用系统默认设置,直到我们另行通知为止。所以现在我们只需要将我们的新布局设置为联系人对象的主布局。需要注意的是:与页面布局不同,您可以为每个配置文件分配不同的布局,一个紧凑的布局适用于所有用户。

  1. 点击 Compact Layout Assignment.
  2. 点击 Edit Assignment.
  3. 在主要联系人布局下拉列表中,选择 Mobile Contact Layout.

    A screenshot of the new compact layout selected as the primary layout

  4. 点击 Save.

    提示

    如果一个对象有多个记录类型,当您选择主要布局时,您将看到一个Record Type Overrides部分。有了它,您可以将特定的紧凑布局分配给不同的记录类型。

在Salesforce应用程序中测试精简布局

现在是时候切换到移动应用程序,以便我们可以享受我们的劳动成果。让我们来看看我们的潜在买家的新的联系方式详细信息页面。

  1. 在您的设备上打开Salesforce。
  2. 点击导航菜单图标Navigation Menu Icon打开导航菜单,然后点击 Contacts.
  3. 选择您之前创建的联系人。
  4. 拉下来刷新记录标题。

    A screenshot of the new contact header with helpful information

TA-DAH!联系人详细信息页面有一个圆滑的新标题。当然,这是一个小小的改变。但这就是定制过程的工作原理。所有这些小小的变化加起来,给移动用户带来了不同的世界。

在下一个单元中,我们通过学习如何修改移动导航菜单来完成我们的移动定制工具的旋风之旅。

Salesforce 配置移动端(3)

学习目标

完成本单元后,您将能够:

  • 创建一个对象特定的操作。
  • 将动作添加到对象的页面布局。
  • 在Salesforce移动应用程序中测试对象特定的操作。

Quick Actions: 续集

在这一点上,您可以感到非常自豪的移动定制技能。您是创建全局行动的专家,您已经准备好迎接下一个挑战:对象特定的操作。不要害怕 – 创建特定于对象的动作的过程与创建全局操作非常相似,因此这个单元将变得轻而易举。

Salesforce应用程序中的特定于对象的操作

为了开始讨论特定于对象的操作,让我们来讨论一下它们与全局操作有什么不同。

  • 对象特定的操作可以更新记录。
  • 对象特定的操作可以创建与相关信息自动关联的记录。例如,用户可以发起同时创建联系人并将其与客户相关联的操作。

还有一个更大的差异。为了在移动应用程序中公开特定于对象的操作,您不要像在最后一个单元中那样将它们添加到全局发布者布局中。而是通过编辑对象的页面布局来让用户可以使用它们。你会看到所有这些行动的差异 – 双关语意图! – 当你走过这个单位的步骤。

让我们来看看D’Angelo用于特定对象操作的用例,以便我们开始构建一些很酷的东西。

DreamHouse情景

当D’Angelo与几个DreamHouse Realty经纪人搭档时,他注意到他们花了很多时间向潜在买家展示物业并管理他们的时间表。他希望让经纪人能够快速安排Salesforce应用程序中的新展示,因此他将创建一个将显示在联系人详细信息页面上的操作。

A broker who is looking at her phone while standing in front of a For Sale sign

奠定基础

要模拟DreamHouse用例,首先需要在自己的org中构建一些东西。现在,现在…没有抱怨。我们承诺这将是值得的。在真实世界的场景中,您将看到特定于对象的动作的力量,另外您还可以练习恶意的平台构建技能。

创建Property自定义对象

经纪人很难安排一个新的展示,而不能把它与一个特定的财产联系起来。他们怎么知道哪个房子展示?所以我们来创建一个名为Property的自定义对象。

如果您在Trailhead上获得“数据建模”徽章时在组织中创建了Property对象,则可以跳过此步骤。

  1. 从对象管理器中选择 Create | Custom Object.
  2. 在标签字段中,输入 Property.
  3. 在复数标签字段中,输入 Properties.

    A screenshot of the custom object's details

  4. 在“可选功能”部分中,选择 Allow Activities.
  5. 点击 Save.

现在我们将为Property对象创建一个自定义选项卡。

  1. 在快速查找框中输入选项卡,然后选择选项卡。
  2. 在自定义对象选项卡列表中单击新建。
  3. 在“对象”下拉列表中,选择“Property”。
  4. 对于“标签样式”,选择“房地产标志”。
  5. 点击下一步。接受默认值,然后再次单击下一步。
  6. 点击保存。

自定义显示的事件对象

你是一个精明的管理员,所以你可能猜到一个展示是一种事件。但D’Angelo不希望使用标准事件进行放映,因为用户需要输入关于它们的额外信息,例如相关资产和买方的反馈。

处理这种自定义挑战的最佳方式是使用具有自己页面布局的新事件记录类型。让我们专门为展示创建一个页面布局,然后创建一个事件记录类型并将其链接到新的页面布局。

  1. 从事件对象管理设置,转到页面布局,然后单击新建。
  2. 从“现有页面布局”下拉列表中选择“事件布局”。
  3. 在页面布局名称字段中,输入 Showing Layout.

    A screenshot of the new page layout's details

  4. 点击 Save.
  5. 从事件对象管理设置中,转到记录类型并单击 New.
  6. 在记录类型标签和记录类型名称字段中输入Showing。

    A screenshot of the new record type's details

  7. 点击 Next.
  8. 在“将一个布局应用于所有配置文件”下拉列表中选择显示布局。

    A screesnhot of the page layout assignment for the new record type

    此布局仅适用于显示记录类型。标准事件记录类型继续使用事件布局。

  9. 点击 Save.

为展示创建一个查找字段

挂在那里!这是最后一步。我们只需要创建一个自定义Property字段,以便经纪人可以将Showing与Property关联起来。我们通过从活动对象到Property对象的查找来做到这一点。

  1. 从“活动对象管理”设置中,转到“字段和关系”,然后单击“新建”。
  2. 选择查找关系,然后单击下一步。
  3. 在“相关”下拉列表中,选择“Property”,然后单击“下一步”。
  4. 在字段名称和字段标签字段中输入Property,然后单击下一步。
  5. 选择Visible复选框,以便该字段可用于所有配置文件,然后单击下一步。
  6. 取消选择事件布局和任务布局。我们只希望这个字段出现在Showing布局上。

    A screenshot of the Showing Layout as the only selected layout for the new field

  7. 点击 Next.
  8. 在相关列表标签字段中输入Showings。

    A screenshot of the related list label for the Property field

  9. 点击 Save.

创建一个对象特定的操作

呃,你是通过你的家庭作业完成的。现在,所有的作品都已经到位,您可以享受您的奖励 – 帮助D’Angelo创造一个真棒对象特定的动作。

这是我们需要做的。 D’Angelo希望创建一个新的显示快速操作,并将其显示在Salesforce应用程序的联系人详细信息页面上。这样,当经纪人安排新的展示时,它会自动与潜在买家的记录相关联。所以在这一步中,我们为联系人创建一个对象特定的操作。

  1. 从联系人的对象管理设置中,转到“按钮”,“链接”和“操作”,然后单击 New Action.
  2. 选择操作类型是 Create a Record.

    操作不仅仅是创建记录。要详细了解其他选项,请阅读“操作类别和类型”帮助文章。

  3. 在“目标对象”下拉列表中,选择 Event.
  4. 在记录类型下拉列表中,单击 Showing.
  5. 在标签字段中输入 New Showing

    A screenshot of the new action's details

  6. 点击 Save.
  7. 在布局编辑器中,删除以下字段:相关于,分配给和名称。
    将Property字段添加到布局并使其成为必需。您可以双击该字段以编辑其设置。
  8. 删除任何额外的空间,并将字段排列在一个列中。

    A screenshot of the new action's layout with 5 fields in a single column

  9. 点击 Save.
  10. 单击是确认警告。即使需要,也可以从布局中删除“分配给”字段,因为它默认为当前用户。

    注意

    除非从布局中删除必填字段,除非:

    • 该字段具有默认值。
    • 您为该操作指定预定义的字段值。
    • 该字段已包含数据。例如,如果动作更新记录,则用户在最初创建记录时输入了所需的信息。
  11. 现在,我们通过预先填充主题字段来节省经纪人。在“预定义值”相关列表中,单击 New.
  12. 在“字段名称”下拉列表中,选择 Subject.
  13. 在“指定新字段值”字段中,输入 "Showing". 一定要把引号放在单词旁边。

    A screenshot of the predefined value for the Subject field

  14. 点击 Save.

将一个动作添加到对象的页面布局

我们正在家中!现在我们只需要将新动作添加到联系人的页面布局。然后,当经纪人正在查看潜在买家的记录时,它将在移动应用程序的操作栏中可用。 (别忘了,当你创建一个对象特定的动作时,它就属于该对象的页面布局。)

  1. 从联系人的对象管理设置中,转到页面布局,然后单击 Contact Layout.
  2. 在Salesforce1和Lightning Experience Actions部分中,如果看到链接覆盖预定义的操作,请单击要覆盖的链接。
  3. 在调色板中选择Salesforce1和闪电操作,然后将新显示快速操作拖到Salesforce1部分。确保它是第一个项目。

    A screenshot of the New Showing action in the Salesforce1 section of the contact page layout

  4. 重新组织这些最常用的动作,并删除任何不必要的动作。

    A screenshot of the reorganized actions in the Salesforce1 section of the contact page layout

  5. 点击 Save.

我们完成了!现在DreamHouse经纪人可以快速安排一个新的展示与潜在买家。

在Salesforce应用程序中测试操作

这里真正令人满意的部分 – 是时候在移动应用程序中测试您的美丽新动作了。因此,在您的设备上启动Salesforce,让我们一起来看看这个用例。

  1. 点击导航菜单图标Navigation Menu Icon打开导航菜单,然后下拉刷新。
  2. 我们先来创建一个新的Property,这样我们可以将它与一个显示相关联。在导航菜单的“最近”部分,点击“更多”,然后点击“Property”。
  3. 点击 New.
  4. 对于Property名称,输入一个街道地址。

    A screenshot of the property detail page in Salesforce1

  5. 填写其他必填字段(如果有),然后点击保存。现在我们可以查找一个潜在的买家,并与他们安排一个展示。
  6. 打开导航菜单,然后点击 Contacts.
  7. 选择您在上一单元中创建的联系人,或者创建一个新联系人。
  8. 拉下来刷新操作栏。
  9. 点按 New Showing.

    A screenshot of the New Showing action in the Salesforce1 action bar

  10. 完成字段。

    A screenshot of the details about the new showing

    提示

    听写比打字快得多。当您进入“说明”字段时,通过选择键盘上的麦克风图标来激活语音输入。这个本地操作系统功能可以为繁忙的移动用户节省时间,所以一定要告诉他们。

  11. 点按 Save.
  12. 让我们回到财产记录,所以你可以看到新的事件出现在显示相关列表。打开导航菜单,点击Property,然后选择刚创建的Property。
  13. 点按 Related.

    A screesnhot of the Showings related list on the property record

  14. 点按“Showings ”查看为该媒体资源预定的所有展示。

很酷,是吧?你真的得到了这个移动的东西的挂钩。 (随意轻拍自己的背部……你应得的。)

帮助DreamHouse与另一个用例

我们为什么不保留这个定制派对?让我们来实现DreamHouse Realty最后的移动用例。这是德安杰洛在对用户进行投影时所观察到的。

在DreamHouse经纪人完成展示物业之后,他们喜欢记下总结买家对于家庭观点的注释。 D’Angelo希望创建一个“输入反馈”操作,让经纪人用他们的笔记快速更新事件记录。

在我们可以专注于新的行动之前,我们需要为活动创建一个自定义的反馈字段。

  1. 从活动的对象管理设置中,转到“字段和关系”,然后单击 New.
  2. 选择文本区域,然后单击下一步。
  3. 在字段标签和字段名称字段中输入反馈,然后单击 Next.

    A screenshot of the details about the Feedback field

  4. 选择Visible复选框,以便该字段可用于所有配置文件,然后单击 Next.
  5. 取消选择“事件布局”和“任务布局”以及除“显示布局”之外的其他任何布局。我们只希望这个字段出现在显示布局上。

    A screenshot of the Showing Layout selected for the Feedback field

  6. 点击 Save.

工作很好现在,我们开始设置轮子,您将完成D’Angelo的移动视野,在这个单位的挑战。祝你好运!我们知道你会粉碎它。

收拾好积分后,转到下一个单元,在那里学习如何使用紧凑布局简化Salesforce应用程序中的记录详细信息页面。

Salesforce 配置移动端(2)

学习目标

完成本单元后,您将能够:

  • 描述两种主要类型的行动之间的差异。
  • 创建一个全局操作。
  • 在动作布局中配置字段。
  • 为动作布局上的字段设置预定义的值。
  • 通过编辑全局发布者布局将操作添加到Salesforce应用程序。

介绍快速操作

快速操作是我们浏览移动定制选项的第一站。而且我们正在把我们最好的脚放在这里。

因为快速行动,我们已经给了你移动王国的钥匙。别开玩笑!这是一个大胆的说法,但这是真的。在所有可供您使用的点击式自定义工具中,快速操作最有可能改变移动体验,使您成为用户的英雄。

快速行动之美

那么什么是快速行动?那么,你可以把它们想成快捷方式。它们为移动用户提供了一种在Salesforce移动应用程序中启动特定工作流的快捷方式,例如创建记录,记录呼叫或共享文件。

Salesforce应用程序带有一些方便的内置操作,它们位于屏幕底部的操作栏和操作菜单(操作菜单图标Action Menu icon)中。操作栏在大多数页面上都是可见的,所以快速的操作只是一个点击你的移动用户。

The Action Bar and Menu and Salesforce1

很方便,呃?但是等等 – 还有更多!

要把这个快速行动称为一个单纯的快捷方式,并不是真正的正义。这就是快速行动如此特殊的原因。

  • 您可以创建适合您自己的业务流程和用例的自定义操作。
  • 每个动作都有自己独特的页面布局,因此您可以将字段限制为移动用户真正需要的字段。
  • 您可以预先填充页面布局上的字段以节省移动用户一段时间。

看到?快速行动不仅仅是满足眼球。它们实际上是三个强大的功能,一个快捷方式,一个页面布局以及预定义的字段,可以集成到一个小而强大的包中。

快速行动的类型

现在你明白了什么是行动,我们将会向你投掷一个曲线球。有两种类型的操作:全局和特定于对象。

特定于对象的操作允许用户在特定对象的上下文中创建或更新记录。在Salesforce应用程序中,对象特定的操作显示在记录详细信息页面上。因此,例如,与机会对象关联的动作只有在用户正在查看机会时才可用。

全局操作让用户创建记录,但新记录与其他记录没有关系。他们被称为全局行动,因为他们可以放在任何地方支持行动 – 记录详细信息页面,但也Feed或Chatter组的地方。

清除泥浆?别担心,在创造一些自己的东西之后,你会对这两种行为感到更加舒适。我们首先处理全局行动。

我们的全局行动使用案例

这是思考全局行为的一种方式:用户想要快速完成的事情,但不一定完全。这正是D’Angelo Cunningham如何利用全局行动让他的经纪人的生活变得更轻松。让我们看看DreamHouse Realty的第一个移动用例。

DreamHouse Realty使用联系人对象来跟踪他们的未来购房者。 D’Angelo在联系人对象上创建了一个自定义“Stage”字段,用于指示购买者在家庭购买过程中的当前阶段。一个新的潜在买家处于展望阶段。

现在想象一下,DreamHouse的经纪人正在举办一个开放的房子,她遇到了一个潜在的买家。她需要一种有效的方式将该人员添加为联系人,而无需导航到特定页面或将该人与其他信息相关联。这是一个全局性的行动 – 用户可以稍后跟进的快速事情。

将用例带入生活

D’Angelo想要定制Salesforce应用程序,以尽可能快速和简单地添加潜在买家。他决定:

  • 创建一个新的展望全局行动
  • 限制布局上的字段只是要点,如姓名,号码和电子邮件
  • 包括自定义阶段字段并将该字段的默认值设置为“潜在”

为了跟上D’Angelo的脚步,我们首先需要在我们的组织中创建自定义Stage字段。

  1. 从联系人的对象管理设置中,转到“字段和关系”,然后单击 New.
  2. 选择Picklist作为数据类型,然后单击Next。
  3. 对于字段标签,输入Stage。
  4. 为选取 Enter values for the picklist, with each value separated by a new line.
  5. 在文本区域中,输入以下值:潜在,显示,提供,关闭,存档

    A screesnhot of the Stage field's details

  6. 点击 Next.
  7. 选择 Visible 以便该字段可用于所有配置文件,然后单击 Next.
  8. 点击 Save.

创建一个全局行动

现在我们和D’Angelo在同一页面,我们已经准备好开始了。在这一步中,我们添加一个创建新联系人的全局操作。

Walkthrough Icon漫游图标漫游:创建一个全局快速行动

  1. 从“设置”中,在快速查找方框中输入操作,然后选择 Global Actions.
  2. 点击 New Action.
  3. 我们希望这个动作创建一个新的联系人,所以确保动作类型是 Create a Record.

    操作也可以执行其他进程,例如记录调用或发送电子邮件。但请注意,全局操作不能更新记录。只有对象特定的操作才能做到这一点。

  4. 在“目标对象”下拉列表中,选择 Contact.
  5. 在标签字段中,输入 New Prospect.

    A screenshot of the new action's details

  6. 点击 Save.

自定义操作布局

快速行动最强大的是每个动作都有自己独特的布局,您可以自定义。这就是移动用户如此节省时间的原因。你可以削减要领,尽可能多地删除不必要的字段。

我们来优化新展望行动的布局。 D’Angelo想要消除几个字段,并确保自定义Stage字段被添加到布局中。

  1. 如果布局编辑器尚未打开,请转到全局操作列表,然后单击新建潜在 动作旁边的布局。
  2. 从版面中删除帐户名称和标题字段。
  3. 将舞台字段添加到布局。

    A screenshot of the fields on the action layout

    提示

    为移动用户定制操作布局时,更少。最好的做法是包括少于五个字段,绝对不超过八个字段。

  4. 点击 Save.

设置预定义的值

加快移动用户输入数据流程的一个好方法是预先为动作布局上的某些字段设置值。

这并不总是可能取决于你的用例,但D’Angelo绝对可以利用这个功能。如果你记得,他想把Stage字段的默认值设置为 “Prospect.”

  1. 转到“全局操作”列表并单击 New Prospect.
  2. 在“预定义字段值”相关列表中,单击 New.

    A screenshot of the New button in the Predefined Field Values list

  3. 在“字段名称”下拉列表中,选择 Stage.
  4. 在“指定新字段值”部分中,选择 Prospect.

    A screenshot of the predefined value for the Stage field

    请记住,预定义的字段值与此特定操作绑定在一起。这些规则仅适用于用户在Salesforce应用程序中启动“新建潜在”操作,而不是在完整的Salesforce网站中创建联系人时应用。

  5. 点击 Save.

将操作添加到全局发布者布局

好!我们有一个漂亮的新行动与移动友好的布局。但最后一步就是完成。在将Salesforce应用添加到全局发行商布局之前,此操作将无法在Salesforce应用中使用。

全局发行商的布局…这是一口,不是吗?那么,这只是指在移动应用程序的操作栏中列出操作方式的技术方式。全局布局仅适用于Feed或Chatter组等地点的操作栏 – 基本上只适用于与特定对象无关的页面。

D’Angelo希望经纪人能够直接从订阅源创建新的潜在客户,所以让我们将新的行为添加到全局发行商的布局。

  1. 从“设置”中,在快速查找方框中输入发布者,然后选择 Publisher Layouts.
  2. 单击全局布局旁边的编辑。
  3. 在Salesforce1和Lightning Experience Actions部分中,如果看到链接 override the predefined actions, 请单击要覆盖的链接。

    A screenshot of the Override Predefined Actions link in the Publisher

  4. 在布局编辑器的上部调色板中选择Salesforce1和Lightning Actions,然后将New Prospect快速操作拖到Salesforce1部分。确保它是第一个项目。

    A screenshot of the New Prospect action in the Global Publisher Layout

    这里的动作顺序决定了他们在移动应用程序中的顺序。重新组织它们,以便使用最常用的操作,并删除所有未使用的操作。

  5. 点击 Save.

在Salesforce应用程序中测试全局操作

恭喜!您成功创建了您的第一个全局行动。为什么我们不启动Salesforce应用程序并为测试驱动器采取行动?

  1. 在移动设备上打开Salesforce。
  2. 点击导航菜单图标Navigation Menu Icon打开导航菜单,然后下拉刷新。 (在安装程序中进行更改后,有时需要在移动应用程序中刷新页面。)
  3. 在菜单中选择Chatter以导航到Feed。
  4. 点击操作栏中的 New Prospect

    A screenshot of the New Prospect action in the Salesforce1 action bar

  5. 输入所需的数据。阶段字段应该默认为 “Prospect.”

    A screenshot of the prospect's details in Salesforce1

  6. 点按 Save.

举手击掌!新的全局行动按预期工作。

现在你已经掌握了全局行为,让我们把注意力转向对象特定的行为。在下一个单元中,您可以通过实施他的第二个移动用例来帮助D’Angelo进一步改进Salesforce应用程序。

Sales’force 配置移动端(1)

学习目标

完成本单元后,您将能够:

  • 说出使用Salesforce移动应用程序的一些好处。
  • 解释为什么定制移动应用程序非常重要。
  • 查找并下载该应用程序。
  • 选择你的应用程序的工作环境。

交付移动的承诺

除非你在过去10年里一直躲在山洞里,否则你可能已经注意到我们正处在一场移动革命之中。移动设备的使用率一直居高不下,事实上,我们大多数人在我们的设备上花费的时间和在电脑前一样多。移动技术改变了我们生活,学习,旅行,购物和保持联系的方式。

企业界也不例外。人们希望他们的商业工具是移动且易于访问的。你的员工在外出或离开办公桌时需要完成工作。 (嘿,你的一些员工甚至没有办公桌 – 他们的办公桌是汽车,飞机上的座位或最近的咖啡店。)

但是这是问题。尽管移动技术普遍存在,但大多数公司还是无法兑现移动技术的承诺。为什么?因为建立移动应用程序很困难。你建立Android或iOS?你用什么工具?你如何设计多个屏幕尺寸?安全呢?

幸运的是,您已经掌握了一系列管理技巧的Salesforce移动应用程序。我们已经照顾到了这些棘手的发展挑战,这意味着您可以从中获得移动的回报,而不需要做任何肮脏的工作。听起来不错?我们觉得可能。那么让我们来了解更多关于Salesforce应用的信息。

欢迎使用Salesforce Mobile App

Salesforce应用程序是一款企业级移动应用程序,可让您的用户通过手机或平板电脑即时访问公司的CRM数据。这里有一些为什么这个应用程序太棒了的原因。

  • 每个Salesforce许可证都包含移动应用程序。 是的,你听到我们是正确的 – 它是免费的。拖延你的手机推广,基本上就像堆着火堆。
  • 该应用程序是即插即用的, 这意味着用户只需从App Store或Google Play下载即可。它无需安装即可使用。这是闪电,认真。在阅读本段文件的时候,您可能已经安装了应用程序并登录了。
  • 该应用程序是跨平台的, 所以它运行在Android和iOS操作系统上。就像,自动 – 无需你做任何开发工作。
  • 该应用程序具有离线功能. 您的移动用户不会受到反复无常的蜂窝信号,FAA法规,地铁通勤或掩体式建筑物的影响。
  • 这不仅仅是一个应用程序。 这是一个平台。由于该应用程序由Salesforce平台提供支持,因此可以进行无限定制。您可以使用点击工具来创建自己的。

如果没有足够的理由让你陷入爱上Salesforce应用的脚步,也许这个简短的演示将会诀窍。

元数据的魔力

也许你想知道Salesforce应用程序可能立即工作,开箱即用。秘密是你的元数据。

作为管理员,您可能使用了可帮助您自定义Salesforce的点击式工具。也许你已经创建了自定义对象,定制的页面布局,建立的列表视图等等。

这些定制成为您的元数据的一部分,这只是一组描述您特定的Salesforce组织的定义。而且大多数自定义功能都可以在Salesforce移动应用程序中自动使用,因为它可以读取这些定义并相应地显示数据。

但是等一下。如果您的所有Salesforce自定义已经在移动应用程序中提供,那么为什么还要自定义呢?

移动是不同的

那么,在桌面环境中工作的东西在移动环境中并不总是如此。这是一个例子。比方说,您向机会对象添加了一堆自定义字段,这意味着您的机会页面布局有超过100个字段。

这对桌面用户来说很好。但考虑一下销售代表从他们的电话中编辑一个机会。他们有细微的蜂窝覆盖,所以他们不得不等待很长时间才能加载一个巨大的页面。然后要编辑他们实际想要更新的三个字段,他们必须滚动…并滚动…并滚动…并滚动。

呸。这听起来令人沮丧,不是吗?但不一定是那样的。通过花时间调整一些特定于移动设备的组织设置,您可以显着改善移动用户的体验。

使移动应用程序为您自己的

通过自定义Salesforce应用程序,您可以将移动应用程序塑造成功能强大的工具,帮助您的用户快速完成工作。在本模块中,我们介绍了可用于自定义移动应用程序的三个功能。

  • 快速行动
  • 紧凑的布局
  • 移动导航

当您刚开始使用Salesforce应用程序时,确切了解如何使用这些功能来解决移动用户的问题可能颇具挑战性。那么让我们来学习如何在真实世界的场景中自定义移动应用程序。

认识DreamHouse Realty

DreamHouse Realty是一家蓬勃发展的房地产企业,拥有75名经纪人。那些经纪人很忙!无论他们是否与买家见面,展示物业,或准备开放的房屋,他们都在不断地移动。

DreamHouse的Salesforce管理员D’Angelo Cunningham听说了Salesforce移动应用程序,他认为这可以帮助经纪人在外地保持高效。

D'Angelo dreaming up mobile possibilities所以D’Angelo做了他的功课。他和他的经纪人交谈过,并做了一些骑行,以发现移动应用程序可能能够解决问题或加快某些过程的时刻。

D’Angelo在回顾他的笔记之后,确定了他的经纪人每天执行的一些最常见的任务。这些任务被称为用例。

我们的移动使命

那么D’Angelo确定的移动用例是什么?这是他的经纪人在场上需要快速完成的三件事情。

  • 增加一个新的准买家
  • 安排新的展示
  • 在展示之后输入潜在买家的反馈

在整个这个模块中,我们将与D’Angelo一起将这些用例转化为移动定制。

提示

现在是开始思考自己的移动用例的好时机。完成此模块后,请转到“Salesforce Mobile App分装”模块。它充满了关于启动Salesforce应用程序的建议,并包含了开发移动用例的说明。

获取Salesforce Mobile App

准备与D’Angelo并肩工作,定制Salesforce应用程序?你当然是!所以,让我们开始使用移动应用程序运行。

检查要求

始终在满足最低平台要求的设备上运行移动应用程序。请注意,这些要求可能会发生变化。

下载应用程序

如果您的Android或iOS设备满足最低要求,则可以使用AppStore®或Google Play™提供的可下载的Salesforce移动应用程序。

您也可以使用在支持的移动浏览器中运行的移动浏览器应用程序。这个选项不需要安装任何东西。

选择您的工作环境

当您登录到Salesforce移动应用程序时,您将自动连接到您的生产组织。但是,您也可以登录到您的沙盒,这是使用移动设置和自定义功能的最佳场所。如果您没有沙箱,请使用Trailhead Playground(TP)凭据登录,或者获得免费的Developer Edition帐户。 (如果您需要TP的用户名和密码,可以按照此处的说明访问它们。)

要了解如何在移动应用程序中的不同组织和实例之间切换,请查看“使用Salesforce Mobile应用程序指南”中的“在用户,组织和社区之间切换”一章。

了解限制

Salesforce应用程序做了很多工作,但是并没有做任何事情 – 请注意与完整的Salesforce网站存在一些差异。了解不在Salesforce应用程序中的Salesforce功能的优先级,这些功能存在功能差距,或者在移动应用程序中的工作方式不同。

拥抱你的移动未来

现在Salesforce已经安装在您的手机上了,暂停一下,并且欣赏一下这样一个事实,即您在组织的移动旅程中迈出了第一步。 令人兴奋的,不是吗?

Salesforce应用程序是一个完美的开始。 它为您的用户提供了大量的价值。 如果您利用本模块中介绍的定制功能,您可以节省用户时间,让生活变得更轻松。 (警告:他们可能会哭泣的快乐,确保你有方便的组织。

额外的奖励? 随着移动设备的成功推出,您可能会看到整体Salesforce应用的增长。 而且我们知道增加采用这个词就像音乐到管理员的耳朵。

所以让我们开始吧! 在下一个单元中,您将学习如何在Salesforce应用程序中设置快速操作,帮助您的用户轻松完成重要任务。

Salesforce Triggers(2)

学习目标

完成本单元后,您将能够:

  • 编写对sObject集合进行操作的触发器。
  • 编写执行高效SOQL和DML操作的触发器。

批量触发器设计模式

Apex触发器被优化以批量操作。我们建议使用批量设计模式处理触发器中的记录。当您使用批量设计模式时,您的触发器具有更好的性能,消耗更少的服务器资源,并且不太可能超出平台限制。
批量代码的好处是,批量代码可以高效地处理大量记录,并在Force.com平台的管理限制内运行。这些州长限制已经到位,以确保失控代码不会垄断多租户平台上的资源。

以下部分将演示在触发器中扩展Apex代码的主要方法:对触发器中的所有记录进行操作,并对sObject集合执行SOQL和DML,而不是同时对单个sObjects执行SOQL和DML。 SOQL和DML批量最佳实践适用于任何Apex代码,包括类中的SOQL和DML。给出的例子是基于触发器,并使用Trigger.New上下文变量。

在记录集上运行

我们先来看触发器中最基本的批量设计概念。批量触发器在触发器上下文中的所有sObjects上运行。通常情况下,如果触发触发器的操作来自用户界面,触发器将在一条记录上运行。但是,如果操作的起源是批量DML或API,则触发器将在记录集上运行,而不是一个记录。例如,当您通过API导入多条记录时,触发器将在整个记录集上进行操作。因此,一个良好的编程习惯就是始终假设触发器在一系列记录上运行,以便在任何情况下都能正常工作。

以下触发器假设只有一条记录导致触发器触发。在同一事务中插入多个记录时,此触发器不能在完整的记录集上工作。下一个示例中显示了一个批量版本。

trigger MyTriggerNotBulk on Account(before insert) {
    Account a = Trigger.New[0];
    a.Description = 'New description';
}
这个例子是MyTrigger的修改版本。它使用for循环遍历所有可用的sObjects。如果Trigger.New包含一个sObject或多个sObjects,则此循环有效。
trigger MyTriggerBulk on Account(before insert) {
    for(Account a : Trigger.New) {
        a.Description = 'New description';
    }
}
执行批量SOQL

SOQL查询可以是强大的。您可以检索相关记录,并在一个查询中检查多个条件的组合。通过使用SOQL功能,您可以编写更少的代码并减少对数据库的查询。减少数据库查询有助于避免遇到查询限制,即同步Apex的100个SOQL查询或异步Apex的200个查询限制。

以下触发器显示要避免的SOQL查询模式。这个例子在for循环中创建一个SOQL查询,以获取每个客户的相关机会,每个客户在Trigger.New中为每个Account sObject运行一次。如果您拥有大量客户,for循环中的SOQL查询可能导致太多的SOQL查询。下一个例子显示了推荐的方法。

trigger SoqlTriggerNotBulk on Account(after update) {   
    for(Account a : Trigger.New) {
        // 获取每个客户的子记录
        // 对于每个客户运行一次的SOQL查询效率低下!
        Opportunity[] opps = [SELECT Id,Name,CloseDate 
                             FROM Opportunity WHERE AccountId=:a.Id];
        
        // 做一些其他处理
    }
}
此示例是前一个示例的修改版本,并显示了运行SOQL查询的最佳实践。 SOQL查询完成繁重的工作,并在主循环之外调用一次。
  • SOQL查询使用内部查询(SELECT Id FROM Opportunities)来获取相关的客户机会。
  • SOQL查询通过使用IN子句并绑定WHERE子句中的Trigger.New变量(WHERE Id IN:Trigger.New)连接到触发器上下文记录。这个WHERE条件将客户过滤为仅触发此触发器的记录。

将查询中的两部分结合起来,就可以在一次调用中得到我们想要的记录:这个客户将触发每个客户的相关机会。

获取记录及其相关记录之后,for循环通过使用集合变量(本例中为acctsWithOpps)来迭代感兴趣的记录。 collection变量保存SOQL查询的结果。这样,for循环只能遍历我们想要操作的记录。由于相关的记录已经被获得,所以在循环内不需要进一步的查询来获得这些记录。

trigger SoqlTriggerBulk on Account(after update) {  
    // 执行一次SOQL查询。
    // 获取客户及其相关机会。
    List<Account> acctsWithOpps = 
        [SELECT Id,(SELECT Id,Name,CloseDate FROM Opportunities) 
         FROM Account WHERE Id IN :Trigger.New];
  
    // 遍历返回的客户 
    for(Account a : acctsWithOpps) { 
        Opportunity[] relatedOpps = a.Opportunities;  
        // 做一些其他处理
    }
}
或者,如果您不需要客户父记录,则只能检索与此触发器上下文中的客户相关的商机。该列表在WHERE子句中通过将机会的AccountId字段与Trigger.New中的客户ID进行匹配来指定:WHERE AccountId IN:Trigger.New。返回的机会适用于此触发器上下文中的所有客户,而不是特定客户。下一个示例显示用于获取所有相关机会的查询。
trigger SoqlTriggerBulk on Account(after update) {  
    // 执行一次SOQL查询。
    // 获取这个触发器中客户的相关机会。
    List<Opportunity> relatedOpps = [SELECT Id,Name,CloseDate FROM Opportunity
        WHERE AccountId IN :Trigger.New];
  
    // 遍历相关的机会 
    for(Opportunity opp : relatedOpps) { 
        // 做一些其他处理
    }
}
您可以通过在一个语句中将SOQL查询与for循环组合来缩小前面的示例:SOQL for循环。这是使用SOQL for循环的这个批量触发器的另一个版本。
trigger SoqlTriggerBulk on Account(after update) {  
    // 执行一次SOQL查询。  
    // 在此触发器中获取客户的相关机会,
    // 并遍历这些记录。
    for(Opportunity opp : [SELECT Id,Name,CloseDate FROM Opportunity
        WHERE AccountId IN :Trigger.New]) {
  
        // 做一些其他处理
    }
}
超越基础

触发器一次执行批次的200条记录。所以如果有400条记录触发一个触发器,那么触发器会触发两次,每个记录有一次。因为这个原因,在触发器中你没有得到SOQL的循环记录批处理的好处,因为触发器也记录了批处理记录。在这个例子中SOQL for循环被调用了两次,但是一个独立的SOQL查询也被调用了两次。但是,SOQL for循环看起来比迭代集合变量更优雅!

执行批量DML

在触发器或类中执行DML调用时,尽可能在一组sObject上执行DML调用。在每个sObject上执行DML单独使用资源效率低下。 Apex运行时允许在一个事务中多达150个DML调用。

该触发器在for循环中执行更新调用,该循环遍历相关的机会。如果满足某些条件,则触发器更新机会描述。在这个例子中,更新语句对于每个机会被低效地调用一次。如果批量客户更新操作触发了该触发器,则可能有多个客户。如果每个客户有一两个机会,我们可以很容易地结束150个机会。 DML语句限制是150个调用。

trigger DmlTriggerNotBulk on Account(after update) {   
    // 获取这个触发器中客户的相关机会。
    List<Opportunity> relatedOpps = [SELECT Id,Name,Probability FROM Opportunity
        WHERE AccountId IN :Trigger.New];          

    // 遍历相关的机会
    for(Opportunity opp : relatedOpps) {      
        // 当概率大于50%但小于100%时更新描述
        if ((opp.Probability >= 50) && (opp.Probability < 100)) {
            opp.Description = 'New description for opportunity.';
            // 为每个机会更新一次 - 效率不高!
            update opp;
        }
    }    
}
下面的例子展示了如何在一个机会列表上只用一个DML调用来高效地执行DML。该示例将添加Opportunity sObject以更新为循环中的机会列表(oppsToUpdate)。接下来,触发器在所有机会添加到列表之后,在此列表的循环外执行DML调用。无论正在更新的sObject数量如何,此模式只使用一个DML调用。
trigger DmlTriggerBulk on Account(after update) {   
    // 获取这个触发器中客户的相关机会。 
    List<Opportunity> relatedOpps = [SELECT Id,Name,Probability FROM Opportunity
        WHERE AccountId IN :Trigger.New];
          
    List<Opportunity> oppsToUpdate = new List<Opportunity>();

    // Iterate over the related opportunities
    for(Opportunity opp : relatedOpps) {      
        // 当概率大于50%但小于100%时更新描述
        if ((opp.Probability >= 50) && (opp.Probability < 100)) {
            opp.Description = 'New description for opportunity.';
            oppsToUpdate.add(opp);
        }
    }
    
    // 在集合上执行DML
    update oppsToUpdate;
}

批量设计模式的实际操作:获取相关记录的触发器示例

让我们通过编写一个访问客户相关机会的触发器来应用您所学习的设计模式。修改AddRelatedRecord触发器的前一单元的触发器示例。 AddRelatedRecord触发器批量操作,但效率不如它可能是因为它遍历所有Trigger.New sObject记录。下一个示例修改SOQL查询以仅获取感兴趣的记录,然后遍历这些记录。如果你还没有创建这个触发器,不要担心,你可以在本节中创建它。

让我们从AddRelatedRecord触发器的要求开始。客户被插入或更新后触发器触发。触发器为每个没有机会的客户添加一个默认机会。要解决的第一个问题是弄清楚如何获得孩子的机会记录。因为这个触发器是一个after触发器,我们可以从数据库中查询受影响的记录。他们已经被触发后触发的时间。让我们编写一个SOQL查询,返回这个触发器中没有相关机会的所有账号。

[SELECT Id,Name FROM Account WHERE Id IN :Trigger.New AND
                                             Id NOT IN (SELECT AccountId FROM Opportunity)]
现在我们已经获得了我们感兴趣的记录子集,让我们通过使用SOQL for循环遍历这些记录,如下所示。
for(Account a : [SELECT Id,Name FROM Account WHERE Id IN :Trigger.New AND
                                         Id NOT IN (SELECT AccountId FROM Opportunity)]){
}
你现在已经看到了我们触发器的基础知识。唯一缺失的部分是创建默认的机会,我们将要进行批量处理。这是完整的触发器。
  1. 如果您已经在上一个单元中创建了AddRelatedRecord触发器,请通过用以下触发器替换其内容来修改触发器。否则,请使用开发者控制台添加以下触发器,并为触发器名称输入AddRelatedRecord。
    trigger AddRelatedRecord on Account(after insert, after update) {
        List<Opportunity> oppList = new List<Opportunity>();
        
        //为每个客户添加一个机会,如果它还没有。
        // 遍历此触发器中没有机会的客户。
        for (Account a : [SELECT Id,Name FROM Account
                         WHERE Id IN :Trigger.New AND
                         Id NOT IN (SELECT AccountId FROM Opportunity)]) {
            // 为此客户添加一个默认机会
            oppList.add(new Opportunity(Name=a.Name + ' Opportunity',
                                       StageName='Prospecting',
                                       CloseDate=System.today().addMonths(1),
                                       AccountId=a.Id)); 
        }
        
        if (oppList.size() > 0) {
            insert oppList;
        }
    }
  2. 要测试触发器,请在Salesforce用户界面中创建一个客户,并将其命名为“Lions&Cats”。
  3. 在客户页面的机会相关列表中,找到新的机会狮子会&猫。触发器自动添加了机会!

Salesforce Triggers(1)

学习目标

完成本单元后,您将能够:

  • 编写一个Salesforce对象的触发器。
  • 使用触发器上下文变量
  • 从触发器调用类方法。
  • 在触发器中使用sObject addError()方法来限制保存操作。

编写 Apex触发器

Apex触发器使您能够在事件之前或之后对Salesforce中的记录(例如插入,更新或删除)执行自定义操作。就像数据库系统支持触发器一样,Apex提供触发器支持来管理记录。
通常,您可以使用触发器根据特定条件执行操作,修改相关记录或限制某些操作的发生。您可以使用触发器在Apex中执行任何操作,包括执行SOQL和DML或调用自定义的Apex方法。

使用触发器执行无法使用Salesforce用户界面中的指向点击工具完成的任务。例如,如果验证字段值或更新记录中的字段,请改为使用验证规则和工作流程规则。

可以为顶级标准对象定义触发器,例如帐户或联系人,自定义对象和一些标准子对象。触发器在创建时默认处于活动状态。当指定的数据库事件发生时,Salesforce会自动触发活动触发器。

Trigger 语法

触发器定义的语法不同于类定义的语法。触发器定义以trigger关键字开始。之后是触发器的名称,触发器所关联的Salesforce对象以及触发的条件。触发器具有以下语法:

trigger TriggerName on ObjectName (trigger_events) {
   code_block
}
要在插入,更新,删除和取消删除操作之前或之后执行触发器,请在逗号分隔列表中指定多个触发器事件。您可以指定的事件是:
  • before insert
  • before update
  • before delete
  • after insert
  • after update
  • after delete
  • after undelete

在插入帐户并将消息写入调试日志之前,触发这个简单的触发器。

  1. 在开发者控制台中,点击 File | New | Apex Trigger.
  2. 输入HelloWorldTrigger作为触发器名称,然后选择sObject的Account。点击 Submit.
  3. 用下面的代码替换默认的代码。
    trigger HelloWorldTrigger on Account (before insert) {
    	System.debug('Hello World!');
    }
  4. 要保存,请按Ctrl + S。
  5. 要测试触发器,请创建一个帐户。
    1. 单击 Debug | Open Execute Anonymous Window.
    2. 在新窗口中,添加以下内容,然后单击 Execute.
      Account a = new Account(Name='Test Trigger');
      insert a;
  6. 在调试日志中,找到Hello World!声明。日志还显示触发器已被执行。

触发器的类型

有两种类型的触发器。

  • 触发器在保存到数据库之前用于更新或验证记录值之前。
  • 使用触发器访问由系统设置的字段值(例如记录的Id或LastModifiedDate字段),并影响其他记录中的更改。触发后触发器的记录是只读的。

使用上下文变量

要访问导致触发器触发的记录,请使用上下文变量。例如,Trigger.New包含插入或更新触发器中插入的所有记录。 Trigger.Old在更新触发器中更新之前提供旧版本的sObjects,或在删除触发器中删除sObjects的列表。当插入一个记录时,或者通过API或Apex批量插入大量记录时,触发器可以触发。因此,上下文变量(如Trigger.New)只能包含一条记录或多条记录。您可以遍历Trigger.New来获取每个单独的sObject。

这个例子是HelloWorldTrigger示例触发器的修改版本。它遍历for循环中的每个帐户并更新每个帐户的说明字段。

trigger HelloWorldTrigger on Account (before insert) {
    for(Account a : Trigger.New) {
        a.Description = 'New description';
    }   
}

注意

系统在触发器执行完成后保存触发前触发器的记录。您可以修改触发器中的记录,而无需显式调用DML插入或更新操作。如果您在这些记录上执行DML语句,则会出现错误。

一些其他的上下文变量返回一个布尔值来指示触发器是否由于更新或其他事件而被触发。当触发器组合多个事件时,这些变量很有用。例如:

trigger ContextExampleTrigger on Account (before insert, after insert, after delete) {
    if (Trigger.isInsert) {
        if (Trigger.isBefore) {
            // Process before insert
        } else if (Trigger.isAfter) {
            // Process after insert
        }        
    }
    else if (Trigger.isDelete) {
        // Process after delete
    }
}

触发上下文变量

下表是可用于触发器的所有上下文变量的综合列表。

变量 用法
isExecuting 如果Apex代码的当前上下文是触发器,而不是Visualforce页面,Web服务或executeanonymous()API调用,则返回true。
isInsert 如果由于Salesforce用户界面,Apex或API的插入操作而触发此触发器,则返回true。
isUpdate 如果由于Salesforce用户界面,Apex或API的更新操作而触发此触发器,则返回true。
isDelete 如果由于Salesforce用户界面,Apex或API的删除操作而触发此触发器,则返回true。
isBefore 如果在保存任何记录之前触发此触发器,则返回true。
isAfter 如果在保存所有记录后触发此触发器,则返回true。
isUndelete 如果在从回收站中恢复记录(即从Salesforce用户界面,Apex或API取消删除操作之后)触发此触发器,则返回true。
new 返回sObject记录的新版本列表。
此sObject列表仅在插入,更新和取消删除触发器中可用,并且记录只能在before触发器中修改。
newMap ID对新对象记录的版本的映射。
此映射仅在更新之前,插入之后,更新之后和取消删除触发器之后可用。
old 返回sObject记录的旧版本列表。
该sObject列表仅在更新和删除触发器中可用。
oldMap 旧版本的sObject记录的ID映射。
此映射仅在更新和删除触发器中可用。
size 触发器调用中的记录总数,包括旧的和新的。

从触发器调用类方法

您可以通过触发器调用公用事业方法。调用其他类的方法可以重用代码,减少触发器的大小,并且可以提高Apex代码的维护。它也允许你使用面向对象的编程。

以下示例触发器显示如何从触发器调用静态方法。如果由于插入事件触发了该触发器,则此示例将在EmailManager类上调用静态sendMail()方法。此实用程序方法向指定的收件人发送电子邮件,并包含插入的联系人记录数。

注意

EmailManager类包含在“Apex单元入门”的示例中。您必须保存组织中的EmailManager类,并在保存此触发器之前将sendMail()方法更改为static。

  1. 在开发者控制台中,点击 File | New | Apex Trigger.
  2. 输入ExampleTrigger作为触发器名称,然后选择Contact作为sObject。点击 Submit.
  3. 将默认代码替换为以下内容,然后将sendMail()中的电子邮件地址占位符文本修改为您的电子邮件地址。
    trigger ExampleTrigger on Contact (after insert, after delete) {
        if (Trigger.isInsert) {
            Integer recordCount = Trigger.New.size();
            // 从另一个类调用实用程序方法
            EmailManager.sendMail('Your email address', 'Trailhead Trigger Tutorial', 
                        recordCount + ' contact(s) were inserted.');
        }
        else if (Trigger.isDelete) {
            // 删除后的处理
        }
    }
  4. 要保存,请按Ctrl + S。
  5. 要测试触发器,请创建一个联系人。
    1. 单击 Debug | Open Execute Anonymous Window.
    2. 在新窗口中,添加以下内容,然后单击 Execute.
      Contact c = new Contact(LastName='Test Contact');
      insert c;
  6. 在调试日志中,检查触发器是否被触发。在日志末尾,找到实用程序方法编写的调试消息: DEBUG|Email sent successfully
  7. 现在检查您是否收到一封电子邮件,其中正文 1 contact(s) were inserted.

    使用新的触发器,每次添加一个或多个联系人时都会收到一封电子邮件!

添加相关记录

触发器通常用于访问和管理与触发器上下文中的记录相关的记录 – 触发该触发器的记录。

如果没有机会与客户相关联,则此触发器为每个新的或更新的客户添加相关机会。触发器首先执行SOQL查询,以获取触发器触发的帐户的所有子机会。接下来,触发器遍历Trigger.New中的sObjects列表以获取每个帐户的sObject。如果该帐户没有任何相关的机会sObjects,for循环会创建一个。如果触发器创造了新的机会,最后的陈述将插入它们。

  1. 使用开发者控制台添加以下触发器(按照HelloWorldTrigger示例的步骤,但使用AddRelatedRecord作为触发器名称)。
    trigger AddRelatedRecord on Account(after insert, after update) {
        List<Opportunity> oppList = new List<Opportunity>();
        
        // 获取这个触发器中客户的相关机会
        Map<Id,Account> acctsWithOpps = new Map<Id,Account>(
            [SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.New]);
        
        // 为每个帐户添加一个机会,如果它还没有。
        // 遍历每个帐户。
        for(Account a : Trigger.New) {
            System.debug('acctsWithOpps.get(a.Id).Opportunities.size()=' + acctsWithOpps.get(a.Id).Opportunities.size());
            // 检查帐号是否有相关的机会。
            if (acctsWithOpps.get(a.Id).Opportunities.size() == 0) {
                // 如果没有,请添加一个默认机会
                oppList.add(new Opportunity(Name=a.Name + ' Opportunity',
                                           StageName='Prospecting',
                                           CloseDate=System.today().addMonths(1),
                                           AccountId=a.Id));
            }           
        }
    
        if (oppList.size() > 0) {
            insert oppList;
        }
    }
  2. 要测试触发器,请在Salesforce用户界面中创建一个帐户,并将其命名为Apple和Orange。
  3. 在客户页面的机会相关列表中,找到新的机会。触发器自动添加了这个机会!

超越基础

你添加的触发器迭代所有属于触发器上下文的记录 – for循环遍历Trigger.New。但是,这个触发器中的循环可能更有效率。我们并不是真的需要访问这个触发器上下文中的每个客户,而是只有一个子集 – 没有机会的客户。下一个单元显示如何使这个触发器更有效率。在“批量触发器设计模式”单元中,了解如何修改SOQL查询以仅获取没有机会的帐户。然后,学习只遍历这些记录。

使用触发器异常

您有时需要对某些数据库操作添加限制,例如在满足某些条件时防止保存记录。为了防止在触发器中保存记录,在有问题的sObject上调用addError()方法。 addError()方法在触发器中引发致命错误。错误消息显示在用户界面中并被记录。

如果具有相关机会,则以下触发器可防止删除帐户。默认情况下,删除一个帐户会导致所有相关记录的级联删除。这个触发器可以防止级联删除机会。为自己尝试这个触发器!如果你已经执行了前面的例子,你的组织有一个名为苹果和橙子的客户有一个相关的机会。本示例使用该示例帐户。

  1. 使用开发者控制台添加以下触发器。
    trigger AccountDeletion on Account (before delete) {
       
        // 如果他们有相关的机会,防止删除帐户。
        for (Account a : [SELECT Id FROM Account
                         WHERE Id IN (SELECT AccountId FROM Opportunity) AND
                         Id IN :Trigger.old]) {
            Trigger.oldMap.get(a.Id).addError(
                '不能删除有相关机会的帐号');
        }
        
    }
  2. 在Salesforce用户界面中,导航到Apples&Oranges帐户的页面,然后单击 Delete.
  3. 在确认弹出窗口中,单击 OK.

    使用自定义错误消息查找验证错误无法删除具有相关机会的帐户。

  4. 禁用AccountDeletion触发器。如果你保持这个触发器激活,你不能检查你的挑战。
    1. 从设置中搜索Apex触发器。
    2. 在Apex触发器页面上,单击AccountDeletion触发器旁边的编辑。
    3. 取消选择 Is Active.
    4. 点击 Save.

超越基础

在触发器中调用addError()会导致整个操作集回滚,除非部分成功调用批量DML。

  • 如果Apex中的DML语句产生了触发器,则任何错误都会回滚整个操作。但是,运行时引擎仍会处理操作中的每个记录,以编译一个全面的错误列表。
  • 如果Force.com API中的批量DML调用产生了触发器,那么运行时引擎将把有害的记录放在一边。运行时引擎然后尝试部分保存没有产生错误的记录。

触发器和外调

Apex允许您打电话并将Apex代码与外部Web服务集成。 Apex调用外部Web服务称为标注。例如,您可以调出股票报价服务以获取最新的报价。当从触发器中进行标注时,标注必须异步完成,以便在等待外部服务的响应时触发器不会阻止您的工作。异步标注在后台进程中进行,并在收到响应时外部服务返回它。

要从触发器中进行调用,请调用异步执行的类方法。这种方法被称为未来的方法,并用@future(callout = true)进行注释。此示例类包含制作标注的未来方法。

注意

该示例仅为说明目的使用了假设的端点URL。除非您将端点更改为有效的URL并在Salesforce中为您的端点添加远程站点,否则无法运行此示例。

public class CalloutClass {
    @future(callout=true)
    public static void makeCallout() {
        HttpRequest request = new HttpRequest();
        // 设置端点URL。
        String endpoint = 'http://yourHost/yourService';
        request.setEndPoint(endpoint);
        // 将HTTP动词设置为GET。
        request.setMethod('GET');
        // 发送HTTP请求并获得响应。
        HttpResponse response = new HTTP().send(request);
    }
}

这个例子展示了调用类中的方法来异步调用标注的触发器。

trigger CalloutTrigger on Account (before insert, before update) {
    CalloutClass.makeCallout();
}
本部分仅提供了标注的概述,并不打算详细说明标注。有关更多信息,请参阅Apex Developer Guide中的使用Apex调用标注。

Salesforce Apex (基础5)SOSL

学习目标

完成本单元后,您将能够:

  • 描述SOSL和SOQL之间的区别。
  • 使用SOSL查询搜索跨多个对象的字段。
  • 使用开发者控制台中的查询编辑器执行SOSL查询。

编写SOSL查询

Salesforce对象搜索语言(SOSL)是一种Salesforce搜索语言,用于在记录中执行文本搜索。使用SOSL在Salesforce中跨多个标准和自定义对象记录搜索字段。 SOSL类似于Apache Lucene。
向Apex添加SOSL查询非常简单 – 您可以直接在您的Apex代码中嵌入SOSL查询。当SOSL嵌入在Apex中时,它被称为在线SOSL。

这是SOSL查询的一个例子,该查询搜索具有任何字段“SFDC”的客户和联系人。

List<List<SObject>> searchList = [FIND 'SFDC' IN ALL FIELDS 
                                      RETURNING Account(Name), Contact(FirstName,LastName)];

SOQL与SOSL的差异与相似性

与SOQL一样,SOSL允许您搜索组织的记录以获取特定信息。与一次只能查询一个标准或自定义对象的SOQL不同,单个SOSL查询可以搜索所有对象。

另一个区别是SOSL匹配基于单词匹配的字段,而默认情况下SOQL执行完全匹配(当不使用通配符时)。例如,在SOSL中搜索“Digital”会返回字段值为“Digital”或“The Digital Company”的记录,但SOQL只返回字段值为“Digital”的记录。

SOQL和SOSL是两种不同语法的独立语言。每种语言都有一个独特的用例:

  • 使用SOQL检索单个对象的记录。
  • 使用SOSL跨多个对象搜索字段。 SOSL查询可以搜索对象上的大多数文本字段。

先决条件

本单位的一些查询希望组织拥有账户和联系人。如果您还没有在SOQL单元中创建样本数据,请在本单元中创建样本数据。否则,您可以跳过在本节中创建示例数据。

  1. 在开发人员控制台中,从“调试”菜单中打开“执行匿名”窗口。
  2. 在窗口中插入下面的代码片段,然后点击执行。
// 添加客户和相关联系人
Account acct = new Account(
    Name='SFDC Computing',
    Phone='(415)555-1212',
    NumberOfEmployees=50,
    BillingCity='San Francisco');
insert acct;

// 一旦插入客户,sObject将填充一个ID。
// 获取这个ID
ID acctID = acct.ID;

// 添加一个联系人到这个客户。
Contact con = new Contact(
    FirstName='Carol',
    LastName='Ruiz',
    Phone='(415)555-1212',
    Department='Wingo',
    AccountId=acctID);
insert con;

// 添加没有联系人的客户
Account acct2 = new Account(
    Name='The SFDC Query Man',
    Phone='(310)555-1213',
    NumberOfEmployees=50,
    BillingCity='Los Angeles',
    Description='Expert in wing technologies.');
insert acct2;

使用查询编辑器

开发者控制台提供查询编辑器控制台,使您可以运行SOSL查询和查看结果。查询编辑器提供了一种快速检查数据库的方法。在将它们添加到您的Apex代码之前,测试您的SOSL查询是一个好方法。当您使用查询编辑器时,您只需提供没有围绕它的Apex代码的SOSL语句。

让我们尝试运行以下SOSL示例:

  1. 在开发者控制台中,点击 Query Editor 标签。
  2. 将以下内容复制并粘贴到查询编辑器下的第一个框中,然后单击 Execute.
FIND {Wingo} IN ALL FIELDS RETURNING Account(Name), Contact(FirstName,LastName,Department)
您组织中符合标准的所有客户和联系人记录都将显示在“查询结果”部分中作为包含字段的行。结果按每个对象(客户或联系人)的选项卡进行分组。 SOSL查询返回具有与Wingo匹配的字段的记录。根据我们的样本数据,只有联系人具有Wingo值的字段,因此此联系人将被返回。

注意

查询编辑器和API中的搜索查询必须用大括号({Wingo})括起来。相反,在Apex中,搜索查询包含在单引号(’Wingo’)内。

基本的SOSL语法

SOSL允许您指定以下搜索条件:

  • 文本表达(单个单词或短语)来搜索
  • 要搜索的字段的范围
  • 要检索的对象和字段的列表
  • 在源对象中选择行的条件

这是一个基本的SOSL查询语法:

FIND 'SearchQuery' [IN SearchGroup] [RETURNING ObjectsAndFields]

SearchQuery是要搜索的文本(单个单词或短语)。搜索项可以与逻辑运算符(AND,OR)和括号组合。此外,搜索字词可以包含通配符(*,?)。 *通配符在搜索项的中间或末尾匹配零个或多个字符。这个?通配符只匹配搜索项中间或末尾的一个字符。

文本搜索不区分大小写。例如,搜索客户,客户或CUSTOMER都会返回相同的结果。

SearchGroup是可选的。这是搜索领域的范围。如果未指定,则默认搜索范围是所有字段。 SearchGroup可以采取以下值之一。

  • ALL FIELDS
  • NAME FIELDS
  • EMAIL FIELDS
  • PHONE FIELDS
  • SIDEBAR FIELDS

ObjectsAndFields是可选的。它是在搜索结果中返回的信息 – 一个或多个sObjects的列表,并且在每个sObject中,包含一个或多个字段的列表,并带有可筛选的值。如果未指定,则搜索结果包含找到的所有对象的ID。

单词和短语

SearchQuery包含两种类型的文本:

  • Single Word— 单个单词,如test或hello。 SearchQuery中的单词由空格,标点符号和从字母到数字的变化(反之亦然)分隔。单词总是不区分大小写的。
  • Phrase— 由双引号包围的单词和空格的集合,如“约翰史密斯”。多个单词可以与逻辑和分组操作符组合在一起,形成一个更复杂的查询。

搜索示例

要了解SOSL搜索的工作原理,让我们使用不同的搜索字符串来查看输出是基于我们的样本数据。此表列出了各种示例搜索字符串和SOSL搜索结果。

在所有领域搜索: 搜索说明 匹配的记录和字段
查询 此搜索将返回其所有字段都包含文本的所有记录:The和Query。搜索字词中的单词顺序无关紧要。 客户:SFDC查询人(名称字段匹配)
Wingo OR Man 该搜索使用OR逻辑运算符。它返回包含Wingo单词的字段的记录或包含SFDC单词的字段的记录。 联系人:Carol Ruiz,部门:’Wingo’
客户:SFDC查询人(名称字段匹配)
1212 此搜索将返回其所有字段包含1212字的记录。以-1212结尾的电话字段被匹配,因为1212被短划线分隔时被认为是单词。客户:SFDC查询人,电话:’(415)555-1212′ 联系人:Carol Ruiz,电话:’(415)555-1212′
wing* 这是一个通配符搜索。此搜索将返回具有以wing开头的字段值的所有记录。

账号:SFDC查询员,描述: ‘Expert in wing technologies.’

SOSL Apex示例

此示例显示如何在Apex中运行SOSL查询。这个SOSL查询通过使用OR逻辑运算符来组合两个搜索项 – 它在任何字段中搜索Wingo或SFDC。此示例返回所有示例客户,因为它们每个都有一个包含其中一个单词的字段。 SOSL搜索结果以列表形式返回。每个列表包含返回记录的数组。在这种情况下,列表有两个元素。在索引0处,列表包含客户数组。在索引1处,列表包含联系人数组。

在开发者控制台的“执行匿名”窗口中执行此代码段。接下来,检查调试日志以验证是否返回所有记录。

List<List<sObject>> searchList = [FIND 'Wingo OR SFDC' IN ALL FIELDS 
                   RETURNING Account(Name),Contact(FirstName,LastName,Department)];
Account[] searchAccounts = (Account[])searchList[0];
Contact[] searchContacts = (Contact[])searchList[1];

System.debug('Found the following accounts.');
for (Account a : searchAccounts) {
    System.debug(a.Name);
}

System.debug('Found the following contacts.');
for (Contact c : searchContacts) {
    System.debug(c.LastName + ', ' + c.FirstName);
}

告诉我更多…

您可以筛选,重新排序和限制SOSL查询的返回结果。因为SOSL查询可以返回多个sObjects,所以这些过滤器应用在RETURNING子句中的每个sObject中。

您可以通过在对象的WHERE子句中添加条件来过滤SOSL结果。例如,这只会导致其行业服装被退回的客户:退货客户(名称,行业)行业=’服装’)

同样,通过为一个对象添加ORDER BY来支持一个sObject的排序结果。例如,这会导致返回的客户按名称字段排序:RETURNING客户(名称,行业ORDER BY名称)。

返回记录的数量可以限制为记录的一个子集。此示例将返回的客户限制为10个:RETURNING Account(Name,Industry LIMIT 10)

Salesforce Apex (基础4)SOQL

学习目标

完成本单元后,您将能够:

  • 在Apex中编写SOQL查询。
  • 通过在开发者控制台中使用查询编辑器执行SOQL查询。
  • 通过使用匿名Apex执行嵌入在Apex中的SOQL查询。
  • 查询相关记录。

编写SOQL查询

要从Salesforce中读取记录,您需要编写一个查询。 Salesforce提供Salesforce对象查询语言(简称SOQL),您可以使用它来读取保存的记录。 SOQL类似于标准的SQL语言,但是为Force.com平台定制。
由于Apex可直接访问存储在数据库中的Salesforce记录,因此可以将SOQL查询嵌入到Apex代码中,并以简单明了的方式获取结果。当SOQL嵌入到Apex中时,它被称为内联SOQL。

要在您的Apex代码中包含SOQL查询,请将SOQL语句包装在方括号中,并将返回值分配给一个sObjects数组。例如,以下内容将检索具有两个字段(名称和电话号码)的所有客户记录,并返回一个Account sObjects数组。

Account[] accts = [SELECT Name,Phone FROM Account];

先决条件

本单位的一些查询希望组织拥有客户和联系人。在运行查询之前,请创建一些示例数据。

  1. 在开发人员控制台中,从“调试”菜单中打开“执行匿名”窗口。
  2. 在窗口中插入下面的代码片段,然后点击执行。
// 添加客户和相关联系人
Account acct = new Account(
    Name='SFDC Computing',
    Phone='(415)555-1212',
    NumberOfEmployees=50,
    BillingCity='San Francisco');
insert acct;

// 一旦插入客户,sObject将填充一个ID。
// 获取这个ID。
ID acctID = acct.ID;

// 添加一个联系人到这个客户。
Contact con = new Contact(
    FirstName='Carol',
    LastName='Ruiz',
    Phone='(415)555-1212',
    Department='Wingo',
    AccountId=acctID);
insert con;

// 添加没有联系人的客户
Account acct2 = new Account(
    Name='The SFDC Query Man',
    Phone='(310)555-1213',
    NumberOfEmployees=50,
    BillingCity='Los Angeles',
    Description='Expert in wing technologies.');
insert acct2;

使用查询编辑器

开发者控制台提供查询编辑器控制台,使您可以运行您的SOQL查询和查看结果。查询编辑器提供了一种快速检查数据库的方法。在将它们添加到您的Apex代码之前,测试您的SOQL查询是一个好方法。当您使用查询编辑器时,您只需提供SOQL语句,而不包含围绕它的Apex代码。

让我们尝试运行以下SOQL示例:

  1. 在开发者控制台中,点击 Query Editor 标签。
  2. 将以下内容复制并粘贴到查询编辑器下的第一个框中,然后单击 Execute.
SELECT Name,Phone FROM Account

您的组织中的所有客户记录都以查询结果部分显示为包含字段的行。

基本的SOQL语法

这是一个基本的SOQL查询语法:

SELECT fields FROM ObjectName [WHERE Condition]
WHERE子句是可选的。我们从一个非常简单的查询开始。例如,以下查询检索客户并为每个客户获取两个字段:ID和电话。
SELECT Name,Phone FROM Account

查询有两部分:

  1. 选择名称,电话:这部分列出您想要检索的字段。这些字段在逗号分隔列表中的SELECT关键字之后指定。或者您只能指定一个字段,在这种情况下不需要逗号(例如SELECT Phone)。
  2. FROM客户:这部分指定您要检索的标准或自定义对象。在这个例子中,它是客户。对于名为Invoice_Statement的自定义对象,它是Invoice_Statement__c。

超越基础

与其他SQL语言不同,您不能为所有字段指定*。你必须指定你想明确得到的每个字段。如果您尝试访问您在SELECT子句中未指定的字段,则会出现错误,因为该字段尚未被检索到。

您不需要在查询中指定Id字段,因为它始终在Apex查询中返回,无论是在查询中指定还是不在查询中指定。例如:SELECT Id,Phone FROM Account和SELECT Phone FROM Account是等价的语句。唯一一次你可能想要指定Id字段,如果它是唯一的字段,你正在检索,因为你必须列出至少一个字段:SELECT ID FROM Account。在查询编辑器中运行查询时,您可能还需要指定Id字段,因为除非指定,否则ID字段将不会显示。

使用条件过滤查询结果

如果您在组织中拥有多个客户,则将全部退回。如果要限制返回给满足特定条件的客户的客户,则可以在WHERE子句中添加此条件。以下示例仅检索名称为SFDC Computing的客户。请注意,字符串比较不区分大小写。

SELECT Name,Phone FROM Account WHERE Name='SFDC Computing'
WHERE子句可以包含多个使用逻辑运算符(AND,OR)和括号分组的条件。例如,此查询将返回名称为SFDC Computing的拥有超过25名员工的所有客户:
SELECT Name,Phone FROM Account WHERE (Name='SFDC Computing' AND NumberOfEmployees>25)
这是一个更复杂条件的例子。此查询将返回所有SFDC计算客户,或者拥有超过25名员工的帐单城市为洛杉矶的所有客户。
SELECT Name,Phone FROM Account WHERE (Name='SFDC Computing' OR (NumberOfEmployees>25 AND BillingCity='Los Angeles'))

超越基础

您可以使用LIKE运算符执行模糊匹配,而不是使用相等运算符(=)进行比较。例如,您可以使用以下条件检索名称以SFDC开头的所有客户:WHERE Name LIKE’SFDC%’。 %通配符匹配任何字符或不匹配。相反的_字符可以用来匹配一个字符。

订购查询结果

执行查询时,它将从Salesforce返回记录,但不会按特定顺序进行,因此每次运行查询时都不能依赖返回数组中记录的顺序。但是,您可以选择通过添加ORDER BY子句并指定记录集应该排序的字段来对返回的记录集进行排序。本示例根据“名称”字段对所有检索到的客户进行排序。

SELECT Name,Phone FROM Account ORDER BY Name
默认排序顺序按照字母顺序排列,指定为ASC。以前的声明相当于:
SELECT Name,Phone FROM Account ORDER BY Name ASC
要反转订单,请按降序使用DESC关键字:
SELECT Name,Phone FROM Account ORDER BY Name DESC

您可以对大多数字段进行排序,包括数字和文本字段。你不能在丰富的文本和多选择选项列表上排序。

在“查询编辑器”中尝试使用这些SOQL语句,并根据“名称”字段查看返回记录的顺序如何变化。

限制返回的记录数

您可以通过添加LIMIT n子句来限制返回到任意数字的记录数,其中n是要返回的记录数。当你不关心哪些记录被返回时,限制结果集很方便,但是你只想使用记录的一个子集。例如,此查询检索返回的第一个客户。请注意,使用LIMIT 1时,返回的值是一个客户,而不是数组。

Account oneAccountOnly = [SELECT Name,Phone FROM Account LIMIT 1];

把所有的东西结合在一起

您可以按照以下顺序在一个查询中组合可选子句

SELECT Name,Phone FROM Account 
                   WHERE (Name = 'SFDC Computing' AND NumberOfEmployees>25)
                   ORDER BY Name
                   LIMIT 10
在开发人员控制台中使用“执行匿名”窗口在Apex中执行以下SOQL查询。然后检查调试日志中的调试语句。应该返回一个样本客户。
Account[] accts = [SELECT Name,Phone FROM Account 
                   WHERE (Name='SFDC Computing' AND NumberOfEmployees>25)
                   ORDER BY Name
                   LIMIT 10];
System.debug(accts.size() + ' account(s) returned.');
// 写入所有客户数组信息
System.debug(accts);

在SOQL查询中访问变量

Apex中的SOQL语句可以引用Apex代码变量和表达式,前提是冒号(:)。在SOQL语句中使用局部变量称为绑定。

这个例子展示了如何在WHERE子句中使用targetDepartment变量。

String targetDepartment = 'Wingo';
Contact[] techContacts = [SELECT FirstName,LastName 
                          FROM Contact WHERE Department=:targetDepartment];

查询相关记录

Salesforce中的记录可以通过关系相互关联:查找关系或主 – 细节关系。例如,联系人与“客户”具有查找关系。当您创建或更新联系人时,您可以将其与一个客户相关联。与相同客户关联的联系人显示在客户页面的相关列表中。以同样的方式,您可以查看Salesforce用户界面中的相关记录,您可以在SOQL中查询相关记录。

要获取与父记录相关的子记录,请为子记录添加一个内部查询。内部查询的FROM子句针对关系名称而不是Salesforce对象名称。此示例包含一个内部查询以获取与每个返回的客户关联的所有联系人。 FROM子句指定联系人关系,这是客户与客户和联系人链接的默认关系。

SELECT Name, (SELECT LastName FROM Contacts) FROM Account WHERE Name = 'SFDC Computing'

下一个示例在Apex中嵌入示例SOQL查询,并演示如何使用sObject上的Contacts关系名称从SOQL结果中获取子记录。

Account[] acctsWithContacts = [SELECT Name, (SELECT FirstName,LastName FROM Contacts)
                               FROM Account 
                               WHERE Name = 'SFDC Computing'];
// 获取子记录
Contact[] cts = acctsWithContacts[0].Contacts;
System.debug('Name of first associated contact: ' 
             + cts[0].FirstName + ', ' + cts[0].LastName);
您可以使用点符号从子对象(联系人)到其父级(Account.Name)上的字段进行遍历。例如,以下Apex片段查询联系名字为Carol的记录,并且能够通过遍历客户和联系人之间的关系来检索Carol的相关客户的名称。
Contact[] cts = [SELECT Account.Name FROM Contact 
                 WHERE FirstName = 'Carol' AND LastName='Ruiz'];
Contact carol = cts[0];
String acctName = carol.Account.Name;
System.debug('Carol\'s account name is ' + acctName);

注意

本节中的示例基于标准对象。自定义对象也可以通过使用自定义关系链接在一起。自定义关系名称以__r后缀结尾。例如,发票声明通过Invoice_Statement__c自定义对象上的Line_Items__r关系链接到订单项。 (这些自定义对象是Force.com工作簿中使用的Warehouse模式的一部分。)

通过使用SOQL for循环查询批次中的记录

使用SOQL for循环,可以在for循环中包含SOQL查询。 SOQL查询的结果可以在循环内迭代。 SOQL for循环使用不同的方法来检索记录 – 通过调用SOAP API的查询和queryMore方法,使用高效分块来检索记录。通过使用SOQL for循环,可以避免碰到堆大小的限制。

SOQL for循环遍历由SOQL查询返回的所有sObject记录。 SOQL for循环的语法是:

for (variable : [soql_query]) {
    code_block
}
要么
for (variable_list : [soql_query]) {
    code_block
}

变量和variable_list必须与soql_query返回的sObjects类型相同。

最好使用SOQL for循环的sObject列表格式,因为循环为每个200 sObjects批次执行一次。这样做使您可以批量处理记录并批量执行DML操作,这有助于避免达到管理员限制。

insert new Account[]{new Account(Name = 'for loop 1'), 
                     new Account(Name = 'for loop 2'), 
                     new Account(Name = 'for loop 3')};

// sObject列表格式为每个返回的批记录执行一次for循环
Integer i=0;
Integer j=0;
for (Account[] tmp : [SELECT Id FROM Account WHERE Name LIKE 'for loop _']) {
    j = tmp.size();
    i++;
}
System.assertEquals(3, j); // 列表中应该包含三个名为“yyy”的客户
System.assertEquals(1, i); // 由于一个批次最多可以容纳200条记录,只有三条记录应该被返回,所以循环只能执行一次