返回列表 上一主題 發帖

vba 依據textbox中所需入的值篩選出相對的筆數

  1. Sub vbaAFilter()
  2. Dim j&, Jm&, k&, TX&, Arr, Sht As Worksheet
  3. TX = TextBox1.Text: If TX = 0 Then Exit Sub
  4.  
  5. Arr = Sheets("工作表1").UsedRange.Value
  6. For j = 19 To UBound(Arr)
  7.   If IsError(Arr(j, 2)) Then GoTo 101
  8.   If Arr(j, 2) <> "PASS" Then GoTo 101
  9.   Jm = Jm + 1
  10.   For k = 1 To UBound(Arr, 2): Arr(Jm + 18, k) = Arr(j, k): Next
  11.   If Jm = TX Then Exit For
  12. 101: Next j
  13. If Jm = 0 Then Exit Sub
  14.  
  15. On Error Resume Next: Set Sht = Sheets("PASS名單"): On Error GoTo 0
  16. If Sht Is Nothing Then Set Sht = Sheets.Add:  Sht.Name = "PASS名單"
  17. With Sht
  18.   .Select: .UsedRange.Clear: .[A1].Resize(Jm + 18, UBound(Arr, 2)) = Arr
  19. End With
  20. End Sub
複製代碼

TOP

回復 4# t591nm


之前有位網友是這樣做的:
1.逐行程式以自己的理解加入註解,然後再整個貼出來
2.有疑問的部份再提出

這樣才可以真正學到程式的用意,
我也才能知道要補充哪裡的說明!

TOP

本帖最後由 准提部林 於 2015-10-21 13:40 編輯

回復 6# t591nm


UBound(Arr) 
_為陣列的〔列數〕,可寫成 UBound(Arr , 1);UBound(Arr, 2) 則為〔欄數〕 

Jm = Jm + 1 
_為已取得符合 "PASS" 資料的〔累計筆數〕 

For k = 1 To UBound(Arr, 2): Arr(Jm + 18, k) = Arr(j, k): Next  
_依 Arr 的〔欄數〕迴圈將資料放入陣列,因從第19列開始,故須+18 

On Error Resume Next: Set Sht = Sheets("PASS名單"): On Error GoTo 0
_檢查〔PASS名單〕工作表是否已存在 
_若不存在,Set Sht = Sheets("PASS名單") 這行會因錯誤而中斷
_On Error Resume Next 就是要〔略過錯誤〕使程式繼續運行
 
_On Error GoTo 0 讓程式恢復檢偵錯功能 

If Sht Is Nothing Then Set Sht = Sheets.Add:  Sht.Name = "PASS名單"
_工作表不存在,新增一個新工作表並重命名 
 
With Sht
    .Select: .UsedRange.Clear: .[A1].Resize(Jm + 18, UBound(Arr, 2)) = Arr
End With
_選取工作表.清除原有資料.置內陣列內容 


GOTO 101 
_當條件成立,指定程式跳至這一標記行,而略過其下方的程式 

TOP

回復 8# t591nm

這樣更複雜些,請自行研究:
  1. Sub vbaAFilter()
  2. Dim j&, Jm&, k&, Km&, TX&, Arr, Brr, TT$, Sht As Worksheet
  3. TX = TextBox1.Text: If TX = 0 Then Exit Sub
  4. With Sheets("工作表1").UsedRange
  5.   Arr = .Value
  6.   Brr = .Rows(12)
  7. End With
  8.  
  9. TT = "_FL_C0_C0/C1_RLD2_RR_TS_C1_FDLD_DLD2_"
  10. For j = 3 To UBound(Brr, 2)
  11.   If InStr(TT, "_" & Brr(1, j) & "_") = 0 Then Brr(1, j) = ""
  12. Next
  13.  
  14. For j = 12 To UBound(Arr)
  15.   If j > 18 Then
  16.     If IsError(Arr(j, 2)) Then GoTo 101
  17.     If Arr(j, 2) <> "PASS" Then GoTo 101
  18.   End If
  19.   Jm = Jm + 1: Km = 0
  20.   For k = 1 To UBound(Arr, 2)
  21.     If Brr(1, k) <> "" Then Km = Km + 1: Arr(Jm + 11, Km) = Arr(j, k)
  22.   Next
  23.   If Jm = TX + 7 Then Exit For
  24. 101: Next j
  25. If Jm = 0 Then Exit Sub
  26.  
  27. On Error Resume Next: Set Sht = Sheets("PASS名單"): On Error GoTo 0
  28. If Sht Is Nothing Then Set Sht = Sheets.Add:  Sht.Name = "PASS名單"
  29. With Sht
  30.    .Select: .UsedRange.Clear: .[A1].Resize(Jm + 11, Km) = Arr
  31. End With
  32. End Sub
複製代碼

TOP

回復 11# t591nm

上傳範例檔如果可以正常執行, 其它檔就要去比對其差異, 才知道錯在哪?
資料必須是有固定規則的:
第1∼11列,為〔表首〕   
第12列,為〔標題列〕
第13∼18列,為〔標註或備註〕吧(猜)
第19列及以下,為〔資料明細區〕

因指定〔標題列〕符合文字才取出該欄,
所以取出資料由19列改由12列開始,
若要取50筆〔明細〕,則包含〔標題〕之間的7列,Jm = TX + 7 才夠

TT = "_FL_C0_C0/C1_RLD2_RR_TS_C1_FDLD_DLD2_"
For j = 3 To UBound(Brr, 2)
    If InStr(TT, "_" & Brr(1, j) & "_") = 0 Then Brr(1, j) = ""
Next
↑這段用來排除〔標題列〕不符合文字時,使其文字變為空字符"",以為下方取得符合〔欄〕資料的依據 


請注意匯入文字檔及貼入資料的問題,
有沒考慮過為何資料會有65536列,而其中有很多的〔#N/A〕錯誤值?
copy1 = Sheets(1).Range("A1:Q8000") 這才8000列
Range("A1:Q65535") = copy1 卻貼成65536列????

TOP

本帖最後由 准提部林 於 2015-10-23 15:10 編輯

Sub vbaAFilter()
Dim j&, Jm&, k&, Km&, TX&, Arr, Brr, N&, uChk&, TT$, Sht As Worksheet
TX = TextBox1.Text: If TX = 0 Then Exit Sub
Arr = Sheets("工作表1").UsedRange.Value
ReDim Brr(1 To UBound(Arr, 2))
TT = "_FL_C0_C0/C1_RLD2_RR_TS_C1_FDLD_DLD2_"
 
For j = 1 To UBound(Arr)
  If Arr(j, 1) = "Crystal" Then '以〔Crystal〕判斷是否為〔標題列〕 
   For k = 1 To UBound(Arr, 2)
     Brr(k) = Arr(j, k) '標題文字納入陣列,不符合者填入空字符 
     If k > 2 And InStr(TT, "_" & Arr(j, k) & "_") = 0 Then Brr(k) = ""
   Next k
   uChk = 1:  N = j - 1 '標題列上方的〔列數〕 
  End If
 
  If Arr(j, 1) = 1 Then uChk = 2: N = j - 1: Jm = 0 
  '_若A欄為1,則判斷為〔明細〕的開始,N為上方列數,Jm歸零 
  If uChk = 0 Then GoTo 101
  If uChk = 2 And Arr(j, 2) <> "PASS" Then GoTo 101
  Jm = Jm + 1: Km = 0
  For k = 1 To UBound(Arr, 2)
    If Brr(k) <> "" Then Km = Km + 1: Arr(Jm + N, Km) = Arr(j, k)
  Next
 
  If uChk = 2 And Jm = TX Then Exit For
101: Next j
If Jm = 0 Then Exit Sub
 
On Error Resume Next: Set Sht = Sheets("PASS名單"): On Error GoTo 0
If Sht Is Nothing Then Set Sht = Sheets.Add:  Sht.Name = "PASS名單"
With Sht
  .Select: .UsedRange.Clear: .[A1].Resize(Jm + N, Km) = Arr
End With
End Sub

'==============================
uChk =1 表示迴圈到〔標題列〕
uChk =2 表示迴圈到〔明細〕的開頭

資料底下的〔錯誤值〕務必先清除∼∼ 

TOP

回復 14# t591nm


是可以將〔標題列〕及〔明細開頭〕強制固定列號,
若有不同,可手動調整,只要多保留幾個空白列當緩衝即可∼∼辦法是想出來的∼∼

TOP

        靜思自在 : 自己害自己,莫過於亂發脾氣。
返回列表 上一主題