新系统上线后,需要导入历史数据,但是旧数据格式,数据缺失,数据错误,奇异值,属性归类与新系统有很大的gap。因此我们需要建立一套数据动态清洗规则给Salesforce系统,通过这些规则自动清洗导入数据,清洗规则可以让function自己配置。而不需要IT负责

下面将详细举一个例子如何在salesforce中做数据处理。数据清洗需要分成5个步骤

1,建立2个关联数据的Object的和 一个数据清洗后台设置的Object的
2,数据导入页面csv
3,定义每个字段的范围、属性,如果是错误的则自动重新分配,或者修改成临近值
4,数据清洗合并。
5,导出错误数据到Excel
 
第一步,新建立两个关联的Recruit 和 Recruit Department, 并且建立一个清洗规则的Object,当导入数据后我们可以读取设置的清洗规则,并对导入的数据进行清洗
第二步,对于清洗规则,我们只能有一条规则被激活,因此我们在插入新规则和更改旧规则的时候,我们需要添加一个tirgger针对Data_Washing_Setting,保证规则的唯一性。

  1. trigger IsActiveChecking on Data_Washing_Setting__c (before insert,before update) {
  2.  
  3. List<Data_Washing_Setting__c> ListOldData =[select Id from Data_Washing_Setting__c
  4. where Active_this_Rule__c = true];
  5. List<Data_Washing_Setting__c> ListNewData =trigger.new;
  6.  
  7. //system.debug('ListNewData:'+ListNewData.size());
  8. integer itemNum = 0;
  9. if(trigger.isInsert)
  10. {
  11. if(trigger.isBefore)
  12. {
  13. for(Data_Washing_Setting__c dws : trigger.new)
  14. {
  15. if(dws.Active_this_Rule__c)
  16. {
  17. itemNum++;
  18. }
  19. }
  20. itemNum +=ListOldData.size();
  21.  
  22. if(itemNum>1)
  23. {
  24. for(Data_Washing_Setting__c dws : trigger.new){
  25. dws.adderror('only one record can be actived! pls check your history data and try again.');
  26. }
  27. }
  28. }
  29. }
  30. else if(trigger.isUpdate)
  31. {
  32. if(trigger.isBefore)
  33. {
  34. // 去掉更新的数据
  35. for(Data_Washing_Setting__c dws : trigger.new)
  36. {
  37. for(integer i=0;i<ListOldData.size();i++){
  38. if(dws.Id== ListOldData[i].Id)
  39. {
  40. ListOldData.remove(i);
  41. }
  42. }
  43. if(dws.Active_this_Rule__c)
  44. {
  45. itemNum++;
  46. }
  47. }
  48. itemNum +=ListOldData.size();
  49. if(itemNum>1)
  50. {
  51. for(Data_Washing_Setting__c dws : trigger.new){
  52. dws.adderror('only one record can be actived! pls check your history data and try again.');
  53. }
  54. }
  55.  
  56. }
  57. }
  58. }

第三步,我们需要建立导入页面,并添加相应的验证按钮

VF的代码

  1. <apex:page controller="BatchInsertByCsvController">
  2. <apex:form >
  3. <apex:sectionHeader title="Upload Recruit Data"/>
  4. <apex:pageMessages />
  5. <apex:pageblock >
  6. <center>
  7. <apex:inputFile value="{!contentFile}" fileName="{!fileName}" />
  8. <apex:commandButton action="{!LoadData}" value="Batch Insert"/>
  9. <apex:commandButton action="{!LoadBlankList}" value="Filter Blank Data"/>
  10. <apex:commandButton action="{!ExportBlankToCSV}" value="Export CSV"/>
  11.  
  12. </center>
  13. </apex:pageblock>
  14. <apex:pageBlock title="Import Data">
  15. <apex:pageblocktable value="{!RecruitList}" var="ReList">
  16. <apex:column value="{!ReList.Name}" />
  17. <apex:column value="{!ReList.Position_Name__c}" />
  18. <apex:column value="{!ReList.Recruit_Department__c}" />
  19. <apex:column value="{!ReList.Recruit_Type__c}" />
  20. <apex:column value="{!ReList.Recruit_Number__c}" />
  21. </apex:pageblocktable>
  22. </apex:pageBlock>
  23. <apex:pageBlock title="Blank Data">
  24. <apex:pageblocktable value="{!BlankList}" var="BList">
  25. <apex:column value="{!BList.Name}" />
  26. <apex:column value="{!BList.Position_Name__c}" />
  27. <apex:column value="{!BList.Recruit_Department__c}" />
  28. <apex:column value="{!BList.Recruit_Type__c}" />
  29. <apex:column value="{!BList.Recruit_Number__c}" />
  30. </apex:pageblocktable>
  31. </apex:pageBlock>
  32. </apex:form>
  33. </apex:page>

后台APEX 导入代码

  1. public class BatchInsertByCsvController {
  2.  
  3. public string fileName{get;set;}
  4. //Blob:二进制对象类型。通过inputFile选中后的文件在后台获取的时候是一个Blob类型,
  5. public Blob contentFile{get;set;}
  6. public String[] filelines = new String[]{};
  7. public List<Recruit__c> RecruitList{get;set;}
  8. public List<Recruit__c> BlankList{get;set;}
  9. public List<Recruit__c> invaildList{get;set;}
  10. //初始化
  11. public PageReference LoadData()
  12. {
  13. try{
  14. filename = bitToString(contentFile,'ISO-8859-1');
  15. filelines = fileName.split('\n');
  16. // ApexPages.Message msgs = new ApexPages.Message(ApexPages.Severity.INFO, 'import account:'+filelines.size());
  17. // ApexPages.addMessage(msgs);
  18. RecruitList = new List<Recruit__c>();
  19. string[] inputvalues;
  20. string SwpNumber;
  21.  
  22. for(Integer i=1;i<filelines.size();i++)
  23. {
  24. inputvalues = new string[]{};
  25. inputvalues = filelines[i].split(',');
  26. Recruit__c recruits = new Recruit__c();
  27. recruits.Name = inputvalues[0];
  28. recruits.Position_Name__c = inputvalues[1];
  29. recruits.Recruit_Department__c = [SELECT Id
  30. FROM Recruit_Department__c
  31. WHERE Name =:inputvalues[2] LIMIT 1].Id;
  32. recruits.Recruit_Type__c = inputvalues[3];
  33. SwpNumber = inputvalues[4];
  34. recruits.Recruit_Number__c = Decimal.valueOf(SwpNumber.trim());
  35. RecruitList.add(recruits);
  36. }
  37. }
  38. catch(exception e){
  39. ApexPages.Message errormsg = new ApexPages.Message(ApexPages.Severity.ERROR,'An error has occured reading the CSV file: '+e.getMessage());
  40. ApexPages.addMessage(errormsg);
  41. }
  42. try{
  43. // insert RecruitList;
  44. // ApexPages.Message successMsg = new ApexPages.Message(ApexPages.severity.INFO,'import success');
  45. // ApexPages.addMessage(successMsg);
  46. }
  47. catch(Exception e)
  48. {
  49. //ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'An error has occured inserting the records'+e.getMessage());
  50. //ApexPages.addMessage(errormsg);
  51. }
  52. return null;
  53. }
  54. //blob是二进制存储的,String是16进制存储的,所以使用此种方式加上编码解码等操作肯定会更加适应,包括中文
  55. private String bitToString(Blob input, String inCharset){
  56. //转换成16进制
  57. String hex = EncodingUtil.convertToHex(input);
  58. //一个String类型两个字节 32位(bit),则一个String长度应该为两个16进制的长度,所以此处向右平移一个单位,即除以2
  59. //向右平移一个单位在正数情况下等同于除以2,负数情况下不等
  60. //eg 9 00001001 >>1 00000100 结果为4
  61. final Integer bytesCount = hex.length() >> 1;
  62. //声明String数组,长度为16进制转换成字符串的长度
  63. String[] bytes = new String[bytesCount];
  64. for(Integer i = 0; i < bytesCount; ++i) {
  65. //将相邻两位的16进制字符串放在一个String中
  66. bytes[i] = hex.mid(i << 1, 2);
  67. }
  68. //解码成指定charset的字符串
  69. return EncodingUtil.urlDecode('%' + String.join(bytes, '%'), inCharset);
  70. }
  71. //筛选空值
  72. public PageReference LoadBlankList()
  73. {
  74. try
  75. {
  76. BlankList=new list<Recruit__c>();
  77. DataWashingSetting dws=new DataWashingSetting();
  78. string[] flines = dws.AddQuestionsData(filelines);
  79. string[] inputvalues;
  80. string SwpNumber;
  81.  
  82. for(Integer i=0;i<flines.size();i++)
  83. {
  84. inputvalues = new string[]{};
  85. inputvalues = flines[i].split(',');
  86. Recruit__c recruits = new Recruit__c();
  87. recruits.Name = inputvalues[0];
  88. recruits.Position_Name__c = inputvalues[1];
  89. recruits.Recruit_Department__c = [SELECT Id
  90. FROM Recruit_Department__c
  91. WHERE Name =:inputvalues[2] LIMIT 1].Id;
  92. recruits.Recruit_Type__c = inputvalues[3];
  93. SwpNumber = inputvalues[4];
  94. recruits.Recruit_Number__c = Decimal.valueOf(SwpNumber.trim());
  95. BlankList.add(recruits);
  96. }
  97. ApexPages.Message msgs = new ApexPages.Message(ApexPages.Severity.INFO, 'blank num:'+BlankList.size());
  98. ApexPages.addMessage(msgs);
  99. }
  100. catch(Exception e)
  101. {
  102. ApexPages.Message errormsg = new ApexPages.Message(ApexPages.Severity.ERROR,'An error has occured reading the CSV file: '+e.getMessage());
  103. ApexPages.addMessage(errormsg);
  104. }
  105. return null;
  106. }
  107. public PageReference ExportBlankToCSV()
  108. {
  109. return new PageReference('/apex/ExportCSV');
  110. }
  111. }

后台调用的验证清洗代码,可以根据需要任意添加

  1. public class DataWashingSetting {
  2.  
  3. //消除重复数据
  4. public List<Recruit__c> DelDuplicateData(List<Recruit__c> OriginalList)
  5. {
  6. set<Recruit__c> myset= new set<Recruit__c>();
  7. List<Recruit__c> result = new List<Recruit__c>();
  8.  
  9. myset.addAll(OriginalList);
  10. result.addAll(myset);
  11.  
  12. return result;
  13. }
  14. //筛选为空数据
  15. public string[] AddQuestionsData(string[] filelines)
  16. {
  17. string[] result =new string[]{};
  18. string[] inputvalues;
  19. for(Integer i=1;i<filelines.size();i++)
  20. {
  21. inputvalues = new string[]{};
  22. inputvalues = filelines[i].split(',');
  23. if(inputvalues[0] == ''||inputvalues[1] == '' ||inputvalues[2] == ''
  24. ||inputvalues[3] == '' ||inputvalues[4] == '')
  25. {
  26. result.add(filelines[i]);
  27. }
  28. }
  29. return result;
  30. }
  31. //检测各个字段的合理性
  32. public string[] CheckFiled(string[] filelines)
  33. {
  34. //读取规则
  35. Data_Washing_Setting__c dws = [select Position_Name_Rule__c,
  36. Recruit_End_Number__c,Recruit_Department_Rule__c,Recruit_Start_Number__c from Data_Washing_Setting__c where Active_this_Rule__c = true];
  37. string PositionNameRule = dws.Position_Name_Rule__c; //部门规则是否允许重复
  38. decimal startNumber= dws.Recruit_Start_Number__c; //招聘人数底线
  39. decimal endNumber= dws.Recruit_End_Number__c; //招聘人数上线
  40. string department = dws.Recruit_Department_Rule__c;//部门限制
  41.  
  42. string[] result =new string[]{};
  43. string[] inputvalues;
  44. for(Integer i=1;i<filelines.size();i++)
  45. {
  46. inputvalues = new string[]{};
  47. inputvalues = filelines[i].split(',');
  48. //填写验证代码
  49. }
  50. return result; //返回不合格代码
  51. }
  52. }

出现问题数据直接导出问题数据到Excel,手动处理后再导入。

  1. <apex:page controller="BatchInsertByCsvController" cache="true" contentType="application/x-excel# BlankList.xls" showHeader="false">
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
  4. </head>
  5. <apex:pageBlock >
  6. <apex:pageblocktable value="{!BlankList}" var="BList">
  7. <apex:column value="{!BList.Name}" />
  8. <apex:column value="{!BList.Position_Name__c}" />
  9. <apex:column value="{!BList.Recruit_Department__c}" />
  10. <apex:column value="{!BList.Recruit_Type__c}" />
  11. <apex:column value="{!BList.Recruit_Number__c}" />
  12. </apex:pageblocktable>
  13. </apex:pageBlock>
  14. </apex:page>

下面就是最终效果:

1,导入数据,自动筛选有缺失值的数据,并支持Excel导出

2,后台清洗的规则设置。

 

Salesforce 数据清洗的更多相关文章

  1. Salesforce开发者学习笔记之一:基本知识

    本文介绍了Salesforce开发平台的基本知识, 包括如下内容: Salesforce平台介绍 Salesforce基本术语 定制和扩展Salesforce平台 创建一个简单的应用程序 Salesf ...

  2. salesforce 零基础学习(六十一)apex:component简单使用以及图片轮转播放的实现

    有的时候,我们项目有可能有类似需求:做一个简单的图像轮转播放功能,不同的VF页面调用可以显示不同的图片以及不同的图片描述.这种情况,如果在每个页面单独处理相关的图像轮转播放则显得代码特别冗余,此种情况 ...

  3. salesforce 零基础学习(五十五)java通过SOAP方式定时访问某个文件然后插入到sObject中

    项目源码:https://github.com/zhangyueqidlmu/SOAP-Access-SFDC.git 项目背景:salesforce端相关数据需要其他系统提供,其他系统可以提供相关数 ...

  4. salesforce 零基础学习(五十四)常见异常友好消息提示

    异常或者error code汇总:https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_calls_con ...

  5. salesforce 零基础学习(五十三)多个文件生成一个zip文件(使用git上封装的代码)

    此篇参考git代码:https://github.com/pdalcol/Zippex 学习salesforce可以访问一个朋友的网站:https://www.xgeek.net 首先感谢git上提供 ...

  6. Hawk 4. 数据清洗

    数据清洗模块,包括几十个子模块, 这些子模块包含四类:生成, 转换, 过滤和执行. 数据清洗可以通过组合多个不同的子模块,生成多样的功能,通过拖拽构造出一个工作流,它能够产生一个有限或无限的文档序列. ...

  7. Salesforce的sharing Rule 不支持Lookup型字段解决方案

    Salesforce 中 sharing rule 并不支持Look up 字段 和 formula 字段.但在实际项目中,有时会需要在sharing rule中直接取Look up型字段的值,解决方 ...

  8. 微软要如何击败Salesforce?Office365、Azure、Dynamics365 全面布局AI | 双语

    微软在上月宣布组建自己的 AI 研究小组.该小组汇集了超过 5000 名计算机科学家和工程师,加上微软内部研究部门,将共同挖掘 AI 技术. 与此同时,亚马逊,Facebook,Google,IBM ...

  9. SalesForce 记录级别安全性

    对象级安全性 简档 对象级安全性提供了控制 Salesforce.com 中数据的最简单方式.使用对象级安全性 您可以防止用户查看.创 建.编辑或删除特殊类型对象的任何实例 如潜在客户或业务机会.对象 ...

随机推荐

  1. 利用IIS管理器模拟CDN

    CDN(Content Delivery Network,内容分发网络).其含义,在百度百科上是这么写的:CDN 是构建在数据网络上的一种分布式的内容分发网.CDN 的作用是采用流媒体服务器集群技术, ...

  2. OpenGL法向量变换

    OpenGL光照开启时,法向量用于决定特定顶点或面上接受到光照的多少.光照处理过程作用于观察坐标空间,因此,模型对象坐标系的法向量也需要使用GL_MODELVIEW矩阵变换到观察坐标系. 然而,法向量 ...

  3. .net frameworkAPI文档下载地址

    http://www.msdn.hk/html/2014/5.html VS2013 ILdasm 反编译工具安装在下面地址里了 C:\Program Files (x86)\Microsoft SD ...

  4. Python 获得对象内存占用内存大小 sys.getsizeof

    from sys import getsizeof class A(object): pass class B: pass for x in (None, 1, 1L, 1.2, 'c', [], ( ...

  5. 可以链接不同源的资源的html元素(能实现跨域)

    可以链接不同源的资源的html元素(能实现跨域): img.script.css.video.audio.object.embed.applet.@font-face.frame.iframe等. ( ...

  6. js post提交

    /* js跳转页面 url跳转地址,params参数列表 */ function Posturl(url,params){ //创建form表单 var temp_form=document.crea ...

  7. SQL总结系列

    SQL总结系列 总结SQL基本知识.用法,并结合多年的应用对SQL有关的相关知识进行总结.希望这些分享能给大家带来一些帮助,如有不足或错误,请批评指正. 主要内容 1)编辑相关,包括:数据库的创建与删 ...

  8. 【转】error while loading shared libraries: libevent-2.0.so.5: cannot open shared object file: No such file or directory

    错误信息: /usr/local/memcacheq/bin/memcacheq: error while loading shared libraries: libevent-2.0.so.5: c ...

  9. 【MySQL】排序原理与案例分析

    前言 排序是数据库中的一个基本功能,MySQL也不例外.用户通过Order by语句即能达到将指定的结果集排序的目的,其实不仅仅是Order by语句,Group by语句,Distinct语句都会隐 ...

  10. 通过宏判断VS编译版本以及系统平台

    MSC_VER 定义编译器的版本.下面是一些编译器版本的_MSC_VER值(参见扩展阅读中的参考文献2的链接) MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio ...