經(jīng)常有人問到excel中去除重復(fù)值的問題,這個(gè)問題本來也一直有很多人討論,現(xiàn)將做法匯總出來共大家參考。 什么是重復(fù)值 顧名思義,重復(fù)值是指一組數(shù)據(jù)中有重復(fù)記錄,去除這些重復(fù)的記錄就叫去除重復(fù)值,具體有兩種情況:源數(shù)據(jù)如圖
去重后
結(jié)果一:所有在源數(shù)據(jù)中出現(xiàn)過二次及以上的記錄均已經(jīng)去除,結(jié)果二指,結(jié)果數(shù)據(jù)表示保留的數(shù)據(jù)均在源數(shù)據(jù)中有,但在結(jié)果中只出現(xiàn)一次 結(jié)果二就是我們常說的去重 去重方法常見的去重方法很多,本文列舉自帶工具去重、高級篩選去重、函數(shù)去重、VBA去重、透視表去重和SQL去重共六種方法 1. 利用excel自帶去重工具去重 自excel2007以后,excel就增加了去重功能,具體看下圖 操作步驟:選中需要去重的原始數(shù)據(jù)/點(diǎn)擊數(shù)據(jù)選項(xiàng)卡/點(diǎn)擊刪除重復(fù)項(xiàng)/確定
2. 所有excel版本均可實(shí)現(xiàn)的辦法:高級篩選 點(diǎn)擊數(shù)據(jù)選項(xiàng)卡/點(diǎn)擊排序和篩選組的高級按鈕,彈出對話框 按上圖設(shè)置后,確定即可。A1:A9系源數(shù)據(jù),條件區(qū)域E1是一個(gè)空白單元格,關(guān)鍵點(diǎn)在于要勾選“選擇不重復(fù)記錄” 注意Excel97、XP及2003的高級篩選在數(shù)據(jù)菜單 以上兩種辦法是最常見的辦法,高級篩選還可以跨表操作,但實(shí)際工作中,去重不但要跨表,還要能更新列表,比如源數(shù)據(jù)是不斷更新的,去重結(jié)果也是需要不斷更新的,所以前文的方法并不能帶來多少實(shí)際的用途,自然,更先進(jìn)的辦法也就來了
3.函數(shù)去重 ? 太多的人喜歡用函數(shù)處理數(shù)據(jù),所以去重也少不了他的身影,請看截圖 數(shù)據(jù)源在H1:H11區(qū)域,函數(shù)運(yùn)算結(jié)果在I列,在I1單元格輸入的函數(shù)公式:=INDEX(H:H,SMALL(IF(MATCH($H$1:$H$11,$H$1:$H$11,)=ROW($1:$11),ROW($1:$11),4^8),ROW(A1)))&""這是流傳最廣的函數(shù)寫法之一 提示:數(shù)組公式要三鍵結(jié)束(ctrl+shift+enter),然后下拉填充至出現(xiàn)空格 公式翻譯:I1單元格結(jié)果為index引用H列中的數(shù)據(jù),數(shù)據(jù)排序號是數(shù)組按小排序的最小值1,該數(shù)組構(gòu)成為 如果在H1:H11區(qū)域中來精確查找H1:H11值的序號等于行號時(shí)取行號,否則取當(dāng)前行號和65536(4^8或者2^16,EXCEL最大行號值2003及以前版本,2007以后版本為1048576即2的10次方2^20) 上面太拗口,看公式解釋: a. MATCH($H$1:$H$11,$H$1:$H$11,)是match的簡寫,標(biāo)準(zhǔn)寫法為MATCH($H$1:$H$11,$H$1:$H$11,0),意思是在H1:H11區(qū)域中查找H1:H11的值,并且精確匹配,其結(jié)果是{1;2;3;4;2;6;3;8;8;2;2},可以解釋為:H1:H11的出現(xiàn)順序,從中可以看到第五個(gè)數(shù)據(jù)等于2,重復(fù)了,其余類似, b. MATCH($H$1:$H$11,$H$1:$H$11,)=ROW($1:$11)表示將{1;2;3;4;2;6;3;8;8;2;2}與H1:H11的行號比較(ROW是計(jì)算行號函數(shù)),得到的結(jié)果為{TRUE;TRUE;TRUE;TRUE;FALSE;TRUE;FALSE;TRUE;FALSE;FALSE;FALSE} c. 加上IF函數(shù)后,取值為{1;2;3;4;65536;6;65536;8;65536;65536;65536}, d. 再加上small函數(shù),數(shù)組變成{1;2;3;4;6;8;65536; 65536;65536;65536;65536} e. 最好,index按順序取值并連上””[&""]|排除錯(cuò)誤或零值,得到結(jié)果 f. 當(dāng)源數(shù)據(jù)區(qū)域發(fā)生變化,對應(yīng)修改函數(shù)的取值區(qū)域后,三鍵結(jié)尾,下拉公式
4.VBA代碼去重 ? 用excel的VBA編程也可解決去重問題,最常使用的方法有以下 a. ActiveSheet.Range("$H$1:$H$11").RemoveDuplicatesColumns:=1, Header:=xlNo這是VBA的RemoveDuplicates刪除重復(fù)記錄方法 b. Range("H1:H11").AdvancedFilterAction:=xlFilterCopy, CopyToRange:=Range("X1"), Unique:=True 這是利用的VBA篩選去重 c. 用VBA字典看示例 以下三個(gè)來源于論壇,非原創(chuàng) 示例1(可以添加三列記錄到字典的) Sub Test() Dim i&, DicA As Object, DicB As Object, DicC As Object Dim Arr1, Arr2, Arr3 Set DicA = CreateObject("scripting.dictionary") Set DicB = CreateObject("scripting.dictionary") Set DicC = CreateObject("scripting.dictionary") Arr1 = Range("A1:A60000") Arr2 = Range("B1:B60000") Arr3 = Range("C1:C60000") For i = LBound(Arr1) To UBound(Arr1) '循環(huán)數(shù)組Arr1 DicA(Arr1(i, 1)) ="" '添加不重復(fù)值到字典DicA Next i For i = LBound(Arr2) To UBound(Arr2) '循環(huán)數(shù)組Arr2 If DicA.exists(Arr2(i, 1))Then '如果Arr2中的值存在于字典DicA中,則往字典DicB添加重復(fù)的值 DicB(Arr2(i, 1)) ="" End If Next i For i = LBound(Arr3) To UBound(Arr3) '循環(huán)數(shù)組Arr3 If DicB.exists(Arr3(i, 1))Then '如果Arr3中的值存在于字典DicB中,則往字典DicC中添加重復(fù)的值 DicC(Arr3(i, 1)) ="" End If Next i Range("D1").Resize(DicC.Count, 1) =Application.Transpose(DicC.keys) '把DicC的keys值賦予給D列 Set DicA = Nothing Set DicB = Nothing Set DicC = Nothing End Sub 類似的,一個(gè)入庫單匯總的小程序 示例2 SubDataWrtin() Dim Arr, k%, str$ Dim Ary, i%, icl% Dim Dic As Object Dim Sh As Worksheet
Set Sh = Sheets("入庫單數(shù)據(jù)庫") Set Dic =CreateObject("Scripting.Dictionary") Arr =Sh.Range("E5", Sh.[E65536].End(3)(1, 3))” Ary = Arr i = 0 For k = 1 To UBound(Arr) str =Join(Application.Index(Arr, k), " ") If Not Dic.exists(str)Then Dic(str) ="" i = i + 1 For icl = 1 To 3 Ary(i, icl) =Arr(k, icl) Next End If Next Dic.RemoveAll
Sheets("目錄").[A5].Resize(i,3) = Ary End Sub E5請做相應(yīng)修改 簡單適用的B列元數(shù)據(jù),E列去重結(jié)果 示例3 Sub 篩選不重復(fù)數(shù)據(jù)() Set dic = CreateObject("Scripting.Dictionary") '字典 For Each r In Sheets("Sheet1").Range("b2:b"& Sheets("Sheet1").[b65536].End(xlUp).Row) '數(shù)組 On Error Resume Next '忽略錯(cuò)誤繼續(xù)執(zhí)行VBA代碼,避免出現(xiàn)錯(cuò)誤消息 If Not r.Value ="" Then dic.Add r.Value, "" '如果不是空,給字典添加內(nèi)容 Next Sheets("Sheet2").Range("e2").Resize(dic.Count, 1) =Application.WorksheetFunction.Transpose(dic.keys) '從e2單元開始向下放 On Error GoTo 0 '恢復(fù)正常的錯(cuò)誤提示 End Sub 用VBA也比較麻煩,而且要求有一定的編程基礎(chǔ),所以接下來來跟容易的
5.數(shù)據(jù)透視 點(diǎn)插入選項(xiàng)卡/數(shù)據(jù)透視表,按圖設(shè)置? 把姓名拖入行標(biāo)簽中,右鍵透視表/透視表選項(xiàng),取消列總計(jì)復(fù)選框,確定 得到結(jié)果
當(dāng)據(jù)源發(fā)生變化時(shí),右鍵透視表,刷新即可更新列表 這是最簡單的能更新的辦法
6.SQL聯(lián)合查詢?nèi)ブ?/strong> ? 利用SQL語句的去重功能實(shí)現(xiàn),也能更新數(shù)據(jù) 點(diǎn)數(shù)據(jù)選項(xiàng)卡/現(xiàn)有連接,出現(xiàn)如圖 點(diǎn)擊瀏覽更多按鈕,按資源管理器方式找到本excel文件并點(diǎn)擊打開 選中sheet1,確定 點(diǎn)擊屬性按鈕,打開屬性對話框 點(diǎn)擊定義選項(xiàng)卡 刪除命令文本里面的內(nèi)容,寫入select distinct 姓名from [sheet2$]語句 注意:除中文外,空格及標(biāo)點(diǎn)均為英文小寫狀態(tài)輸入,]后沒有內(nèi)容,點(diǎn)擊確定 選擇放置結(jié)果的起始單元格,確定 完成 需要更新時(shí),右擊結(jié)果,刷新即可
前述六種辦法,一般情況下推薦使用第一二辦法,需要經(jīng)常更新時(shí),建議采用第五第六種辦法,使用數(shù)組函數(shù)在數(shù)據(jù)太多時(shí)電腦運(yùn)行緩慢,不推薦,至于VBA,呵呵 ,能用VBA編程的高手不在乎這種小問題的 |
|