返回列表 上一主題 發帖

[發問] vba的篩選功能 (取消部分篩選)

回復 33# wei9133

#33
有2場一樣(勝率欄為"空","空")合併勝率為1
只有1場(勝率欄為"空")勝率為"空"

幾種狀況如何計算
2場(勝率為"3","空")合併勝率??(是否為4)
3場(勝率為"3","空","空")合併勝率??(是否為4)
3場(勝率為"空","空","空")合併勝率??(是否為1)
3場(勝率為"3","1","空")合併勝率??(是否為5)
4場(勝率為"空","3","1","空")合併勝率??(是否為5)
只有一場是否勝率欄位都不變
多場的只要勝率為空的不管幾場都只算1場勝場,其餘勝率欄有值的直接累加值

TOP

回復  wei9133

你把 jcchiang前輩的 以下這段改一下 看看 是不是你要的結果

Sub ex3()
Dim d As Ob ...
軒云熊 發表於 2020-10-21 21:56

你好
因為測試完
勝率那格無論是空還是1都會被視為1,但實際上應該是空為1,寫1實際應為2 (要被合併的狀況下)
而不被合併的狀況下空就是空,該格不應有值 (因為該列自己就是1)
所以只註解掉迴圈加1的部分還是沒用的
勝率那格有值的正確了,空的就會有問題,反之亦然
所以你改的這樣還是不太對
感謝你了

TOP

回復 31# jcchiang

30F的確是我算錯了
力量英雄應該是4

(#23樓:而勝場部份的值則分別為3、空格、1,敗場的值則為1、空格、空格
  算出來合併的勝場欄位應為"6",敗場則為"1"
   算法是這樣的,假設3那格保留,而空格代表勝1場,勝場填入1的實際上是"當列"加"勝1場"
   所以加出來是"6")

第二段的部分你的理解是對的

勝場(3,空,1)=6,如果以空為1,實際也是5,多的1場不就是而外增加的嗎??
這個其實我沒看懂

我這樣看你能不能理解
紀錄出來的當列,本身就代表那次的勝場,當我統計到一模一樣的對戰,就在勝場處+1
所以每一列都代表了1,而勝場是另外加上去的,才會變成處理到該格若該格有值要+1上去
勝率那格若無另外的數值,整列視為1

===================分隔線======================
我拿了你在28F提供的程式碼下去執行
圖1

圖一的第一跟第二列勝率欄位都是0,代表各自當列的勝場,而這兩個結構都一樣
所以運行出來應該是
合併起來,勝率寫1  (實際上是贏2場沒錯,但自己這一列就代表了一場,所以勝率那格只會寫1)
第三行是獨自自己一個,沒有相同列,所以就只有保留,至於勝率因為該格是0,且只有它自己,所以應該留空
我想執行出來的結果
圖2

===============================================
實際執行出來的結果
圖3

我執行的結果出來感覺是,勝率那格無論是空還是1都會被視為1
但實際上應該是該列等於1,勝率那格若有數字,
且該列要被併到另一列的話,就要以該格數字加上自己這一列代表的1

而是勝率那格是空值且無相同列可合併的,保留該列,勝率那格也就還是0
(因為贏的依舊只有一場,而那場就是該列本身)

==============================================
若這樣真的很難被理解的話,我可以改變統計方式
整列不代表任何數字,贏的次數全寫在勝率那��
這個組合贏一次就寫1,贏兩次就寫2
這樣就不會有要計算本身列為1的問題了

你的整個程式我再研究看看要改哪裡才會符合我的需求
感謝兩位

圖1.png (16.24 KB)

圖1.png

TOP

回復 30# wei9133

你把 jcchiang前輩的 以下這段改一下 看看 是不是你要的結果

Sub ex3()
Dim d As Object, ar As Object, r
Dim i%, AA$, a
Application.ScreenUpdating = False
Set d = CreateObject("Scripting.Dictionary")
Set ar = Sheets(1).[a1].CurrentRegion

For i = 1 To ar.Rows.Count
   AA = Join(Application.Transpose(Application.Transpose(ar(i, 1).Resize(, 102))), ",") & "," & ar(i, 106) '建立判斷條件
   If Not d.exists(AA) Then   '字典內查無該條件
      a = Application.Transpose(Application.Transpose(ar(i, 1).Resize(, 115)))
      If a(103) = "" Then a(103) = 1 '勝場空白填入1
      d(AA) = a '將資料放回字典
   Else
      a = Application.Transpose(Application.Transpose(d(AA)))   '將字典資料取出
      If ar(i, 103) = "" Then a(103) = a(103) + 1 Else a(103) = a(103) + ar(i, 103) '勝場空白勝場累加1,不是空白則將欄位值相加
      a(105) = a(105) + ar(i, 105) '敗局累加
      For Each r In Array(104, 107, 109, 115) '將備註,DC,DE,DK欄位資料合併
         If a(r) <> "" And ar(i, r) <> "" Then '如果字典與欄位都有資料,使用","相連
            a(r) = a(r) & "," & ar(i, r)
         ElseIf a(r) = "" And ar(i, r) <> "" Then '如果字典資料為空白,欄位是有資料的,使用欄位資料
            a(r) = ar(i, r)
         End If
      Next
      d(AA) = a   '將資料放回字典
   End If
Next
With Sheets(2)  '在第二個Sheet填入資料
.[a1].CurrentRegion.Clear '清除Sheet資料
.[a1].Resize(d.Count, 115) = Application.Transpose(Application.Transpose(d.items)) '將字典資料列出
'For Each r In .Range(.[cy2], .[cy2].End(4))  '保留勝場+1
'   r.Value = r.Value + 1
'Next

End With
Set d = Nothing
Application.ScreenUpdating = True
End Sub

TOP

回復 29# wei9133

勝率計算是否為沒有重複的就不多加1場嗎??
因為你的勝場算法都不一樣
以你在#30樓的貼圖
人類4場勝率為(1,2,空,空),勝率應為1+2+1+1=5保留再加1,所以為6
但力量英雄2場勝率為(空,3),勝率應為1+3=4保留再加1,所以為5,但給的正確勝率卻為3

(#23樓:而勝場部份的值則分別為3、空格、1,敗場的值則為1、空格、空格
  算出來合併的勝場欄位應為"6",敗場則為"1"
   算法是這樣的,假設3那格保留,而空格代表勝1場,勝場填入1的實際上是"當列"加"勝1場"
   所以加出來是"6")
勝場(3,空,1)=6,如果以空為1,實際也是5,多的1場不就是而外增加的嗎??

另外資料放置其他Sheet是不去改變原有資料以便驗證,而且程式註解也有寫放置於第二個Sheet
如要改放於其他位置或做法,程式中都有註解,請自行微調,謝謝!!

TOP

回復 27# 軒云熊
你好
直接執行你的附件,勝率的確會增加
以刪除下面幾行,僅複製2~3行做副本,貼在5~6行
執行不會運作(懷疑是因為我空行了)
圖1

並且在你初始的檔案中,執行後並未合併,而是直接加上勝率(場)

圖2
初始

圖3
執行後

正確應該是
圖4

TOP

回復 28# jcchiang

你好
先以5格為基準直接執行
經測試,勝率部分不管有沒有重複都會直接+1上去
圖一
(原始資料)
圖二
(產出資料)

勝率這格有問題的樣子
我總共以5格做測試,1~5格複製一份放在下面列中,僅更改星象部分
出來結果是錯誤的
圖三
(原始資料)
圖四
(產出資料)

正確應該為
圖5



另外,之前要修正後資料放進sheet2內本來就是為了比對程式是否執行正確
這次也是多虧了這點才能看出加總的部分不對
而我的第二位置活頁簿其實是有其他資料的,這樣就直接把資料全蓋過去了
可以麻煩改成複製一份當前(sheet)執行程式的副本,然後直接在執行活頁簿中將重複列刪除加總?
(建立副本作為備份,直接在需要運行的活頁簿內做刪除,若無法
我想到的是執行後把目前的sheet1刪除,sheet2改名成sheet1而已)

複製副本的指令可以的話幫我加註解,確認程式都正常運行之後就不需要做副本了
因為副本本來就是為了驗證是否正確執行而存在的
感謝

TOP

回復 26# wei9133

資料改放置於第二個Sheet
Sub ex3()
Dim d As Object, ar As Object, r
Dim i%, AA$, a
Application.ScreenUpdating = False
Set d = CreateObject("Scripting.Dictionary")
Set ar = Sheets("對戰統計").[a1].CurrentRegion

For i = 1 To ar.Rows.Count
   AA = Join(Application.Transpose(Application.Transpose(ar(i, 1).Resize(, 102))), ",") & "," & ar(i, 106) '建立判斷條件
   If Not d.exists(AA) Then   '字典內查無該條件
      a = Application.Transpose(Application.Transpose(ar(i, 1).Resize(, 115)))
      If a(103) = "" Then a(103) = 1 '勝場空白填入1
      d(AA) = a '將資料放回字典
   Else
      a = Application.Transpose(Application.Transpose(d(AA)))   '將字典資料取出
      If ar(i, 103) = "" Then a(103) = a(103) + 1 Else a(103) = a(103) + ar(i, 103) '勝場空白勝場累加1,不是空白則將欄位值相加
      a(105) = a(105) + ar(i, 105) '敗局累加
      For Each r In Array(104, 107, 109, 115) '將備註,DC,DE,DK欄位資料合併
         If a(r) <> "" And ar(i, r) <> "" Then '如果字典與欄位都有資料,使用","相連
            a(r) = a(r) & "," & ar(i, r)
         ElseIf a(r) = "" And ar(i, r) <> "" Then '如果字典資料為空白,欄位是有資料的,使用欄位資料
            a(r) = ar(i, r)
         End If
      Next
      d(AA) = a   '將資料放回字典
   End If
Next
With Sheets(2)  '在第二個Sheet填入資料
.[a1].CurrentRegion.Clear '清除Sheet資料
.[a1].Resize(d.Count, 115) = Application.Transpose(Application.Transpose(d.items)) '將字典資料列出
For Each r In .Range(.[cy2], .[cy2].End(4))  '保留勝場+1
   r.Value = r.Value + 1
Next
End With
Set d = Nothing
Application.ScreenUpdating = True
End Sub

TOP

回復 26# wei9133

有空看一下 不知道是不是你要的  

javascript:;

對戰統計 - 複製1019.rar (23.49 KB)

TOP

回復 24# jcchiang

回復 24# jcchiang

兩位好
首先先感謝二位花時間幫我想辦法

至於空間的部分
我重新換個空間
googl
https://drive.google.com/file/d/1VFZMILovCRpQT6AGyaAd8ZNb9VAZSFlO/view?usp=sharing
onedrive
https://1drv.ms/u/s!Amaq2OY73W7WiSHXDt88TA7rsUgC?e=BmwuJh

附件:我有砍東西因為論壇只給1MB,不過用來理解需求應該夠
對戰統計 - 複製.rar (666.38 KB)
  1. Sub ex3()
  2. Dim d As Object, ar As Object, r As Object
  3. Dim i%, AA$, a

  4. Set d = CreateObject("Scripting.Dictionary")
  5. Set ar = [A1].CurrentRegion

  6. For i = 1 To ar.Rows.Count
  7.    AA = Join(Application.Transpose(Application.Transpose(ar(i, 1).Resize(, 102))), ",") & "," & ar(i, 106) '建立判斷條件
  8.    If ar(i, 103) = "" Then ar(i, 103) = 1 '勝場空白填入1
  9.    If Not d.exists(AA) Then   '字典內查無該條件
  10.       d(AA) = ar(i, 1).Resize(, 106) '增加字典資料
  11.    Else
  12.       a = Application.Transpose(Application.Transpose(d(AA)))   '將字典資料取出
  13.       a(103) = a(103) + ar(i, 103) '勝率累加
  14.       a(104) = a(104) + 1           '備註:相符的筆數(不包含第一筆)
  15.       a(105) = a(105) + ar(i, 105) '敗局累加
  16.       d(AA) = a   '將資料放回字典
  17.    End If
  18. Next
  19. [a14000].Resize(d.Count, 106) = Application.Transpose(Application.Transpose(d.items)) '將字典資料列出
  20. For Each r In Range([cw14001], [cw14001].End(4))  '保留勝場+1
  21.    r.Value = r.Value + 1
  22. Next
  23. Set d = Nothing
  24. End Sub
複製代碼
因為加了新英雄所以位置不一樣了
我把程式的數字都往後推,但是看起來是有問題的
應該是因為前面的沒有給圖所以這裡會有問題
(勝跟敗中間有一個備註欄位)




加總後應該優先填在這種列上 DC OR DE OR DK有值 其次是CZ有值

P.S.
在把數值加上去之前有讓程式跑過一遍
不過跟預計的一樣,格子不對所以是有問題的
但發現有幾個想問問可否變更的部分
其一
目前資料已有九千多行,所以其實比對出來資料是否正確我也無法驗證
所以可否將運行完成後的直接產生另一個活頁簿,我直接看兩個活業簿的列數是否有差異
(當然初始驗證運作的時候可以先把固定的資料複製多行再到產生的活頁簿去看相同列是否有加總上去就知道了)
ex.
原始資料(sheet1)9000行,產生的新活頁簿(sheet2)(比對過的資料),變成8800,這樣就可以知道確實有疊上去了
再人工去確認sheet1跟sheet2的差異點就可以確認程式是否正確

其二
執行的時候是否可加上
Application.Calculation = xlCalculationManual '關閉自動計算
Application.ScreenUpdating = False '關閉螢幕刷新
全部結束後再加上
Application.Calculation = xlCalculationAutomatic '開啟自動計算
Application.ScreenUpdating = True '開啟螢幕刷新
避免程式一直重新計算儲存格?
(我目前無法測,因為我也不知道目前的程式到底對不對)

to 軒云熊
抱歉之前我沒自己下回來測過,這次我有下回來測過了,應該可以用了
p.s. 無法解壓也有可能是因為rar版本過舊,可以試看看新版的rar,目前個人版是免費的。

真的沒法下載的話,我把第一列都拍下來了




目前是比對A~CX and DB長一樣
把上述條件一樣的列的CY(勝場) | DA(敗場)  加總填入同一列
至於填入哪一列優先考慮   DC OR DE OR DK有值 其次是CZ有值

jcchiang所理解的條件是對的

TOP

        靜思自在 : 【時間無法遮擋】怕時間消逝,花了許多心血,想盡各式方法要遮擋時間,結果是:浪費了更多時間,且一無所成!
返回列表 上一主題