Id rid = [select Id from RecordType where DeveloperName = 'Campaign' and sobjecttype ='DocumentCompiling__c'][0].Id;
RecordType recoType = [select Id from RecordType where SobjectType = 'DocumentCompiling' and DeveloperName = 'BidDocumentation' limit 1];
Id recordTypeId = Schema.SObjectType.对象API.getRecordTypeInfosByName().get('记录类型名').getRecordTypeId();
备注:不建议用ByName查询记录类型,因为记录类型的Name会根据系统语言进行变更。
Id recordTypeId = Schema.SObjectType.对象名.getRecordTypeInfosByDeveloperName().get('记录类型名称').getRecordTypeId();
根据ID获取记录类型名
Schema.getGlobalDescribe().get(objectName).getDescribe().getRecordTypeInfosById().get(strRecordTypeId).getName();
List<Order_Details__c> orddList = [Select Id,OrderNo__r.Status, OrderNo__c fromOrder_Details__cwhere OrderNo__c in : ordId];
//将数据锁定 可以是对象的List集合,也可以是Id的Set
Approval.LockResult[] lrList = Approval.lock(orddList, false);
//将数据解锁
Approval.UnlockResult[] lrList = Approval.unlock(orddList, false);
判断记录是否锁定:
Approval.isLocked(记录Id);
trigger.oldMap.get();
Apex Scheduler类启动方法
proschedule p = new proschedule();
String sch = '0 0 8 13 2 ?';//秒分时日月周年
system.schedule('One Time Pro', sch, p);
每小时运行一次
System.schedule('交际费预算每小时运行一次', '0 0 * * * ?', new Sch_Interface_B2B_ComBudget() );
无参数情况并立即启动:
Database.executeBatch(new UpdateAccountFields());
Database.executeBatch(new UpdateAccountFields(),'ID',数量);
原始页面报错:
对象.addError('');
自己定义的页面报错
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, '责任人字段必填'));
List<String> listHaveAcquiredLsit = new List<String>();
List<String> designInformationList = new List<String>();
Integer i = 0;
Schema.DescribeSObjectResult dsr = 对象名.sObjectType.getDescribe();
Map<String, Schema.SObjectField> field_map = dsr.fields.getMap();
List<Schema.PicklistEntry> HaveAcquiredValues = field_map.get('字段名').getDescribe().getPickListValues();
List<Schema.PicklistEntry> DesignInfoValues = field_map.get('字段名').getDescribe().getPickListValues();
for (Schema.PicklistEntry a : HaveAcquiredValues) {
listHaveAcquiredLsit.add(a.getValue());
}
for (Schema.PicklistEntry a : DesignInfoValues) {
designInformationList.add(a.getValue());
}
public static Map<String,String> getPickList(String objectName,String fieldname){
Map<String,String> picklistMap = new Map<String,String>();
Schema.SObjectType targetType = Schema.getGlobalDescribe().get(objectName);//From the Object Api name retrieving the SObject
Sobject Object_name = targetType.newSObject();
Schema.sObjectType sobject_type = Object_name.getSObjectType(); //grab the sobject that was passed
Schema.DescribeSObjectResult sobject_describe = sobject_type.getDescribe(); //describe the sobject
Map<String, Schema.SObjectField> field_map = sobject_describe.fields.getMap(); //get a map of fields for the passed sobject
List<Schema.PicklistEntry> pick_list_values = field_map.get(fieldname).getDescribe().getPickListValues(); //grab the list of picklist values for the passed field on the sobject
for (Schema.PicklistEntry a : pick_list_values) { //for all values in the picklist list
picklistMap.put(a.getValue(), a.getLabel());
}
return picklistMap;
}
去空行
opp.Field4YZSQ__c = opp.Field4YZSQ__c.replaceAll('((\r\n)|\n)[\\s\t ]*(\\1)+', '$1').replaceAll('^((\r\n)|\n)', '');
替换
opp.Field4YZSQ__c = opp.Field4YZSQ__c.replaceAll(旧值,新值);
包含
contains
list转string
String s = String.join(集合名称,';')
string转list
str.split(';')
map转obj
Map<String,String> mapstr = new Map<String,String>();
mapstr.put('Name', 'true');
mapstr.put('Id', 'eee');
String s = JSON.serialize(mapstr);
Account acc = (Account)JSON.deserialize(s, Account.class);
System.debug(acc);
Object 转 Map
Map<String, Object> tempMap = (Map<String, Object>)JSON.deserializeUntyped(JSON.serialize(Object));
SF中,与审批有关的对象:
ProcessInstance
关联了记录
ProcessInstanceHistory
PorcessInstanceHistory
被分配人 =======> OriginalActorId
实际批准人 =======> ActorId
审批日期 =======> SystemModstamp
审批状态 =======> StepStatus
审批整体状态 =======> 与之相对应的ProcessInstance上的Status
审批留言 =======> Comments
审批目标对象 =======> TargetObjectId
Approval Status:(ProcessInstance:Status, ProcessInstanceHistory:StepStatus)
中文名 API Name Label
已批准 =====>Approved =====> Approved
故障 =====>Fault =====> Fault
暂停 =====>Held =====> Hold
无响应 =====>NoResponse =====> NoResponse
待处理 =====>Pending => Pending
已重新分配=>Reassigned =====> Reassigned
已拒绝 =====>Rejected =====> Rejected
已调回 =====>Removed =====> Recalled
已提交 =====>Started =====> Submitted
ProcessInstanceStep 已完成的审批
ProcessInstanceWorkitem 等待审批的记录
ProcessNode
TargetObject.
通过/拒绝某个节点的审批
//Class used for Approving Record
Approval.ProcessWorkitemRequest req = new Approval.ProcessWorkitemRequest();
req.setComments('Approving request for Opportunity');
//Approve or Reject Record
req.setAction('Approve');//设置状态为批注还是拒绝 Reject
//Getting Work Item Id
ProcessInstanceWorkitem pItem = [Select Id from ProcessInstanceWorkitem
where ProcessInstance.TargetObjectId =: opp.id];
req.setWorkitemId(pItem.Id);
// Submit the request for approval
Approval.ProcessResult result = Approval.process(req);
自动提起审批流
单个提交审批
Approval.ProcessSubmitRequest req1 = new Approval.ProcessSubmitRequest();
req1.setComments('新供应商注册信息已提交,请审核!');
req1.setObjectId(需要审批的记录的Id);
req1.setSubmitterId(初始提交人Id);
req1.setProcessDefinitionNameOrId('批准进程api Name');
// req1.setNextApproverIds(approverIdList);// 下一步审批人,传入参数必须为List,注意是队列类型小组Id,而不是用户Id
// req1.setSkipEntryCriteria(true);// 是否跳过标准
Approval.ProcessResult result = Approval.process(req1);
批量提交审批
List<Approval.ProcessSubmitRequest> requests = new List<Approval.ProcessSubmitRequest>();
For(对象){
Approval.ProcessSubmitRequest req1 = new Approval.ProcessSubmitRequest();
req1.setComments('新供应商注册信息已提交,请审核!');
req1.setObjectId(需要审批的记录的Id);
req1.setSubmitterId(初始提交人Id);
req1.setProcessDefinitionNameOrId('批准进程api Name');
// req1.setNextApproverIds(approverIdList);// 下一步审批人,传入参数必须为List,注意是队列类型小组Id,而不是用户Id
// req1.setSkipEntryCriteria(true);// 是否跳过标准
requests.add(req1);
}
Approval.ProcessResult[] processResults = Approval.process(requests);
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restful_crypto.htm?search_text=Crypto
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restful_encodingUtil.htm?search_text=EncodingUtil
Blob str = '';//要加密的数据
MD5加密
String myString = 'Some String';
Blob myBlob = Blob.valueOf(myString);
Blob md5hash = Crypto.generateDigest('MD5',myBlob);
System.debug(EncodingUtil.convertToHex(md5hash));//显示密文
Basic64转码
String uspastr = EncodingUtil.base64Encode(str );
String defaultUser = 自定义对象APi.getInstance('BidPrincipal').字段;
获取集合
Map(String,obj) = 自定义对象APi.getall();
List = 自定义对象APi.getall().values();
来自 https://developer.salesforce.com/forums/?id=906F0000000MNvmIAG
获取所有字段
SObjectType esalesTemp = Schema.getGlobalDescribe().get('表名称');
Map<String,Schema.SObjectField> mfields = esalesTemp.getDescribe().fields.getMap();
for (String s: mfields.keySet()) {
SObjectField fieldToken = mfields.get(s);
DescribeFieldResult selectedField = fieldToken.getDescribe();
System.debug('===Name=='+selectedField.getName()); //API名称
System.debug('===Label=='+selectedField.getLabel()); //字段标签
System.debug('===Type=='+selectedField.getType());//数据类型
Boolean isRequired = false;
if (selectedField.isNillable() == false) {
isRequired = true;
}else{
isRequired = false;
}
System.debug('===isRequired=='+isRequired);
}
获取特定的选项列表字段:
List<String> result = new List<String>();
Schema.DescribeFieldResult fieldResult = 表名称.字段API.getDescribe();
List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
for( Schema.PicklistEntry f : ple)
{
result.add(f.getLabel());
}
表名称.字段API.getDescribe().getLabel()
// 获取全部字段
List fields = new List(AgreementPayment__c.SObjectType.getDescribe().fields.getMap().keySet());
Set set_agmeId = new Set();
set_agmeId.addAll(map_agid_queidset.keySet());
String appaSql = 'select ' + String.join(fields, ',') + ' from AgreementPayment__c where Agreement__c in: set_agmeId';
Map<Decimal,Decimal> maps = new Map<Decimal,Decimal>();
maps.put(1, 2);
maps.put(2, 7);
maps.put(5, 9);
System.debug(maps.keySet().iterator().next());
System.debug(maps.values().iterator().next());
基础链接:
Url.getSalesforceBaseUrl().toExternalForm()
完全链接:
ApexPages.currentPage().getURL()
UserInfo.getId();
某个ID.getsobjecttype().getDescribe()
Id.valueOf('a0G0p0000005bVT').getsobjecttype().getDescribe().getName()
无邮件模板
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {UserInfo.getUserEmail()};
mail.setToAddresses(toAddresses);
mail.setSenderDisplayName('销售目标');
mail.setSubject('主题');
mail.setHtmlBody( '内容' );
Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
有邮件模板
List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();
Messaging.SingleEmailMessage temail = new Messaging.SingleEmailMessage();
temail.setSenderDisplayName('主题');
temail.setWhatId(邮件需要的对象Id);
temail.setTargetObjectId(联系人Id);
temail.setTreatTargetObjectAsRecipient(false);
temail.setTemplateId(邮件模板Id);
temail.setSaveAsActivity(false);
temail.setToAddresses(addresses);
emails.add(temail);
Messaging.sendEmail(emails);
如果需要的对象为潜客 则
temail.setWhatId(邮件需要的对象Id); 不需要了
temail.setTargetObjectId(联系人Id);修改为 temail.setTargetObjectId(潜客ID);
// Instantiate a new http object
Http h = new Http();
// Instantiate a new HTTP request, specify the method (GET) as well as the endpoint
HttpRequest req = new HttpRequest();
req.setEndpoint('YOUR_URL');
req.setTimeout(60000);//sets maximum timeout
req.setMethod('GET');
// Send the request, and return a response
HttpResponse res = h.send(req);
Blob body = res.getBodyAsBlob();
//then you can attach this body wherever you want
Attachment att = new Attachment(Name = 'SET A NAME', Body = body, ContentType = 'SET A VALID CONTENT TYPE', ParentId='PARENT_OBJ_ID');
insert att;
来自 https://developer.salesforce.com/forums/?id=906F0000000ApEAIA0
public class ImportOrderItemController
{
public class PrboObj
{
public Boolean isCheck {get; set; }
public Pricebook2 prbo {get; set; }
}
public Blob csvFileBody {get; set; } //csv文件内容
public string csvAsString {get; set; }
public String[] csvFileLines {get; set; } //存储csv中每行数据
public String downurl {get; set; }
public String orderId; //订单Id
public class OritList
{
public String productCode {get; set; } //产品代码
public String productname {get; set; } //产品名称
public String callGues {get; set; }
public OrderItem orit {get; set; }
}
public List < OritList > orderItemList {get; set; } //订单明细
public List < PrboObj > prboList {get; set; }
public String prboID = '';
public String currencyIsoCode = '';
public ImportOrderItemController()
{
prboList = new List < PrboObj > ();
csvFileLines = new String[]
{};
orderItemList = New List < OritList > ();
orderId = system.currentPageReference().getParameters().get('id');
Order ord = [select Id, Pricebook2Id, Pricebook2.CurrencyIsoCode, CurrencyIsoCode from Order where Id = : orderId][0];
if (ord.Pricebook2Id != null)
{
prboID = ord.Pricebook2Id;
}
currencyIsoCode = ord.CurrencyIsoCode;
String query = 'select Id,name,Description,IsStandard, CurrencyIsoCode from Pricebook2 ';
if (!String.isEmpty(prboID))
{
query += ' where Id =\'' + prboID + '\' ';
}
query += ' order by name limit 5000 ';
system.debug(query);
List < Pricebook2 > prboList_sele = Database.query(query);
for (Pricebook2 prbo: prboList_sele)
{
PrboObj prob = new PrboObj();
prob.isCheck = false;
if (!String.isEmpty(prboID)) prob.isCheck = true;
prob.prbo = prbo;
prboList.add(prob);
}
downurl = Url.getSalesforceBaseUrl().toExternalForm() + '/apex/DownloadOrderItemTemplate?orId=' + orderId;
System.debug(downurl);
}
//获取csv中的数据,封装成订单明细对象
public void importCSVFile()
{
//先选择价格手册,如果没有选择则报错
Set < String > strset_prbo = new Set < String > ();
for (PrboObj prbo: prboList)
{
if (prbo.isCheck == true)
{
strset_prbo.add(prbo.prbo.Id);
prboID = prbo.prbo.Id;
}
}
if (strset_prbo.size() == 0)
{
ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.ERROR, '请先选择价格手册');
ApexPages.addMessage(errorMessage);
return;
}
if (strset_prbo.size() != 1)
{
ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.ERROR, '只能选择一个价格手册');
ApexPages.addMessage(errorMessage);
return;
}
//选择价格手册结束
try
{
orderItemList = New List < OritList > ();
//调用方法解析分级
csvAsString = blobToString(csvFileBody, 'GBK');
System.debug(csvAsString);
csvFileLines = csvAsString.split('\n');
System.debug('订单记录Id:' + system.currentPageReference().getParameters().get('id'));
if(csvFileLines.size() < 2)
{
ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.ERROR, '没有需要导入的记录');
ApexPages.addMessage(errorMessage);
return;
}
//查找产品
Set < String > strSet_produ = new Set < String > ();
for (Integer i = 1; i < csvFileLines.size(); i++)
{
string[] csvRecordData = csvFileLines[i].split(',');
Integer cssize = csvRecordData.size() - 1;
if (cssize >= 3) strSet_produ.add(csvRecordData[3]);
if (cssize >= 4) strSet_produ.add(csvRecordData[4]);
strSet_produ.add(csvRecordData[0]);
}
//查询产品
List < PricebookEntry > prenList = new List < PricebookEntry > ([
select Id, Product2Id, Product2.Name,Product2.ProductCode, UnitPrice, CurrencyIsoCode,Pricebook2Id from PricebookEntry
where Pricebook2Id in : strset_prbo and CurrencyIsoCode = : currencyIsoCode and (Product2.Name in: strSet_produ or Product2.ProductCode in: strSet_produ)]);
Map < String, PricebookEntry > strMap_id = new Map < String, PricebookEntry > ();
/*List < Product2 > prduList_sele = new List < Product2 > ([
select Id, name, ProductCode from Product2 where name in : strSet_produ or ProductCode in : strSet_produ]);*/
for (PricebookEntry prdu: prenList)
{
strMap_id.put(prdu.Product2Id, prdu);
if (prdu.Product2.Name != null)
{
strMap_id.put(prdu.Product2.Name, prdu);
}
if (prdu.Product2.ProductCode != null)
{
strMap_id.put(prdu.Product2.ProductCode, prdu);
}
}
//
List < OrderItem > oritlist_sele = new List < OrderItem > ([select
Id, Productline__c, Specification__c, Product2Id, Quantity,
SubtotalF__c, Call_Guest__c, Description, Product_Name__c, UnitPrice2__c,
OrderItemNumber, OrderId,PricebookEntryId
from orderItem where id in : strSet_produ]);
if (!oritlist_sele.isEmpty() && oritlist_sele[0].OrderId != orderId)
{
ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.ERROR, '订单明细关联的订单与本订单不符合');
ApexPages.addMessage(errorMessage);
return;
}
Map < String, OrderItem > strobjmap_orit = new Map < String, OrderItem > ();
for (OrderItem orit: oritlist_sele)
{
strobjmap_orit.put(orit.Id, orit);
}
//构建订单明细
Set < String > strset_produId = new Set < String > ();
for (Integer i = 1; i < csvFileLines.size(); i++)
{
string[] csvRecordData = csvFileLines[i].split(',');
Integer cssize = csvRecordData.size() - 1;
System.debug(csvRecordData.size() + '===' + 'csvRecordData' + csvRecordData);
//
OritList orli = new OritList();
if (cssize >= 3) orli.productCode = csvRecordData[3]; //产品代码
if (cssize >= 8) orli.callGues = csvRecordData[8]; //客供否
orli.productname = csvRecordData[4]; //品名
OrderItem orderItem = new OrderItem();
if (!string.isEmpty(csvRecordData[0]))
{
orderItem = strobjmap_orit.get(csvRecordData[0]);
System.debug(orderItem);
}
else
{
orderItem.OrderId = orderId;
}
//价格手册和产品赋值
if (string.isEmpty(csvRecordData[1]))
{
PricebookEntry pren = strMap_id.get(csvRecordData[3]) == null ? strMap_id.get(csvRecordData[4]) : strMap_id.get(csvRecordData[3]);//获取价格手册条目
if (pren == null)
{
ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.ERROR, '第' + i + '行中的产品不在该价格手册下');
ApexPages.addMessage(errorMessage);
return;
}
String proId = strMap_id.get(csvRecordData[3]) == null ? strMap_id.get(csvRecordData[4]).Id : strMap_id.get(csvRecordData[3]).Id; //获取产品Id
orderItem.Product2Id = pren.Product2Id; //产品
orderItem.Product_Name__c = pren.Product2.Name;
orderItem.PricebookEntryId = pren.Id;
orderItem.UnitPrice2__c = pren.UnitPrice;
strset_produId.add(proId);
}
System.debug(csvRecordData[2]);
if (cssize >= 2) orderItem.Productline__c = csvRecordData[2]; //产品项次
System.debug(orderItem.Productline__c);
if (cssize >= 5) orderItem.Specification__c = csvRecordData[5]; //规格型号
if (cssize >= 6 && !String.isEmpty(csvRecordData[6])) orderItem.Quantity = Decimal.valueOf(csvRecordData[6]); //数量/面积
if (cssize >= 7 && !String.isEmpty(csvRecordData[7])) orderItem.SubtotalF__c = Decimal.valueOf(csvRecordData[7]); //卖价总计
if (cssize >= 8) orderItem.Call_Guest__c = csvRecordData[8] == '是' ? true : false; //客供否
if (cssize >= 9) orderItem.Description = csvRecordData[9]; //行备注
orderItem.UnitPrice = 0;
orli.orit = orderItem;
orderItemList.add(orli);
}
/*List < PricebookEntry > prenList = new List < PricebookEntry > ([
select Id, Product2Id, Product2.Name, UnitPrice, CurrencyIsoCode from PricebookEntry
where Product2Id in : strset_produId and Pricebook2Id in : strset_prbo and CurrencyIsoCode = : currencyIsoCode]);
Map < String, PricebookEntry > strmap_propri = new Map < String, PricebookEntry > ();
for (PricebookEntry pren: prenList)
{
strmap_propri.put(pren.Product2Id, pren);
}
for (OritList oritli: orderItemList)
{
OrderItem orderItem = oritli.orit;
if (orderItem.Id == null)
{
System.debug(strmap_propri.get(orderItem.Product2Id));
if(strmap_propri.get(orderItem.Product2Id) != null)
{
orderItem.PricebookEntryId = strmap_propri.get(orderItem.Product2Id).id;
orderItem.UnitPrice2__c = strmap_propri.get(orderItem.Product2Id).UnitPrice;
}
orderItem.OrderId = orderId;
}
}*/
csvFileBody = null;
}
catch (Exception e)
{
if(e.getMessage().contains('Argument cannot be null.'))
{
ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.ERROR, '引用了空值');
ApexPages.addMessage(errorMessage);
return;
}
ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.ERROR, '请选择csv文件或确认csv文件格式是否正确!' + e.getMessage());
system.debug(e.getLineNumber());
ApexPages.addMessage(errorMessage);
}
}
//保存记录
public PageReference save()
{
List < OrderItem > oritlist_upsert = new List < OrderItem > ();
for (OritList oritli: orderItemList)
{
oritlist_upsert.add(oritli.orit);
}
upsert oritlist_upsert Id;
return new PageReference('/' + orderId);
}
//取消
public PageReference cancel()
{
return new PageReference('/' + orderId);
}
//将Blob转换成指定编码格式的String
public static String blobToString(Blob input, String inCharset)
{
System.debug(String.valueOf(input));
String hex = EncodingUtil.convertToHex(input);
System.assertEquals(0, hex.length() & 1);
final Integer bytesCount = hex.length() >> 1;
String[] bytes = new String[bytesCount];
for (Integer i = 0; i < bytesCount; ++i) bytes[i] = hex.mid(i << 1, 2);
return EncodingUtil.urlDecode('%' + String.join(bytes, '%'), inCharset);
}
}
<apex:page controller="ImportOrderItemController">
<script type="text/javascript">
function downfile(url){
window.open(url);
}
script>
<apex:pageBlock title="导入订单明细">
<apex:form >
<apex:pagemessages />
<apex:pageBlockSection title="价格手册" columns="1" id="Section" >
<apex:pageblocktable value="{!prboList}" var="prbo">
<apex:column headerValue="选择">
<apex:inputCheckbox value="{!prbo.isCheck}" />
apex:column>
<apex:column headerValue="{!$ObjectType['Pricebook2'].fields['name'].Label}" >
<apex:outputField value="{!prbo.prbo.Name} " />
apex:column>
<apex:column headerValue="{!$ObjectType['Pricebook2'].fields['Description'].Label}" >
<apex:outputField value="{!prbo.prbo.Description} " />
apex:column>
<apex:column headerValue="{!$ObjectType['Pricebook2'].fields['IsStandard'].Label}" >
<apex:outputField value="{!prbo.prbo.IsStandard} " />
apex:column>
apex:pageblocktable>
apex:pageBlockSection>
<center>
<apex:inputFile value="{!csvFileBody}" filename="{!csvAsString}" style="margin-bottom:10px"/>
<apex:comma
ndButton value="导入" action="{!importCSVFile}" style="margin-bottom:10px"/>
<apex:commandButton value="下载模板" onclick="downfile('{!downurl}')"/>
center>
<apex:pageblocktable value="{!orderItemList}" var="order" id="orderitemall">
<apex:column headerValue="{!$ObjectType['OrderItem'].fields['OrderItemNumber'].Label}" style="width: 11%">
<apex:outputField value="{!order.orit.OrderItemNumber} " />
apex:column>
<apex:column headerValue="{!$ObjectType['OrderItem'].fields['Productline__c'].Label}" style="width: 11%">
<apex:outputField value="{!order.orit.Productline__c} " />
apex:column>
<apex:column headerValue="产品代码" style="width: 11%">
<apex:outputText value="{!order.productCode} "/>
apex:column>
<apex:column headerValue="产品名称" style="width: 11%">
<apex:outputField value="{!order.orit.Product2Id} " />
apex:column>
<apex:column headerValue="{!$ObjectType['OrderItem'].fields['Product_Name__c'].Label}" style="width: 11%">
<apex:outputField value="{!order.orit.Product_Name__c} " />
apex:column>
<apex:column headerValue="{!$ObjectType['OrderItem'].fields['Specification__c'].Label}" style="width: 11%">
<apex:outputField value="{!order.orit.Specification__c} " />
apex:column>
<apex:column headerValue="{!$ObjectType['OrderItem'].fields['UnitPrice2__c'].Label}" style="width: 11%">
<apex:outputText value="{!order.orit.UnitPrice2__c} " />
apex:column>
<apex:column headerValue="{!$ObjectType['OrderItem'].fields['Quantity'].Label}" style="width: 11%">
<apex:outputField value="{!order.orit.Quantity} " />
apex:column>
<apex:column headerValue="{!$ObjectType['OrderItem'].fields['SubtotalF__c'].Label}" style="width: 11%">
<apex:outputText value="{!order.orit.SubtotalF__c} " />
apex:column>
<apex:column headerValue="{!$ObjectType['OrderItem'].fields['Call_Guest__c'].Label}" style="width: 11%">
<apex:outputText value="{!order.callGues} " />
apex:column>
<apex:column headerValue="{!$ObjectType['OrderItem'].fields['Description'].Label}" style="width: 11%">
<apex:outputField value="{!order.orit.Description} " />
apex:column>
apex:pageblocktable>
<center>
<apex:commandButton value="保存" action="{!save}" style="margin-right:50px;margin-top:50px"/>
<apex:commandButton value="取消" action="{!cancel}" style="margin-top:50px"/>
center>
apex:form>
apex:pageBlock>
apex:page>
String str = 'sdf1sf**&';
String reg = '[^a-zA-Z0-9]';
str=str.replaceAll(reg,'');
System.debug(str);
SELECT Id, (SELECT LastName FROM Contacts),(SELECT Description FROM Opportunities) FROM Account WITH SECURITY_ENFORCED
//By SharSolutions
public class MyPickListInfo
{
public String validFor;
}
public static Map<String, List<String>> getFieldDependencies(String objectName, String controllingField, String dependentField)
{
Map<String, List<String>> controllingInfo = new Map<String, List<String>>();
Schema.SObjectType objType = Schema.getGlobalDescribe().get(objectName);
Schema.DescribeSObjectResult describeResult = objType.getDescribe();
Schema.DescribeFieldResult controllingFieldInfo = describeResult.fields.getMap().get(controllingField).getDescribe();
Schema.DescribeFieldResult dependentFieldInfo = describeResult.fields.getMap().get(dependentField).getDescribe();
List<Schema.PicklistEntry> controllingValues = controllingFieldInfo.getPicklistValues();
List<Schema.PicklistEntry> dependentValues = dependentFieldInfo.getPicklistValues();
for(Schema.PicklistEntry currControllingValue : controllingValues)
{
System.debug('ControllingField: Label:' + currControllingValue.getLabel());
controllingInfo.put(currControllingValue.getLabel(), new List<String>());
}
for(Schema.PicklistEntry currDependentValue : dependentValues)
{
String jsonString = JSON.serialize(currDependentValue);
MyPickListInfo info = (MyPickListInfo) JSON.deserialize(jsonString, MyPickListInfo.class);
String hexString = EncodingUtil.convertToHex(EncodingUtil.base64Decode(info.validFor)).toUpperCase();
System.debug('DependentField: Label:' + currDependentValue.getLabel() + ' ValidForInHex:' + hexString + ' JsonString:' + jsonString);
Integer baseCount = 0;
for(Integer curr : hexString.getChars())
{
Integer val = 0;
if(curr >= 65)
{
val = curr - 65 + 10;
}
else
{
val = curr - 48;
}
if((val & 8) == 8)
{
System.debug('Dependent Field: ' + currDependentValue.getLabel() + ' Partof ControllingField:' + controllingValues[baseCount + 0].getLabel());
controllingInfo.get(controllingValues[baseCount + 0].getLabel()).add(currDependentValue.getLabel());
}
if((val & 4) == 4)
{
System.debug('Dependent Field: ' + currDependentValue.getLabel() + ' Partof ControllingField:' + controllingValues[baseCount + 1].getLabel());
controllingInfo.get(controllingValues[baseCount + 1].getLabel()).add(currDependentValue.getLabel());
}
if((val & 2) == 2)
{
System.debug('Dependent Field: ' + currDependentValue.getLabel() + ' Partof ControllingField:' + controllingValues[baseCount + 2].getLabel());
controllingInfo.get(controllingValues[baseCount + 2].getLabel()).add(currDependentValue.getLabel());
}
if((val & 1) == 1)
{
System.debug('Dependent Field: ' + currDependentValue.getLabel() + ' Partof ControllingField:' + controllingValues[baseCount + 3].getLabel());
controllingInfo.get(controllingValues[baseCount + 3].getLabel()).add(currDependentValue.getLabel());
}
baseCount += 4;
}
}
System.debug('ControllingInfo: ' + controllingInfo);
return controllingInfo;
}
List<ConnectApi.BatchInput> batchInputs = new List<ConnectApi.BatchInput>();
ConnectApi.FeedItemInput feedItemInput = new ConnectApi.FeedItemInput();
ConnectApi.MentionSegmentInput mentionSegmentInput = new ConnectApi.MentionSegmentInput();
ConnectApi.MessageBodyInput messageBodyInput = new ConnectApi.MessageBodyInput();
ConnectApi.TextSegmentInput textSegmentInput = new ConnectApi.TextSegmentInput();
messageBodyInput.messageSegments = new List<ConnectApi.MessageSegmentInput>();
//拼接上链接
ConnectApi.EntityLinkSegmentInput entityLinkSegmentInputOpportunity = new ConnectApi.EntityLinkSegmentInput();
entityLinkSegmentInputOpportunity.entityId = 要链接的记录的ID;
messageBodyInput.messageSegments.add(entityLinkSegmentInputOpportunity);
mentionSegmentInput.id = 要@的人的ID;
messageBodyInput.messageSegments.add(mentionSegmentInput);
textSegmentInput.text = 发送的内容;
messageBodyInput.messageSegments.add(textSegmentInput);
feedItemInput.body = messageBodyInput;
feedItemInput.feedElementType = ConnectApi.FeedElementType.FeedItem;
feedItemInput.subjectId =关联的记录;
feedItemInput.visibility = ConnectApi.FeedItemVisibilityType.AllUsers;//设置该chatter的权限(ConnectApi.FeedItemVisibilityType.InternalUsers默认,只有销售云中的用户可见;ConnectApi.FeedItemVisibilityType.AllUsers其他云的用户也可见)
ConnectApi.BatchInput batchInput = new ConnectApi.BatchInput(feedItemInput);
batchInputs.add(batchInput);
ConnectApi.ChatterFeeds.postFeedElementBatch(Network.getNetworkId(), batchInputs);
Apex: String someLabel = System.Label.Label_API_Name;
/**
* 从接口中下载文件,需要获取到文件下载的链接和文件的名称
* @param fileLink [文件链接]
* @param fileName [文件名称(带后缀名)]
* @param parid [要关联的记录ID]
* @param ownerid [文件的所有人ID]
*/
@future(callout = true)
public static void esbCalloutTest(String fileLink, String fileName, Id parid, Id ownerid)
{
try
{
//发送请求
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint(fileLink);
req.setTimeout(60000);
req.setMethod('GET');
HttpResponse res1 = h.send(req);
Blob body = res1.getBodyAsBlob();
//保存文件
Attachment att = new Attachment();
att.Name = fileName;
att.Body = body;
att.ContentType = '';
att.ParentId = parid;
att.OwnerId = ownerid;
insert att;
}
catch (Exception e)
{
system.debug(e.getLineNumber() + e.getMessage());
}
}
//附件
List < ContentDocumentLink > cdllist = [select ContentDocumentId, LinkedEntityId from ContentDocumentLink where LinkedEntityId = : 对象ID];
Set < String > cdIdSet = new Set < String > ();
for (ContentDocumentLink cdl: cdllist)
{
cdIdSet.add(cdl.ContentDocumentId);
}
//获取文件名称
List < ContentDocument > cdclist = [select Id, OwnerId, Owner.Name, Owner.EmployeeCode__c, Title, CreatedDate FROM ContentDocument where Id in : cdIdSet];
//获取链接
List < ContentDistribution > cdlist = [select ContentDocumentId, DistributionPublicUrl, ContentDownloadUrl from ContentDistribution where ContentDocumentId in : cdIdSet];
//获取文件的类型
List < ContentVersion > covelist = new List < ContentVersion > ([select id, ContentDocumentId, FileExtension from ContentVersion where ContentDocumentId in : cdIdSet]);
Map < Id, String > idsetmap_docufile = new Map < Id, String > ();
for (ContentVersion cove: covelist)
{
idsetmap_docufile.put(cove.ContentDocumentId, cove.FileExtension);
}
List < SettlementCode_Entity.AttAchmentList > attlist = new List < SettlementCode_Entity.AttAchmentList > ();
for (ContentDocument cdc: cdclist)
{
for (ContentDistribution cd: cdlist)
{
if (cdc.Id == cd.ContentDocumentId)
{
attFile atli = new attFile();
atli.FileName = cdc.Title + '.' + idsetmap_docufile.get(cdc.Id);
atli.URL = cd.ContentDownloadUrl;
atfilist.add(atli);
}
}
}
frjs.AttachFile = atfilist;
apexpages.currentPage().getParameters().get('applicationId');
出席者 Attendees 是一个对象,而不是一个字段
对象:EventRelation
SELECT Id, Relationid, Relation.name, EventId,isinvitee FROM EventRelation where isinvitee = true
isinvitee == true 为出席者
https://help.salesforce.com/articleView?id=000324749&type=1&mode=1
Add a static boolean variable to a class, and check its value within the affected triggers.
public class HelperClass { public static boolean firstRun = true; }
trigger affectedTrigger on Account (before delete, after delete, after undelete)
{
if(Trigger.isBefore)
{
if(Trigger.isDelete)
{
if(HelperClass.firstRun)
{
Trigger.old[0].addError('Before Account Delete Error');
HelperClass.firstRun=false;
}
}
}
}
Yes you can!
First get the sObjectType of the ListView by querying like
SELECT Id, sObjectType FROM ListView WHERE Id = :yourId
Then simply make a callout to your own org with a URL like
/services/data/v40.0/sobjects/[sObjectType]/listviews/[yourId]/describe
You will get back an object with (amongst others) a query attribute. Use that to query your records.
Making a callout to your own org has become even easier since spring 19 because you don’t need a Remote Site Setting and can use UserInfo.getSessionId() even in async jobs.
Good luck!
https://salesforce.stackexchange.com/questions/167009/can-we-access-all-listview-records-of-any-object-using-listview-id
方法一:把生成的验证码保存在一个静态变量中,然后设置一个缓存时间,二次传入的时候
把生成的验证码存放在一个静态变量中
public static RS_CacheManager cacheManager = new RS_CacheManager(false);
/**
* 获取验证码
*/
public static String getCaptcha(String mobile){
if(String.isBlank(mobile)){
return null;
}
System.debug('RS_SessionCache.getCaptcha:'+mobile);
RS_CacheManager cacheManager = RS_SessionCache.cacheManager;
String captcha = (String)cacheManager.get(RS_Constants.CACHE_KEY_CAPTCHA + mobile);
return captcha;
}
https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_dateformats.htm
客户中标准生日字段
查询今天的数据是如果用 = today 或 yesterday 时只匹配月份和日期,不匹配年份
TimeZone tz = UserInfo.getTimeZone();
DateTime dt = Datetime.now();
system.debug('gmt时间 ' + dt);
system.debug('正确时间' + dt.format());
system.debug('Offset ' + tz.getOffset(dt)/1000);
system.debug('Formatted Time ' + dt.addSeconds((tz.getOffset(dt)/1000)));
使用 GROUP BY 进行分组,并且搜索出来的字段仅能是Id和用于分组的字段。
List<AggregateResult> agrResult = new List<AggregateResult>([SELECT Status FROM Case GROUP BY Status]);//
注意点:不能超过2000条数据,limit 2000
System.isSchedulable()
https://salesforce.stackexchange.com/questions/29520/how-to-prevent-a-trigger-firing-during-a-batch-job
Database.AllowsCallouts
SELECT Id, MSP1__c from CustObj__c WHERE MSP1__c includes ('AAA;BBB','CCC')
Decimal rA = 1298763.86;
Integer ra2 = Integer.valueOf(rA);
List<String> args = new String[]{'0','number','###,###,##0.00'};
String s = String.format(ra2.format(), args);
System.debug(s);
Account record = [select Id,textlong__c from Account where id = '0010K00002I3aCI'];
// use reluctant regex to match each image tag individually
// https://docs.oracle.com/javase/tutorial/essential/regex/quant.html
Matcher imgMatcher = Pattern.compile( '<img(.+?)>' ).matcher( record.textlong__c );
// iterate each image tag found
while ( imgMatcher.find() ) {
// get the image tag html
String imageTag = imgMatcher.group();
System.debug( 'imageTag=' + imageTag );
// get the value of the src attribute
// the leading space is significant to avoid other attributes like data-cke-saved-src
String imageURL = imageTag.substringBetween( ' src="', '"' );
System.debug( 'imageURL=' + imageURL );
// if url contained parameters they might be html escaped, unescape them
// or, more conservatively, replace '&' with '&'
String decodedURL = imageURL.unescapeHtml4();
System.debug( 'decodedURL=' + decodedURL );
// note, as of API 34.0 or later, getContent() is considered an http callout
// so take that into consideration for your unit tests and governor limits
// https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/apex_System_PageReference_getContent.htm
PageReference page = new PageReference( decodedURL );
Blob b = page.getContent();
System.debug( 'blob=' + b );
System.debug( 'Enjoy your Blob, save it as a Document, ContentVersion, whatever!' );
System.debug(''); // I like blank lines in my logs, easier to scan/read =)
}
Date selectedDate = Date.today();
Date lastDate = selectedDate.toStartOfMonth().addDays(Date.daysInMonth(selectedDate.year(), selectedDate.month()) - 1);
System.debug(lastDate);
BusinessHours bh = [SELECT Id FROM BusinessHours WHERE IsDefault=true];
System.debug(BusinessHours.isWithin(bh.id, lastDate));
BusinessHours.isWithin(bh.id, lastDate) 如果这一天是工作日,那么则返回true,如果不是,则返回false
Date selectedDate = Date.today();
Date lastDate = selectedDate.toStartOfMonth().addDays(Date.daysInMonth(selectedDate.year(), selectedDate.month()) - 1);
System.debug(lastDate);
BusinessHours bh = [SELECT Id FROM BusinessHours WHERE IsDefault=true];
System.debug(BusinessHours.isWithin(bh.id, lastDate));
Integer i = 0;
Date last2day;
while (i < 2)
{
if (BusinessHours.isWithin(bh.id, lastDate))
{
i++;
}
last2day = lastDate;
lastDate = lastDate.addDays(-1);
}
System.debug(last2day);
不可以。SF的限制
https://salesforce.stackexchange.com/questions/300961/is-it-possible-to-change-the-size-of-the-auto-chunked-batches-in-bulk-api
AI Application config
Action
Action Link Group Template
Allow URL for Redirects
Apex Class
Apex Sharing Reason
Apex Trigger
App
Approval Process
Asset File
Assignment Rule
Assistant Recommendation Type
Aura Component Bundle
Auth. Provider
Auto-Response Rule
Button or Link
CORS Allowed Origin List
Call Center
Case Keywords Priority
Channel Menu Deployment
Chat Agent Configuration
Chat Blocking Rule
Chat Button
Chat Deployment
Classic Letterhead
Communication Channel Layout
Compact Layout
Content Security Policy Trusted Site
Custom Console Component
Custom Data Type
Custom Field
Custom Help Menu Section
Custom Index
Custom Label
Custom Metadata Type
Custom Notification Type
Custom Object
Custom Permission
Custom Report Type
Custom Setting
Dashboard
Data Service
Document
Duplicate Rule
EclairNG Map GeoJson
Email Service
Email Template
Embedded Service Deployment
Entitlement Process
Entitlement Template
Entity Implements
Escalation Rule
Event Subscription
Extension
External Data Source
External Service Registration
Feed Filter
Field Mapping
Field Set
Flow Definition
Folder
Global Value Set
Group
Home Page Component
Home Page Layout
Inbound Network Connection
Knowledge Action
Language Translation
Lightning Bolt
Lightning Community Template
Lightning Community Theme
Lightning Experience Theme
Lightning Message Channel
Lightning Page
Lightning Web Component Bundle
List View
ML Data Definition
ML Prediction Definition
Managed Content Type
Matching Rule
Microsoft® Outlook® Web App Domain
Milestone
Named Credential
Network
Outbound Network Connection
Page Layout
Path Assistant
Permission Set
Permission Set Group
Platform Cache Partition
Platform Event Channel
Platform Event Channel Member
Platform Event Subscriber Configuration
Post Template
Prompt
Queue
Recommendation Strategy
Record Type
RecordAction Deployment
Remote Site
Report
Reporting Snapshot
Role
S-Control
Security Custom Baseline
Send Action
Sensitive Data Rule
Sharing Criteria Rule
Sharing Guest Rule
Sharing Owner Rule
Sharing Set
Site.com
Skill
Static Resource
Tab
User Provisioning Config
Validation Rule
Visualforce Component
Visualforce Page
Workflow Email Alert
Workflow Field Update
Workflow Outbound Message
Workflow Rule
Workflow Task
Zone
List<String> availableValues = new List<String>{'17','21','33','44','55'};
Integer listSize = availableValues.size() - 1;
Integer randomNumber = Integer.valueof((Math.random() * listSize));
String randomString= availableValues[randomNumber];
System.debug('randomString is'+randomString);
删除
MetadataService.MetadataPort service = new MetadataService.MetadataPort();
List<String> recordsToDelete = new List<String>();
recordsToDelete.add('My_Custom_Type.record1');
service.deleteMetadata('CustomMetadata', recordsToDelete);
From https://salesforce.stackexchange.com/questions/229406/how-to-delete-custom-metadata-records-via-apex
The DescribeSObjectResult Class contains methods for describing sObjects.
Important Methods for DescribeSObjectResult. All are instance methods.
fields
Follow fields with a field member variable name or with the getMap method.
getChildRelationships()
Returns a list of child relationships, which are the names of the sObjects that have a foreign key to the sObject being described.
getLabel()
Returns the object’s label, which may or may not match the object name.
getLabelPlural()
Returns the object’s plural label, which may or may not match the object name.
getName()
Returns the name of the object.
getSobjectType()
Returns the Schema.SObjectType object for the sObject. You can use this to create a similar sObject.
isAccessible()
Returns true if the current user can see this object, false otherwise.
isCreateable()
Returns true if the object can be created by the current user, false otherwise.
isCustom()
Returns true if the object is a custom object, false if it is a standard object.
isCustomSetting()
Returns true if the object is a custom setting, false otherwise.
isDeletable()
Returns true if the object can be deleted by the current user, false otherwise.
isQueryable()
Returns true if the object can be queried by the current user, false otherwise
isSearchable()
Returns true if the object can be searched by the current user, false otherwise.
isUndeletable()
Returns true if the object cannot be undeleted by the current user, false otherwise.
isUpdateable()
Returns true if the object can be updated by the current user, false otherwise.
From https://www.sfdcmeet.com/development/apex-in-salesforce/dynamic-apex-salesforce/
Platform Events Developer Guide | Retry Event Triggers with EventBus.RetryableException (salesforce.com)
https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_subscribe_apex_refire.htm
第二种方法:
queueable job来retry
GitHub - jantaks/salesforce-apex-retry: Retry framework for Salesforce applications
List<Games__mdt> mcs = Games__mdt.getAll().values();
boolean textField = null;
if (mcs[0].GameType__c == 'PC') {
textField = true;
}
system.assertEquals(textField, true);
public static set<Id> getSubordinateRoles(Id roleId) {
map<Id, set<Id>> parentAndChildren = new map<Id, set<Id>>();
set<Id> children;
for(UserRole ur : [select Id, ParentRoleId from UserRole]) {
children = parentAndChildren.containsKey(ur.ParentRoleId) ? parentAndChildren.get(ur.ParentRoleId) : new set<Id>();
children.add(ur.Id);
parentAndChildren.put(ur.ParentRoleId, children);
}
return getSubordinateRoles(role, parentAndChildren);
}
public static set<Id> getSubordinateRoles(Id roleId, map<Id, set<Id>> parentAndChildren) {
set<Id> subordinateRoles = new set<Id>();
set<Id> remainingSubordinateRoles = new set<Id>();
if(parentAndChildren.containsKey(roleId)) {
subordinateRoles.addAll(parentAndChildren.get(roleId));
for(Id subRoleId : subordinateRoles) {
remainingSubordinateRoles.addAll(getSubordinateRoles(subRoleId, parentAndChildren));
}
}
subordinateRoles.addAll(remainingSubordinateRoles);
return subordinateRoles;
}
Map<String, Schema.FieldSet> FsMap = Schema.SObjectType.Account.fieldSets.getMap();
Schema.DescribeSObjectResult d = Account.sObjectType.getDescribe();
Map<String, Schema.FieldSet> FsMap = d.fieldSets.getMap();
Schema.FieldSet fs1 = Schema.SObjectType.Account.fieldSets.getMap().get('field_set_name');
Schema.FieldSet fs2 = Schema.SObjectType.Account.fieldSets.field_set_name;
https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_fieldsets_describe.htm
Account acc = [select Id,(select id from Contacts) from Account limit 1];
system.debug(acc.get('ID'));
system.debug(acc.getSObjects('Contacts'));
实际效果
16:52:32.30 (74317403)|USER_DEBUG|[2]|DEBUG|001xxxxxxxxxxxxxxx
16:52:32.30 (74757995)|USER_DEBUG|[3]|DEBUG|(Contact:{AccountId=001xxxxxxxxxxxxxxx, Id=003xxxxxxxxxxxxxxx})
赋值:
sObject acc = [select lastname, firstname from account limit 1];
system.debug('输出' + acc);
acc.put('lastname','test');
system.debug('输出' + acc);
实际效果
17:24:35.31 (53438763)|USER_DEBUG|[2]|DEBUG|输出Account:{LastName=er, FirstName=er, Id=0010T00000MT41uQAD}
17:24:35.31 (53702076)|USER_DEBUG|[4]|DEBUG|输出Account:{LastName=test, FirstName=er, Id=0010T00000MT41uQAD}
public class CreateUpdateMetadataUtils implements Metadata.DeployCallback {
public void handleResult(Metadata.DeployResult result, Metadata.DeployCallbackContext context) {
if (result.status == Metadata.DeployStatus.Succeeded) {
System.debug(' success : '+ result);
} else {
System.debug(' fail : '+ result);
}
}
public static void createUpdateMetadata(String fullName, String label, Map<String, Object> fieldWithValuesMap){
Metadata.CustomMetadata customMetadata = new Metadata.CustomMetadata();
customMetadata.fullName = fullName;
customMetadata.label = label;
for(String key : fieldWithValuesMap.keySet()){
Metadata.CustomMetadataValue customField = new Metadata.CustomMetadataValue();
customField.field = key;
customField.value = fieldWithValuesMap.get(key);
customMetadata.values.add(customField);
}
Metadata.DeployContainer mdContainer = new Metadata.DeployContainer();
mdContainer.addMetadata(customMetadata);
CreateUpdateMetadataUtils callback = new CreateUpdateMetadataUtils();
Id jobId = Metadata.Operations.enqueueDeployment(mdContainer, callback);
}
}
需要的system permission
<userPermissions>
<enabled>trueenabled>
<name>ApiEnabledname>
userPermissions>
<userPermissions>
<enabled>trueenabled>
<name>CustomizeApplicationname>
userPermissions>
<userPermissions>
<enabled>trueenabled>
<name>ManageCustomPermissionsname>
userPermissions>
<userPermissions>
<enabled>trueenabled>
<name>ManageTranslationname>
userPermissions>
<userPermissions>
<enabled>trueenabled>
<name>ModifyMetadataname>
userPermissions>
<userPermissions>
<enabled>trueenabled>
<name>ViewRolesname>
userPermissions>
<userPermissions>
<enabled>trueenabled>
<name>ViewSetupname>
userPermissions>
String.escapeSingleQuotes(str);
String name = 'aa\'dd';
String sql = 'SELECT Id FROM Account WHERE Name = \'' + String.escapeSingleQuotes(name) + '\'';
List<Account> acclist = Database.query(sql);
当name字段含特使符号时,如果直接查询,则会报错。
Description | Cumulative Cross-Namespace Limit |
---|---|
Total number of SOQL queries issued | 1,100 |
Total number of records retrieved by Database.getQueryLocator | 110,000 |
Total number of SOSL queries issued | 220 |
Total number of DML statements issued | 1,650 |
Total number of callouts (HTTP requests or web services calls) in a transaction | 1,100 |
Total number of sendEmail methods allowed | 110 |
Description | Synchronous Limit | Asynchronous Limit |
---|---|---|
Total number of SOQL queries issued1 | 100 | 200 |
Total number of records retrieved by SOQL queries | 50,000 | |
Total number of records retrieved byDatabase.getQueryLocator | 10,000 | |
Total number of SOSL queries issued | 20 | |
Total number of records retrieved by a single SOSL query | 2,000 | |
Total number of DML statements issued2 | 150 | |
Total number of records processed as a result of DML statements,Approval.process, ordatabase.emptyRecycleBin | 10,000 | |
Total stack depth for any Apex invocation that recursively fires triggers due toinsert,update, ordeletestatements3 | 16 | |
Total number of callouts (HTTP requests or web services calls) in a transaction | 100 | |
Maximum cumulative timeout for all callouts (HTTP requests or Web services calls) in a transaction | 120 seconds | |
Maximum number of methods with thefutureannotation allowed per Apex invocation | 50 | 0 in batch and future contexts; 1 in queueable context |
Maximum number of Apex jobs added to the queue withSystem.enqueueJob | 50 | 1 |
Total number ofsendEmailmethods allowed | 10 | |
Total heap size4 | 6 MB | 12 MB |
Maximum CPU time on the Salesforce servers5 | 10,000 milliseconds | 60,000 milliseconds |
Maximum execution time for each Apex transaction | 10 minutes | |
Maximum number of push notification method calls allowed per Apex transaction | 10 | |
Maximum number of push notifications that can be sent in each push notification method call | 2,000 | |
Maximum number ofEventBus.publishcalls for platform events configured to publish immediately | 150 | |
mber ofEventBus.publishcalls for platform events configured to publish immediately | 150 |
List View: we can’t sort by the records with the encrypted fields and not supported those operations like “contains”/“Starts with” in the filter
Sharing rule: we can’t use the encrypted fields in the criteria-based sharing rules.
Report: we can’t sort records in list views by fields that contain encrypted data.
Apex class/SOQL: don’t support below statements:
Case-sensitive and case-insensitive deterministic encryption schemes support compound fields, but only with individual column queries.
Such as: after encrypt field “Contact.name”, this is a combined field, which name = firstname + lastname.
And only below query support: select id from Contact where firstname = ‘xxx’ and lastname = ‘xxx’
a.字母:搜索结果只返回以每个单词以搜索词为开头的数据(每个单词的是指用空格或者其他类型字符隔开的字母)
比如:有以下Account
Account1: Last Name = New Account
Account2: Last Name = NewAccount
Account3: Last Name = New 123Account
Account4: Last Name = New 客户Account
在Last Name搜索框中搜索Account
返回结果:Account1,Account3,Account4
b.数字:搜索结果只返回以每串数字以搜索词为开头的数据(每串数字的是指用空格或者其他类型字符隔开的字母)
比如:有以下Account
Account1: Last Name = 123New Account; Email = [email protected]
Account2: Last Name = 456123NewAccount; Email = [email protected]
Account3: Last Name = New99@123Account; Email = [email protected]
Account4: Last Name = New客123户Account; Email = [email protected]
在Last Name搜索框中搜索123
返回结果:Account1,Account3,Account4
在Email中搜索框中搜索123
返回结果:Account1,Account3,Account4
c.中文:无限制,只要系统有匹配的都可以返回。
比如:有以下Account
Account1: Last Name = 新客户旧客户
Account2: Last Name = 今天天气不错
Account3: Last Name = new客户
在Last Name中搜索'客户'
返回结果:Account1,Account3
导致的影响:
##判断用户是否在某个custom permission中
Boolean hasCustomPermission = FeatureManagement.checkPermission('your_custom_permission_api_name');
https://developer.salesforce.com/docs/atlas.en-us.securityImplGuide.meta/securityImplGuide/custom_perms_overview.htm
/**
* @description Public method for updating data, determines if have permission before updating.
* @param objectName need update record object name
* @param updatelist update record list
**/
public static void checkObjectPermissionAndUpdateRecord(String objectName, List<sObject> updatelist){
SObjectType objectType = ((SObject)Type.forName('Schema', 'Account').newInstance()).getSObjectType();
if (updatelist != null && !updatelist.isEmpty() && objectType.getDescribe().isUpdateable()){
update updatelist;
}
}
在sql语句中加上 ALL ROWS
List<Account> acclist = [SELECT id FROM Account WHERE IsDeleted = true ALL ROWS];