Board logo

標題: [發問] 比對資料,不相同的資料顯示於右側 [打印本頁]

作者: jackson7015    時間: 2018-10-9 16:08     標題: 比對資料,不相同的資料顯示於右側

想請問站上的前輩們
我有兩個資料(手動放置同頁面了)需要比對3個資料
分別是[座標,點數,地址]
如果其中有一種資料不同則會顯示於右側
而兩個資料不重複資料則是各放在各邊的右側
有點類似Excel的移除重複功能,但是不移除,而是放置在右側

請問有辦法用公式做到嗎 ?
作者: zheng211016    時間: 2018-10-10 20:55

你可以試試看陣列公式 但還是建議你提供檔案上來這樣要幫你的人也方便多了
作者: jackson7015    時間: 2018-10-15 16:12

回復 2# zheng211016

抱歉
這幾天重感冒沒時間看回覆
沒注意到忘記上傳做好的檔案了

在麻煩站上的前輩幫忙看看
謝謝~

[attach]29536[/attach]
作者: jackson7015    時間: 2018-10-16 15:48

自己做移除重複項目的方式的時候
發現只能留下 [座標,點數,地址]三個部份才能做移除重複的指令
這樣會有資料不完整的情形
不曉得能否使用公式達到類似的目的...

再請站上大大看看~
作者: faye59    時間: 2018-10-16 19:15

回復 4# jackson7015


    有結果圖嗎?
重覆項目直接往右貼嗎?
沒重覆的空白?
是這樣嗎?
作者: jackson7015    時間: 2018-10-17 16:11

回復 5# faye59
感謝 faye59 大大的回覆

相反才對;不重複的部分貼到右邊
但是會往上遞補空白位
而且上下兩個對照部分的不重複部分,各自貼在上下部右側

因為數量有點龐大,所以無法單一比對
在麻煩大大們看看
謝謝~
作者: faye59    時間: 2018-10-19 21:12

回復 6# jackson7015


相反才對;不重複的部分貼到右邊
(不重覆貼上第一筆?最後一筆?)
但是會往上遞補空白位
而且上下兩個對照部分的不重複部分,各自貼在上下部右側
(這段我看不太懂意思,上下部右側是哪裡?)

因為數量有點龐大,所以無法單一比對
在麻煩大大們看看
謝謝~

作者: zheng211016    時間: 2018-10-20 21:51

試試看吧 我也不是很清楚你要的結果
但是我是依照你說的比對 [座標,點數,地址]
把不重複的資料撈在右邊
使用方法 基本上就是把灰底的函數選取起來往下填滿就可以了(資料量多少就遞增)
只是我建議你 可以利用vba去撰寫 自動帶入函數的部分

[attach]29567[/attach]
作者: jackson7015    時間: 2018-10-21 10:11

本帖最後由 jackson7015 於 2018-10-21 10:19 編輯

回復 7# faye59
感謝 faye59 大大的回覆

而且上下兩個對照部分的不重複部分,各自貼在上下部右側
這是在第2676列開始有下半部比對用資料
上傳後好像分割畫面會消失?

回復 7# zheng211016
感謝 zheng211016 大大的幫忙

資料的分析好像有錯誤
篩選的方式類似以下檔案的工作表1
再請大大看看是否能修改

感謝各位大大的協助
目前只能手動刪除再作判定
但是還有近百頁的分頁要判讀
所以須要簡化步驟
再請看看能否編寫類似的判定

[attach]29569[/attach]
作者: zheng211016    時間: 2018-10-21 12:25

我想先問清楚
妳分割上下部分的用意是為了方便檢閱嗎?
且上下部分的資料都同一份?

還是是同一份資料
只是上半部是1~2675
下半部是2676~最後
然後要上下比對
上跟下重複的資料丟在右側(重複定義:2個相同以上只留一個資料在右側)
那不重複的資料呢?需要丟到右側嗎?(不重複的資料:只有一筆獨一無二)
作者: jackson7015    時間: 2018-10-21 12:54

回復 10# zheng211016
感謝zheng211016大大的協助

妳分割上下部分的用意是為了方便檢閱嗎?
是的,沒錯


且上下部分的資料都同一份?
資料會有些微不同,標題和欄數是相同的
因為下半部是從其他頁面複製過去比對的
所以要把不重複的都抓取出來
而兩個不重複的部分也要分開
所以分成上下部來檢視我覺得是最佳的方式

上跟下重複的資料丟在右側(重複定義:2個相同以上只留一個資料在右側)
重複的定義是完全不取出來
只留下不相同的資料比
就和資料移除重複的效果一樣
只是參考數據都要留著在左方,右側則是不重複的部分

那不重複的資料呢?需要丟到右側嗎?(不重複的資料:只有一筆獨一無二)
是的,不重複的部分都丟到右側
且,分為上下半部的不重複部分(檢閱用)
作者: zheng211016    時間: 2018-10-21 14:22

回復 11# jackson7015


你還是提供一個小小的範例好了
不用太多資料只要能夠詳細的顯示你要的結果就好
作者: jackson7015    時間: 2018-10-21 18:00

回復 12# zheng211016
呈現的的結果大概就是下面的檔案那樣
但是我是將資料先複製到工作頁面1
然後刪除不需要比對的部分
再用刪除重複的方式得出結果
再把資料回傳

不曉得表達的方式,能不能了解

    [attach]29574[/attach]
作者: zheng211016    時間: 2018-10-21 20:57

回復 13# jackson7015

我稍微懂一點你要的東西
只是還不是很清楚
但是大致上是不是就是
上半部資料 : 5~2676
下半部資料 : 2677~5562

上半部資料 跟 下半部資料 對照

上半部右側資料 :  與 左側下半部 不重複的資料
下半部右側資料 :  與 左側上半部 不重複的資料

然後下方檔案我是利用vba模擬你說的使用移除重複功能 你先看看
    [attach]29575[/attach]
作者: jackson7015    時間: 2018-10-23 11:49

回復 14# zheng211016
感謝zheng211016的幫忙

測試好幾次都怪怪的
發現原來是EXCEL的刪除重複方式會把重複的留一個下來
但是資料需求不需要留重複的項目

所以只要有重複的,都不需要複製到右側
而因為資料列因為還有其他不同的資料
所以列位會有不一樣(欄位都相同)

如果使用巨集可能還要做列位多寡判定
可能會比較麻煩

再請各位大大看看
感激不盡~
作者: 准提部林    時間: 2018-10-23 20:11

1>A區/B區同時存在,剔除
2>A區有多筆相同,只取一筆(B區同理)
3>右側結果每筆之間不留空白行,兩區各自上下區存放

寫得有點複雜,自行逐行參酌:
[attach]29583[/attach]

Sub TEST()
Dim Arr, Brr, xD, i&, j%, U&, V&, N&, T1$, T2$, T3$
[O4:AA20000].Clear
Set xD = CreateObject("Scripting.Dictionary")
Arr = Range([M4], Cells(Rows.Count, 1).End(xlUp))
ReDim Brr(1 To UBound(Arr), 1 To 13)
For i = 2 To UBound(Arr)
    T1 = Arr(i, 1): T2 = Arr(i, 4): T3 = Arr(i, 8)
    If T1 = "座標" Then V = i - 1: GoTo 101
    If T1 = "" Or T2 = "" Or T3 = "" Then GoTo 101
    U = xD(T1 & T2 & T3)
    If U = 0 Then xD(T1 & T2 & T3) = i: GoTo 101
    If U > 0 And U <= V Then xD(T1 & T2 & T3) = -1
101: Next i

For i = 1 To UBound(Arr)
    T1 = Arr(i, 1): T2 = Arr(i, 4): T3 = Arr(i, 8)
    U = xD(T1 & T2 & T3)
    If T1 = "座標" And N > 0 Then N = V
    If T1 = "座標" Or U = i Then
       N = N + 1
       For j = 1 To 13: Brr(N, j) = Arr(i, j): Next
    End If
Next i

With [O4:AA4].Resize(UBound(Brr))
     .NumberFormatLocal = "@"
     .Value = Brr
     .Borders.LineStyle = 1
End With
End Sub

 
作者: faye59    時間: 2018-10-23 20:11

回復 9# jackson7015


    如10樓所言
不懂分割用意,
程序也可以寫成讓你方便檢視,
但你要把你的過程及結果詳細提出,
過程:執行的限制條件。
結果:執行後所想看的資訊。
要寫到巨集幾乎都是為了效率,
難以計算、重複動作太多、每日同樣操作繁瑣...等狀況,
我們就會以巨集簡易且快速計算。

建議手動先把你的範例結果上傳,
可能程式碼你不是很熟,
不知道程序能執行的效果到哪,
所以溝通上有所差異,
你講的問題我們都會在腦中先經過計算看是否可行或是否繁瑣,
覺得可以才會回覆你的問題。
作者: faye59    時間: 2018-10-23 20:26

回復 15# jackson7015


    抱歉,
沒看到後面還有第二頁,
大致上明白你要的結果了,
但准大已出馬,
小弟就不贅述了。
作者: jackson7015    時間: 2018-10-24 09:59

回復 16# 准提部林
回復 16# faye59
沒想到還讓大大出手協助
超級感謝 准提部林 版主大大的幫忙

程式運作沒問題,也能套用在其他分頁資料上
追加的2>A區有多筆相同,只取一筆(B區同理)也很好用
程式內容內部修改標題搜尋,就能運用在其他資料上了
程式碼定義和編成還要在了解一下

也感謝faye59的回覆

再次感謝協助過的大大們的幫忙
作者: Andy2483    時間: 2022-11-1 11:29

回復 16# 准提部林
        謝謝前輩!這太難了!
以下心得註解!請前輩再指導!
執行前:
[attach]35437[/attach]

執行結果:
[attach]35438[/attach]

Option Explicit
Sub TEST()
Dim Arr, Brr, xD, i&, j%, U&, V&, N&, T1$, T2$, T3$, S
S = Timer
'↑宣告變數
[O4:AA20000].Clear
'↑將儲存格清除
Set xD = CreateObject("Scripting.Dictionary")
'↑令xD是字典
Arr = Range([M4], Cells(Rows.Count, 1).End(xlUp))
'↑令Arr是字典!倒入:[M4]到A欄最後一有內容儲存格之間,
'擴展為最小方正區域儲存格的值

ReDim Brr(1 To UBound(Arr), 1 To 13)
'↑宣告Brr空陣列範圍縱向從1到Arr陣列縱向最大列數,
'橫向從1到13欄(兩個陣列大小相同)

For i = 2 To UBound(Arr)
'↑設順迴圈!從2 到Arr陣列縱向最大列數
    T1 = Arr(i, 1) '座標欄
    '↑令T1是Arr陣列迴圈列/第一欄值
   
    T2 = Arr(i, 4) '點數欄
    '↑令T2是Arr陣列迴圈列/第四欄值
   
    T3 = Arr(i, 8) '點數欄
    '↑令T3是Arr陣列迴圈列/第八欄值
   
    If T1 = "座標" Then
    '↑如果儲存格[M4] 裡的值是 "座標" 字串??
       V = i - 1  '@@
       '↑條件成立就令 V記憶是當下迴圈數 -1 ,這是要辨認A區最後列數
       GoTo 101
       '↑條件成立就跳到 101位置繼續執行
       ',B區標題列!此列不處理

    End If
    If T1 = "" Or T2 = "" Or T3 = "" Then
    '↑如果迴圈座標 迴圈點數 迴圈點數任何一個是空白
       GoTo 101
       '↑條件成立就跳到 101位置繼續執行,這是不處裡空白格
    End If
    U = xD(T1 & T2 & T3)
    '↑令U是 (迴圈座標,迴圈點數,迴圈點數)組合字串_以下稱(組合字串)為key的item值
    '初始值是 0

    If U = 0 Then
    '↑如果U 是初始值是 0,因為 U宣告長整數
       xD(T1 & T2 & T3) = i
       '↑條件成立!組合字串為key倒入xD字典!item值是迴圈數
       '這是A區有多筆相同,只取一筆(B區同理)! 列數記憶在字典item裡

       GoTo 101
       '↑條件成立就跳到 101位置繼續執行
    End If
    If U > 0 And U <= V Then
    '↑如果U不是初始值!已經有迴圈數作為 item 了
    '而且U的列數小於等於(A區最後列數)!也就是在A區有且B區也有!

       xD(T1 & T2 & T3) = -1
       '↑條件成立!就令在xD字典裡以組合字串為key的item為 -1
       '這裡的 -1是不讓寫入Brr陣列裡

    End If
101: Next i

'1.A區/B區同時存在,剔除
'2.A區有多筆相同,只取一筆(B區同理)

'↑執行功能雖然是如此敘述!但後學在邏輯裡的心得是:
'1.1.全部迴圈判斷只有一筆的就留著!字典記憶所在列數!沒懸念!管他A區 或 B區
'1.2.全部迴圈判斷有多筆的!找到相同的第二筆看是不是在同區,在不同區這筆兩區都不要了


For i = 1 To UBound(Arr)
'↑設外順迴圈!從1 到Arr陣列縱向最大列數
    T1 = Arr(i, 1) '座標欄
    '↑令T1是Arr陣列迴圈列/第一欄值
   
    T2 = Arr(i, 4) '點數欄
    '↑令T2是Arr陣列迴圈列/第四欄值
   
    T3 = Arr(i, 8) '點數欄
    '↑令T3是Arr陣列迴圈列/第八欄值
    U = xD(T1 & T2 & T3)
    '↑令U是 (迴圈座標,迴圈點數,迴圈點數)組合字串_以下稱(組合字串)為key的item值
    '初始值是 0
    If T1 = "座標" And N > 0 Then
    '↑這 T1 = "座標" 是要辨認B區標題列數
    '↑如果迴圈跑到了 B區標題列數 而且N > 0 ,N宣告為長整數!初始值是 0
    ',所以一開始條件是不會成立的!這種邏輯寫法需要跳脫眼見為憑的觀念!
    '邏輯框架概念需要練習!無中生有的N 先知道要查宣告就可以了!
    '↑迴圈的一開始條件是不會成立的!
    '因為當i=1,T1 = "座標",N=0 , 當i=2,N=1,T1 已經不是字串 "座標"

   
       N = V
       '↑直到B區標題列開始條件成立!就令N=V!  V:在上方 @@標示處
       '這是要讓 資料要寫入結果陣列Brr的列數 切換到B區開始累加列數用的
    End If
    If T1 = "座標" Or U = i Then
    '↑如果迴圈座標欄是 "座標"字串(標題列也要寫進陣列Brr裡)
    '或 如果組合字串為key的item是迴圈數??

       N = N + 1
       '↑條件成立! N就累加 1,這是資料要寫入結果陣列Brr的列數
       For j = 1 To 13
       '↑設內順迴圈!從1 到 13(欄數)
          Brr(N, j) = Arr(i, j)
          '↑Arr陣列的值倒入Brr陣列 N對應的列位/j欄位裡
       Next
    End If
Next i
With [O4:AA4].Resize(UBound(Brr))
'↑關於[O4:AA4]向下匡列Brr陣列縱向最大列數的範圍儲存格,以下稱(匡列格)
     .NumberFormatLocal = "@"
     '↑匡列格的格式設為 文字
     .Value = Brr
     '↑值是Brr陣列裡對應的值
     .Borders.LineStyle = 1
     '↑儲存格格線設為 細實線
End With
MsgBox Timer - S & " 秒"
End Sub
作者: Andy2483    時間: 2022-11-1 16:18

回復 16# 准提部林


    謝謝前輩
後學用比較笨的方法練習陣列與字典!
請前輩撥空指正並指導!謝謝

[attach]35440[/attach]

Option Explicit
Sub 陣列與字典練習()
Dim Arr, N&, i&, Y, A&, S, TT$
Dim B#, j&, K%, P$, Q, Ra
Set Y = CreateObject("Scripting.Dictionary")
S = Timer
[O4:AA20000].Clear
Set Y = CreateObject("Scripting.Dictionary")
Arr = Range([M4], Cells(Rows.Count, 1).End(xlUp).Offset(1))
ReDim Brr(1 To UBound(Arr), 1 To 13)
For i = 2 To UBound(Arr) - 1
   TT = Arr(i, 1) & Arr(i, 4) & Arr(i, 8)
   Y(A & "|" & TT & "|" & i) = i
   Y(A & "|" & TT) = Y(A & "|" & TT) + 1
   If Arr(i + 1, 1) = "座標" Then
      A = i + 1
      i = A
   End If
Next
For i = 1 To UBound(Arr) - 1
   If i = A Then
      N = A - 1
   End If
   TT = Arr(i, 1) & Arr(i, 4) & Arr(i, 8)
   If Y("0|" & TT) = Y(A & "|" & TT) And i <> 1 And i <> A Then
      ElseIf Y("0|" & TT) > 1 Then
         Y("0|" & TT) = Y("0|" & TT) - 1 '若相同!留最後一筆
      ElseIf Y(A & "|" & TT) > 1 Then
         Y(A & "|" & TT) = Y(A & "|" & TT) - 1 '若相同!留最後一筆
      Else
         N = N + 1
         For j = 1 To 13
            Brr(N, j) = Arr(i, j)
         Next
   End If
Next
With [O4:AA4].Resize(UBound(Brr))
     .NumberFormatLocal = "@"
     .Value = Brr
     .Borders.LineStyle = 1
End With
MsgBox Timer - S & " 秒"
End Sub




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)