Summary of common skills in Salesforce Apex (continuous update)

Preface The blogger is also a Salesforce Apex, who has been working for a long time. I would like to share the useful knowledge and the knowledge I u...
Preface

Preface

The blogger is also a Salesforce Apex, who has been working for a long time. I would like to share the useful knowledge and the knowledge I usually refer to with you.

summary

1. When using SOQL statement to query, only 'single quotation mark' can be used for string type, otherwise an error will be reported: Unknown error parsing query;

eg: SELECT Id, Subject, CaseNumber, Status, Priority FROM Case WHERE CaseNumber = '00001036' //Note that the number of autoNumber type here is of String type

Other precautions for using SOQL:

  • Use Order By as much as possible to ensure the stability of query results;
  • Use LIMIT to prevent data volume exceeding 50000 and error reporting;
  • When Offset is used, it must be placed at the back of the query statement. For its limitations and application scenarios, see: Portal
  1. The API Name of the standard field is the Field Name of the standard field;
eg: the Subject API Name of the Case standard object is Subject

  1. Calculate the number of days between two dates:
eg: TODAY() - DATEVALUE( CreatedDate ) Implementd__Date__c - DATEVALUE( CreatedDate )

Note: use DATEVALUE() to convert only when the date is a standard field

  1. In terminal, use curl to view json data (usually use workbench > utilities > rest Explorer). sessionId is usually used. The obtaining method is as follows:
String sessionID = UserInfo.getSessionId(); System.debug(sessionID);
  1. Full version of REST services demo
@RestResource(urlMapping='/Cases/*') global with sharing class CaseManager { @HttpGet global static Case getCaseById() { RestRequest req = RestContext.request; String caseId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1); Case result = [SELECT CaseNumber, Subject, Status, Origin, Priority FROM Case WHERE Id = :caseId]; return result; } /* HttpGet Steps: 1,Create a request object of type RestRequest (the return value type of RestContext.request is RestRequest) 2,Get caseId by using string retrieval technology through the requestURI property of the request object 3,Create the Case object result and assign the record found through caseId to the object. Note "where id =: caseId" 4,Return Case object */ @HttpPost global static ID createCase(String subject, String status, String origin, String priority) { Case thisCase = new Case( Subject=subject, Status=status, Origin=origin, Priority=priority); insert thisCase; return thisCase.Id; } /* HttpPost Steps: 1,Declare and create a Case type object thisCase, and assign a value to the standard field of the object 2,Insert the custom object into the Case table to form a record 3,Returns the variable ID of type ID of a new record to find a new record */ @HttpDelete global static void deleteCase() { RestRequest req = RestContext.request; String caseId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1); Case thisCase = [SELECT Id FROM Case WHERE Id = :caseId]; delete thisCase; } /* Train of thought: To delete a record, first find the record, and the method can be to find the main code of a record using soql language. Here is the ID (the ID obtained from the uri after obtaining the uri using the rest service request) HttpDelete Steps: 1,Create ResrRequest object req 2,Declare caseId, and assign the value of uri intercepted / after rest request to this variable 3,Use soql statement to find the record with id =: caseid 4,Delete the record */ @HttpPut global static ID upsertCase(String id, String subject, String status, String origin, String priority) { Case thisCase = new Case( Id = id, Subject = subject, Status = status, Origin = origin, Priority = priority ); upsert thisCase; return thisCase.Id; } /* HttpPut Steps: 1,Declare and create a Case type object thisCase, and define a standard field assignment for the object 2,Insert the custom object into the Case table to form a record or update the record with ID 3,Returns the variable ID of type ID of a new record to find a new record */ @HttpPatch global static ID updateCaseFields() { RestRequest req = RestContext.request; String caseId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1); Case thisCase = [SELECT Id FROM Case WHERE Id = :caseId]; Map<String, Object> params = (Map<String, Object>)JSON.deserializeUntyped(req.requestBody.toString()); for(String fieldName : params.keySet()) { thisCase.put(fieldName, params.get(fieldName)); } update thisCase; return thisCase.Id; } /* HttpPatch Steps: 1,Create a request object of type RestRequest (the return value type of RestContext.request is RestRequest) 2,Get caseId by using string retrieval technology through the requestURI property of the request object 3,Create a Case object and assign the Case table record found by Id to the object 4,After the requestBody obtained from the request is converted into a string, it is deserialized into an object and forcibly converted into a Map < string. The object > is assigned to the Map variable params 5,Traverse the key of the object and write the key value in the Case object thisCase found by id 6,Update record 7,Return the id of the record */ } /* Generality: 1,Each object system has an Id attribute, which is automatically assigned by the system; 2,Each Http method is global static 3,@HttpPut Difference from @ HttpPost (upsert, insert) */

Difference: put vs patch

the same: You can update records with the put or patch methods.

the difference: put can either create new resouce or update the existing resource; patch can update the existing resouce exclusively.

  1. Different from Java inheritance, the superclass must be decorated with virtual, and the subclass must be decorated with override and extends. If the method of the parent class needs to be overridden, the method of the parent class needs to be decorated with virtual, and the subclass needs to be decorated with override. In addition, if the subclass needs to use the domain or method of the superclass, it needs to use the super keyword. Note that the reuse of the construction method does not need to use the paired virtual and override keywords to modify the construction method of the superclass and the construction method of the subclass.

  2. Use formula field to insert picture: IMAGE(path,img_title,height,width)
  3. Use the "power of one" technology in the report to count the non repeated data
  4. Load jquery with static resources in Apex:
<apex:page> <!-- Add the static resource to page's <head> --> <apex:includeScript value="{! $Resource.jQuery }"/> <!-- A short bit of jQuery to test it's there --> <script type="text/javascript"> jQuery.noConflict(); jQuery(document).ready(function() { jQuery("#message").html("Hello from jQuery!"); }); </script> <!-- Where the jQuery message will appear --> <h1 id="message"></h1> </apex:page>
  1. Simply use vf standard controller to display the Contact list, and realize click name to jump to the detailed page. There are three methods:
<apex:page standardController="Contact" recordSetVar="contacts"> <apex:pageBlock title="Contact List"> <apex:repeat value="{!contacts}" var="ct"> <li> <apex:outputLink value="/{!ct.Id}">{!ct.Name}</apex:outputLink> <!-- <apex:outputLink value="{!URLFOR($Action.Contact.View,ct.id,[retURL=''])}">{!ct.Name}</apex:outputLink> --> <!-- <apex:outputLink value="https://componentstest-dev-ed.my.salesforce.com/{!ct.Id}">{!ct.Name}</apex:outputLink> --> </li> </apex:repeat> </apex:pageBlock> </apex:page>
  1. Enhance the lookup function: when we search the Name of the parent record through lookup, usually only Name can be used by default. Sometimes, for example, we want to search the Name of the Account through Phone in the child record. At this time, we can enhance the search in setup - > Enter 'Search Settings' in Quick Search Box

  2. The method of putting the front-end website edited by HTML on the force.com platform: package all the files of the website, such as shangpinghui / Bootstrap, into zip and upload them to the Static Resources of salesforce. For example, take shangpinghui as an example, the directory structure is: shangpinghui - > images / JS / CSS / index.html, and name it shangpinghuizip after package and upload (the name cannot start with a number), Then edit the following code in Visualforce Pages:

<apex:page docType="html-5.0" sidebar="false" showHeader="false" standardStylesheets="false" action="{!URLFOR($Resource.ShangpinhuiZip, 'shangpinhui/index.html')}"> </apex:page>

In action, the URLFOR expression is used to load the page. In this way, you don't need to modify the path of the website page resource reference. Note that in Developer Edition, only one website can be placed and bound to one url due to the limit of each account, so to achieve multiple websites to be uploaded at the same time as a work display, you can make another list and map to the corresponding website through hyperlink, so that all your works can be bound Visit each page separately.

  1. In Company Information, you can view the usage times of user license, as shown in the following figure:

  2. Comparison between recordSetVar and < apex: variable value = "{!}" var = "" / >:
    recordSetVar stores the List of sobjects, which is generally used with the familiar standController (i.e. can transfer standard objects or custom objects) of < apex: pageblocktable > and < apex: Page >. It is often used for components with output properties. For components with input properties, if you need to add [0] for strong line usage, it is recommended to use the < apex: variable > tag in this scenario, so as to get a long api name Called variable storage.

  3. What is the difference between 15 bit Id and 18 Bit Id?

C:Q:: what is the difference 18 digit id and 15digit? Ans: When we create record in the object salesforce will create 18 digit unique to recognize it. This is a case insensitive Same 18 digit is represented as 15 digit id as case sensitive Id 001—9000001—1o2Of in this 15/18 digit id first 3digits indicate Object and last 5 digits indicate record
  1. There are two ways to get the component id:
  • {!KaTeX parse error: Expected 'EOF', got '}' at position 17: … omponent.idName}̲ - eg. var el1… Component.name} '). value; / / this method does not need to write nested id. to specify: $Component.bk.age
  • pg:fm:bk:name - eg. var el2 = document.getElementById('pg:fm:bk:name '). value; / / each component of this method needs to indicate the id and write in sequence according to the nesting relationship. The IDs are separated by:
    The above method can also be used in css in addition to js. If the id system is not specified, the id will be generated automatically, and the nesting relationship will be added in the corresponding component automatically.
<apex:page id="pg"> <apex:form id="fm"> <apex:inputText id="name" οnchange="show()"/> <script> function show() { var el1 = document.getElementById('{!$Component.name}').value; var el2 = document.getElementById('{!$Component.bk.age}').value; alert('name: '+el1+', age: '+el2); } function demo() { // getting specific dom element by this format, you shold write every level id. var el1 = document.getElementById('pg:fm:name').value; var el2 = document.getElementById('pg:fm:bk:age').value; alert('name: '+el1+', age: '+el2); } </script> <apex:pageBlock id="bk"> <apex:inputText id="age" οnchange="demo()"/> <apex:pageBlockSection id="bks1"> <apex:inputText id="ip1"/> </apex:pageBlockSection> <apex:pageBlockSection id="bks2"> <apex:inputText id="ip2"/> <apex:outputText id="op"/> </apex:pageBlockSection> <apex:pageBlockButtons > <apex:commandButton value="populateAutomaticly" οnclick="al()" oncomplete="populateAutomaticly()"/> </apex:pageBlockButtons> <script> function populateAutomaticly() { var el = document.getElementById('{!$Component.bks1.ip1}').value; document.getElementById('pg:fm:bk:bks2:ip2').value = el; document.getElementById('pg:fm:bk:bks2:op').innerHTML = el; } function al() { alert('Testing...'); } </script> </apex:pageBlock> </apex:form> </apex:page>
  1. The interaction between the properties of the apex:page component and the apex:sectionHeader component:
    The attributes that are rarely used in the apex:page component:
<!-- setup="true";show sidebar as setup format; renderAs="pdf";the body you development will show as pdf; action="someMethods";excute the action first before render the page; -->
<apex:sectionHeader title="Section Header Practice" subtitle="Home" description="draw your page using code" help="https://baidu.com" printUrl="https://baidu.com"/>
<span style="color:#Ff0000 "> if the setup="true "attribute is used in the page, the object icon cannot be displayed in the sectionHeader. </span>
  1. There are four ways to create visual force:
  • Navigation method - Setup - > developer - > visual force page;
  • developer console;
  • IDE - eg. sublime text / eclipses - install eclipses and configure forceIDE plug-in Video - https://www.youtube.com/watch?v=ufe62nGecMg
  • Open developer mode (two ways: 1. In User - edit development mode; 2. In my setting personal advanced User details edit development mode), create by url.

  1. Set a solution with invalid width for the column component in pageBlockTable:
  • Nesting relationship 1: Form > pageblock > pageBlockTable > column. You can directly add the style or styleClass of width to the column. If you need, set the width of pageBlockTable to 100%;
  • Nesting relationship 2: Form > pageblock > pageblocksection > pageBlockTable > column. Adding style and styleClass is not effective at this time. At this time, you only need to set columnsWidth = "width1,width2..." in pageBlockTable ;
  1. Diagram approval process, understanding queue, multi-level approval: http://blog.csdn.net/itsme_web/article/details/732509
  2. ApexPages.currentPage().getUrl().contains('st '), apex checks whether the current page url contains a string.
  3. Decimal. Valueof (apex pages. Currentpage(). Getparameters(). Get ('st ')), which converts string form to decimal form;
  4. DateTime.getTime() gets the time stamp, in ms;
    24. Date of using apex:
DateTime nowTime = System.now(); String now_date = nowTime.format('yyyy-MM-dd'); String now_dateTime = nowTime.format('yyyy-MM-dd HH:mm:ss'); System.debug(now_date+'<------>'+now_dateTime); debug Message: [plain] view plain copy 14:23:00:002 USER_DEBUG [4]|DEBUG|2017-07-26<------>2017-07-26 14:23:00
  1. Limit profiles that click the Customize button:
/** Function Description: judge whether users are project comparison and selection specialists Parameter Description: user Id Return value: true/false By Wilson Xu Date: July 26, 2017 **/ public static Boolean isValidUser(String userId){ Set<String> profileSet = new Set<String>{'Brand Commissioner','Event marketing specialist','Material production specialist','Online media specialist','Offline media specialist','Exhibition specialist','Planning specialist of subsidiary'}; String profileName = [SELECT Profile.Name FROM User WHERE Id = :userId].Profile.Name; return profileSet.contains(profileName); }
// Verify that the user is an expert profile User if(!isValidUser(UserInfo.getUserId())){ result.code = '1'; result.msg = 'Only relevant specialists can initiate targeted negotiation!'; return JSON.serialize(result); }
  1. Apex instantiates an internal class:
public class OuterClass { public class InnerClass { String name = ''; Blob body = ''; } } // Instantiate inner class OuterClass outer = new OuterClass(); OuterClass.InnerClass inner = new OuterClass.InnerClass(); /*Interface class instantiation*/ global class SyncInterface { // Encapsulate data structure - return results global class SyncResults{ global List<Response> responses; } global class Response{ public String TYPE; public String MSG; public String BUSINESS_ID; public String SALESFORCE_ID; public String PROC_TYPE; } } // Instantiate interface response list SyncResults syncResponseList = new SyncResults(); syncResponseList.responses = new List<Response>();
  1. Use Database.query() to query the data collection:
filterStr = 'AND Type__c = \'Text\' ';// Pay attention to the escape character form query = 'SELECT Name, Type__c, Message__c, Msgpic__c, Mediaid__c, VioceRecognition__c, VoiceFormat__c, VoiceSrc__c ' + 'FROM BD_CaseDetail__c ' + 'WHERE Case__c = :caseId ' + filterStr + 'ORDER BY CreatedDate ASC LIMIT 500'; caseDetailList = Database.query(query);
caseDetailList = [SELECT Name, Type__c, Message__c, Msgpic__c, Mediaid__c, VioceRecognition__c, VoiceFormat__c, VoiceSrc__c FROM BD_CaseDetail__c WHERE Case__c = :caseId AND Type__c = 'Text' ORDER BY CreatedDate ASC LIMIT 500];
  1. Live Agent configuration:

    1. First enable live agent - Setup - > live agent settings - > Enable
    2. My settings - > Advanced Settings - > live agent user (check above)
  2. According to the API name of the custom geolocation data type field, latitude and longitude are represented:
    The existing API name is geographic location coordinate field, to represent longitude, to represent latitude

Select Id, Address__c, Geographic_Coordinates__Longitude__s, Geographic_Coordinates__Latitude__s From Store__c
  1. To create a Task:
Tasks: Task task = new Task(); task.Subject = 'A Information modification application'; task.status = 'open'; task.priority = 'High'; task.whatId = '0017F00000CfcdsQAB';// Related items, here is the supplier Id task.ownerId = '0057F000000pe6uQAA';// Assigned person, UserId here // The following two lines are setting reminders task.IsReminderSet = true; task.ReminderDateTime = System.now(); insert task;
  1. Summary of List, Map and Set sets in Apex:
  • List: orderly and repeatable;
  • Map: unordered. If the key is repeated, the value is overwritten;
  • Set: out of order, not repeatable; even if it is repeated, take the previous value, such as:
Set<Integer> s = new Set<Integer> ; system.debug('s: ' + s); DEBUG INFO: s: Sample:
List<Account> accs = [select id, name from account limit 3]; map<Id, Account> m = new map<Id, Account>(); String lastId = ''; if(accs != null && !accs.isEmpty()) { Integer i = 0; for(Account a : accs) { System.debug('a['+i+'] : ' + a); lastId = a.Id; m.put(a.Id, a); i++; } } // Verify that the List has order and Map has no order System.debug(m); System.debug(m.get(lastId)); Map<String, String> m1 = new Map<String, String> { 'key1' => 'value1', 'key2' => 'value2', 'key1' => 'value2', 'key2' => 'value3', 'key1' => 'value3' }; System.debug('m1: ' +m1); System.debug('m1.key1: ' + m1.get('key1'));

  1. Partner User is not visible to the Quote Tab, and the Quote has no Sharing Rule. Its sharing is controlled by the Opportunity. If the OLS of Partner User's Quote is set to View and the Quote of the Opportunity page layout is released, if the Owner of the shared Opportunity does not create a Quote record, Partner User does not see the list related to the Quote, and needs to create a Quote before it can be seen.
  2. Group By cannot be used for formula fields in salesforce soql;
  3. How to Send More than 10 E-mails
Map<Id, List<Case>> userCaseMap = new Map<Id, List<Case>>(); List<Case> allCaseLoggedToday = new List<Case>(); List<Id> salesIds = new List<Id>(); List<User> salesRep = [SELECT Id , Name , Email , ManagerId FROM User WHERE Profile.Name = 'System Administrator']; for(User u : salesRep) { salesIds.add(u.Id); } allCaseLoggedToday = [SELECT Id, CaseNumber,CreatedById, Owner.Name , Account.Name , Contact.Name FROM Case WHERE CreatedDate = TODAY AND CreatedById in : salesIds]; for(Case c : allCaseLoggedToday) { if(userCaseMap.containsKey(c.CreatedById)) { //Fetch the list of case and add the new case in it List<Case> tempList = userCaseMap.get(c.CreatedById); tempList.add(c); //Putting the refreshed case list in map userCaseMap.put(c.CreatedById , tempList); }else { //Creating a list of case and outting it in map userCaseMap.put(c.CreatedById , new List<Case>); } }
  1. Use apex to get the IP address: apex pages. Currentpage(). Getheaders(). Get ('X-Salesforce-SIP ');
  2. When assigning initial values to an input element, we often write parameters to the Name attribute of the input element using the url. We usually worry about whether these Name values will change during the Org migration, thus increasing our maintenance burden? After investigation, the Name of Vf screen will not change with the change of Org.
  3. Salesforce gets the number of days in the month of a date:
Date d = System.today(); Integer numberDays = date.daysInMonth(d.Year(), d.Month()); System.debug(numberDays);
  1. Salesforce layout feature: if there are no buttons on the related list, the related list panel is displayed only when there are records.

  2. Experience of Lead Home Page adjustment:

  • There is no configuration method to adjust the layout of the Home page, such as changing the location of Tools and Reports;
  • Unable to replace the standard report link in Reports with the custom report link - unable to edit the standard report, unable to move the custom report to the lead Reports folder;
  • If it has to be implemented, only the standard Lead Tab button can be rewritten;
  1. If records are locked and users need to update records, they must use Webservice. For example, when the quotation is locked and the non system administrator needs to automatically synchronize the quotation, we need to call Webservice in Trigger, and then we need to use @ future asynchronous mode.
  2. Opportunity and Quote are master detail relationships. When importing historical data, the Owner of opportunity and Quote are not synchronized. When synchronizing afterwards, you cannot use apex method to update the Quote Owner. The error message is: "Can't change quote owner. Enable quotes without parent opportunities.".
  3. System.debug('result: '+ rtMap.get(myRt).equals(qt.RecordTypeId) +' – qt.RecordTypeId: '+ qt.RecordTypeId +' – rtMap.get(myRt): '+ rtMap.get(myRt));Id is 18 bits.
  4. De duplicate Sample - it seems strange, but it is very useful:
Map<String, String> accIDs = new Map<String,String>(); for(Quote qt: (List<Quote>)Trigger.New){ if(!accIDs.containsKey(qt.Quote_To_Account__c)) accIDs.put(qt.Quote_To_Account__c,''); } Map<String, Account> accs = new Map<String, Account>([SELECT id,BillingStreet,BillingCity, BillingState, BillingPostalCode, BillingCountry FROM Account WHERE Id IN : accIDs.keySet()]);
  1. Enable or disable inline editing - sometimes we want to disable the user's default inline editing function. Just go to the user interface and turn off Enable Inline Editing.
  2. Question: Default On is displayed in Tab settings of Home in profile of System Administrator. Do you see Home in Tab panel and customize list of Tab? -First, disable the enhanced profile user interface of the profile, and then check the following figure 1 in the Tab settings of the profile to save it. See information: Portal
  3. Enable the record lock in apex to lock or unlock records.
select count() from DTT__Geographic_Region__c select count() from DTT__Geographic_Region__c select count() from DTT__Geographic_Region__c select count() from DTT__Geographic_Region__c select count() from DTT__Geographic_Region__c
  1. How to configure and realize super administrator's next login to salesforce org does not need to enter the verification code: Profile - > system administrator - > login IP ranges, set IP Start Address: 0.0.0.0, IP End Address: 255.255.255.255.

  2. Use Mavensmate to synchronize field level permissions of profiles in DEV and UAT environments: During environment migration, some metadata will be lost, resulting in differences between the two environments, such as FLS in profile.

  • Step by Step: first log in to the DEV environment, use Mavensmate retrieve Profile and Custom Object (standard object is also in it), then check the fields and profile details of an object such as Order, click Update, and open the file in Sublime; use the same file method to download the relevant files of UAT to the local, and then directly copy and paste the profile file metadata to overwrite UAT .
  1. [use soql to query the number of records]:
select count() from DTT__Geographic_Region__c
  1. [get Label value]:
{!$ObjectType.ACC_Return_Order_Product__c.LabelPlural} {!$ObjectType.ACC_Return_Order_Product__c.Fields.ACC_Product__c.Label}
  1. About datetime.now date action: Portal , get the last modified time in the query statement: SELECT Id,Name,OwnerId,AccountId,LastModifiedDate FROM Opportunity
  2. Query the modified records within 15 minutes: select name from opportunity where systemmodstamp >: datetime. Now(). Addminutes (- 15)
  3. Use last ﹣ days: days to query the data based on the current time interval: SELECT Id,Name,OwnerId,AccountId,LastModifiedDate FROM Opportunity WHERE StageName! = 'sign contract' AND StageName! = 'terminate' and lastmodifieddate = last ﹣ n ﹣ days: 30
Chen Yong Jia 384 original articles published, 955 praised, 80000 visitors+ His message board follow

12 January 2020, 21:35 | Views: 6753

Add new comment

For adding a comment, please log in
or create account

0 comments