Salesforce触发器解析求助:插入QMBDataLogging__c后无记录显示
QMBDataLogging__c插入记录后不显示的问题与触发器解析
问题描述
使用Data Loader向QMBDataLogging__c对象插入记录,系统提示成功但对象中未显示任何记录,接手离职同事编写的触发器代码,无法理解其逻辑,现解析如下:
trigger DataLoggingTrigger on QMBDataLogging__c (after insert) { Map<string,Schema.RecordTypeInfo> recordTypeInfo = Schema.SObjectType.QMB_Initial_Letter__c.getRecordTypeInfosByName(); List<QMBDataLogging__c> logList = (List<QMBDataLogging__c>)Trigger.new; List<Sobject> sobjList = (List<Sobject>)Type.forName('List<'+'QMB_Initial_Letter__c'+'>').newInstance(); Map<string, QMBLetteTypeToVfPage__c> QMBLetteTypeToVfPage = QMBLetteTypeToVfPage__c.getAll(); Map<String,QMBLetteTypeToVfPage__c> mapofLetterTypeRec = new Map<String,QMBLetteTypeToVfPage__c>(); set<Id>processdIds = new set<Id>(); for(string key : QMBLetteTypeToVfPage.keyset()) { if(!mapofLetterTypeRec.containsKey(key)) mapofLetterTypeRec.put(QMBLetteTypeToVfPage.get(Key).Letter_Type__c, QMBLetteTypeToVfPage.get(Key)); } for(QMBDataLogging__c log : logList) { Sobject logRecord = (sobject)log; Sobject QMBLetterRecord = new QMB_Initial_Letter__c(); if(mapofLetterTypeRec.containskey(log.Field1__c)) { string recordTypeId = recordTypeInfo.get(mapofLetterTypeRec.get(log.Field1__c).RecordType__c).isAvailable() ? recordTypeInfo.get(mapofLetterTypeRec.get(log.Field1__c).RecordType__c).getRecordTypeId() : recordTypeInfo.get('Master').getRecordTypeId(); string fieldApiNames = mapofLetterTypeRec.containskey(log.Field1__c) ? mapofLetterTypeRec.get(log.Field1__c).FieldAPINames__c : ''; //QMBLetterRecord.put('Letter_Type__c',log.Name); QMBLetterRecord.put('RecordTypeId',tgh); processdIds.add(log.Id); if(string.isNotBlank(fieldApiNames) && fieldApiNames.contains(',')) { Integer i = 1; for(string fieldApiName : fieldApiNames.split(',')) { string logFieldApiName = 'Field'+i+'__c'; fieldApiName = fieldApiName.trim(); system.debug('fieldApiName=='+fieldApiName); Schema.DisplayType fielddataType = getFieldType('QMB_Initial_Letter__c',fieldApiName); if(fielddataType == Schema.DisplayType.Date) { Date dateValue = Date.parse(string.valueof(logRecord.get(logFieldApiName))); QMBLetterRecord.put(fieldApiName,dateValue); } else if(fielddataType == Schema.DisplayType.DOUBLE) { string value = (string)logRecord.get(logFieldApiName); Double dec = Double.valueOf(value.replace(',','')); QMBLetterRecord.put(fieldApiName,dec); } else if(fielddataType == Schema.DisplayType.CURRENCY) { Decimal decimalValue = Decimal.valueOf((string)logRecord.get(logFieldApiName)); QMBLetterRecord.put(fieldApiName,decimalValue); } else if(fielddataType == Schema.DisplayType.INTEGER) { string value = (string)logRecord.get(logFieldApiName); Integer integerValue = Integer.valueOf(value.replace(',','')); QMBLetterRecord.put(fieldApiName,integerValue); } else if(fielddataType == Schema.DisplayType.DATETIME) { DateTime dateTimeValue = DateTime.valueOf(logRecord.get(logFieldApiName)); QMBLetterRecord.put(fieldApiName,dateTimeValue); } else { QMBLetterRecord.put(fieldApiName,logRecord.get(logFieldApiName)); } i++; } } } sobjList.add(QMBLetterRecord); } if(!sobjList.isEmpty()) { insert sobjList; if(!processdIds.isEmpty()) DeleteDoAsLoggingRecords.deleteTheProcessRecords(processdIds); } Public static Schema.DisplayType getFieldType(string objectName,string fieldName) { SObjectType r = ((SObject)(Type.forName('Schema.'+objectName).newInstance())).getSObjectType(); DescribeSObjectResult d = r.getDescribe(); return(d.fields.getMap().get(fieldName).getDescribe().getType()); } }
触发器核心逻辑
这是QMBDataLogging__c对象的after insert触发器,核心作用是:将插入的日志记录转换为QMB_Initial_Letter__c对象的记录,随后删除已处理的日志记录——这就是你插入后看不到QMBDataLogging__c记录的直接原因。
逐段解析代码
1. 初始化数据结构
- 获取
QMB_Initial_Letter__c对象所有记录类型的信息,存入recordTypeInfo映射,用于后续设置信件记录的记录类型 - 把触发器触发时的新日志记录集合存入
logList - 动态创建
QMB_Initial_Letter__c类型的列表sobjList,用于批量插入转换后的信件记录 - 读取自定义设置
QMBLetteTypeToVfPage__c的所有数据,将其按Letter_Type__c字段重新整理到mapofLetterTypeRec映射,方便快速按信件类型查找配置 - 初始化
processdIds集合,用于记录需要删除的已处理日志记录ID
2. 遍历处理每条日志记录
对每条插入的QMBDataLogging__c记录:
- 创建一条空的
QMB_Initial_Letter__c记录 - 检查当前日志的
Field1__c是否存在对应的信件类型配置(即mapofLetterTypeRec中是否有匹配的键):- 若存在,先确定信件记录的记录类型ID:如果配置指定的记录类型可用则使用该ID,否则使用Master记录类型ID
- 从配置中取出需要映射的目标字段API名称列表
fieldApiNames - 将当前日志ID加入
processdIds,标记为待删除 - 如果字段列表非空且为逗号分隔格式,循环处理每个字段:
- 日志记录的字段按
Field1__c、Field2__c...的顺序与配置中的字段一一对应,用计数器i匹配 - 调用
getFieldType方法获取目标字段的数据类型 - 根据数据类型做类型转换(比如日期解析、数字格式处理等),将日志字段的值赋值给信件记录对应的字段
- 日志记录的字段按
- 将处理后的信件记录加入
sobjList
3. 批量操作
- 若
sobjList不为空,批量插入所有QMB_Initial_Letter__c记录 - 若
processdIds不为空,调用DeleteDoAsLoggingRecords.deleteTheProcessRecords方法删除已处理的QMBDataLogging__c记录——这就是日志记录插入后消失的关键操作
4. 辅助方法getFieldType
该静态方法用于根据对象名和字段名,动态获取字段的数据类型,为后续的类型转换提供依据。
代码中的明显问题
- 未定义变量错误:
QMBLetterRecord.put('RecordTypeId',tgh);中的tgh是未定义的变量,正确应该使用前面获取的recordTypeId,这会导致插入QMB_Initial_Letter__c记录时报错,可能影响后续删除逻辑 - 自定义设置覆盖问题:遍历自定义设置时,若多条记录的
Letter_Type__c字段值相同,后面的记录会覆盖前面的,最终只保留最后一条配置 - 字段映射依赖顺序:日志字段
Field1__c、Field2__c的顺序必须与配置中的字段顺序严格对应,一旦配置顺序错误,数据会被填入错误的目标字段
内容的提问来源于stack exchange,提问作者sfdc developer
相关产品推荐
相关产品推荐

