Board logo

標題: [發問] VBA 搜尋的問題 [打印本頁]

作者: sss1159    時間: 2015-11-6 11:28     標題: VBA 搜尋的問題

本帖最後由 sss1159 於 2015-11-6 11:31 編輯

HI,大家好

在網路上爬了一段時間,測了多種的做法還是沒找到理想的方式
在此詢問一下各位大大

有2個工作表
工作表1 = 存放各種資料的地方
工作表2 = 搜尋區

這邊需要2種方式:
1.
在工作表2 搜尋區 輸入要搜尋的資料【甲】
即可顯示 有關於【甲】的所有資料

2.
在工作表1 點選搜尋
會跳出彈窗 輸入【甲】
就會在工作表1 顯示所有關於 班級【甲】的資料

在點選 按鈕取消搜尋 即可恢復成原來的所有資料


在麻煩各位大大教導,謝謝
作者: yen956    時間: 2015-11-6 17:50

本帖最後由 yen956 於 2015-11-6 17:52 編輯

試試看:
Q1:
  1. Private Sub CommandButton1_Click()
  2.     Dim sCel As Range
  3.     Dim inTxt, First1 As String
  4.     Dim LastRow As Long
  5.     Range("K2:N" & Rows.Count & "").ClearContents    '清除先前搜尋的資料"
  6.     inTxt = InputBox("請輸入搜尋班級", "搜尋班級")
  7.     If inTxt = "" Then Exit Sub                      '若使用者按 [取消] 則離開
  8.     Set sCel = [A:A].Find(What:=inTxt, LookAt:=xlWhole)
  9.     If sCel Is Nothing Then
  10.         MsgBox ("未找到你要搜尋的班級"), vbCritical
  11.         Exit Sub
  12.     End If
  13.     First1 = sCel.Address                       '保留第一個搜尋到的位址
  14.     Do
  15.         LastRow = Cells(Rows.Count, 11).End(xlUp).Row + 1
  16.         sCel.Resize(1, 4).Copy Cells(LastRow, 11)
  17.         Set sCel = [A:A].FindNext(sCel)        '尋找下一個
  18.     Loop Until First1 = sCel.Address            '下一個的位置=第一個的位置(回到第一個的位置)
  19. End Sub
複製代碼
Q2:
  1. Private Sub Worksheet_Change(ByVal Target As Range)
  2.     Dim sh1, sh2 As Object
  3.     Dim sCel As Range
  4.     Dim First1 As String
  5.     Dim LastRow As Long
  6.     Set sh1 = Sheets("工作表1")
  7.     Set sh2 = Sheets("工作表2")
  8.     If Intersect(Target, sh2.[I1]) Is Nothing Then Exit Sub
  9.     If Target = "" Then Exit Sub
  10.     sh2.Range("H4:K" & sh2.Rows.Count & "").ClearContents    '清除先前搜尋的資料"
  11.     sh1.Activate
  12.     With sh1
  13.         Set sCel = .[A:B].Find(What:=Target, LookAt:=xlPart)
  14.         If sCel Is Nothing Then
  15.             MsgBox ("未找到你要搜尋的資料"), vbCritical
  16.             Exit Sub
  17.         End If
  18.         First1 = sCel.Address                          '保留第一個搜尋到的位址
  19.         Do
  20.             LastRow = sh2.Cells(sh2.Rows.Count, 8).End(xlUp).Row + 1
  21.             sCel.Resize(1, 4).Copy sh2.Cells(LastRow, 8)
  22.             Set sCel = .[A:B].FindNext(sCel)           '尋找下一個
  23.         Loop Until First1 = sCel.Address               '下一個的位置=第一個的位置(回到第一個的位置)
  24.     End With
  25.     sh2.Activate
  26. End Sub
複製代碼

作者: sss1159    時間: 2015-11-9 11:17

抱歉,這週末不在家,很晚才回覆您
非常感謝 yen956 大大


另外想再請問
1.
工作表1 點選搜尋 甲
即可在此工作表 直接列出 班級甲的所有資料

再點選 取消搜尋
即可恢復原本未搜尋前的資料

2.
套用大大個方法
我目前卡住了....目前多了一個工作表3
在工作表2想搜尋限定範圍
搜尋 甲
A~D欄 會顯示工作表1 甲的搜尋內容
H~K欄 會顯示工作表3 甲的搜尋內容

3.
如果 搜尋按鈕找不到資料,要在哪打上 [抱歉,找不到資料] 的語法呢



麻煩請指教,萬分感謝
作者: sss1159    時間: 2015-11-9 11:51

啊啊啊><
小妹搞錯了...上一則回覆 是用另一個方法....

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim sh1, sh2 As Object
    Dim sCel As Range
    Dim First1 As String
    Dim LastRow As Long
    Set sh1 = Sheets("工作表1")
    Set sh2 = Sheets("工作表2")
    If Intersect(Target, sh2.[I1]) Is Nothing Then Exit Sub
    If Target = "" Then Exit Sub
    sh2.Range("H4:K" & sh2.Rows.Count & "").ClearContents    '清除先前搜尋的資料"
    sh1.Activate
    With sh1
        Set sCel = .[A:B].Find(What:=Target, LookAt:=xlPart)
        If sCel Is Nothing Then
            MsgBox ("未找到你要搜尋的資料"), vbCritical
            Exit Sub
        End If
        First1 = sCel.Address                          '保留第一個搜尋到的位址
        Do
            LastRow = sh2.Cells(sh2.Rows.Count, 8).End(xlUp).Row + 1
            sCel.Resize(1, 4).Copy sh2.Cells(LastRow, 8)
            Set sCel = .[A:B].FindNext(sCel)           '尋找下一個
        Loop Until First1 = sCel.Address               '下一個的位置=第一個的位置(回到第一個的位置)
    End With
    sh2.Activate
End Sub

想請問這段該怎麼使用呢..不知道為甚麼沒有巨集


Set sCel = [A:A].Find(What:=inTxt, LookAt:=xlWhole)

這段該怎麼去抓另一個工作表呢?
作者: 准提部林    時間: 2015-11-9 14:03

回復 3# sss1159


〔工作表1〕
再點選 取消搜尋
即可恢復原本未搜尋前的資料

A:D欄即是原本資料,搜尋並未動到此部份,何來〔恢復原本未搜尋前的資料〕???
作者: sss1159    時間: 2015-11-9 16:22

准提部林 大大您好

〔工作表1〕
再點選 取消搜尋
即可恢復原本未搜尋前的資料

A:D欄即是原本資料,搜尋並未動到此部份,何來〔恢復原本未搜尋前的資料〕???


這方面是我描述的不好,在工作表1中,A:D欄 為資料區
當我點擊 搜尋-> 甲 會將資料塞選成 所有關於 班級甲的資料(會顯示在A:D欄)
當我查完班級甲的資料後,點選 取消搜尋 即可恢復原本未搜尋前的資料(一樣在A:D欄)

再麻煩指教了,萬分感謝:$
作者: 准提部林    時間: 2015-11-9 17:29

回復 6# sss1159


Sub 篩選()
Dim X$
X = Application.InputBox("請輸入篩選關鍵字")
If X = "" Or X = "False" Then Exit Sub
With Range([A3], Cells(Rows.Count, 1).End(xlUp))
     If .Offset(1, 0).Find(X, Lookat:=xlPart) Is Nothing Then MsgBox "找不到資料!!": Exit Sub
    .AutoFilter Field:=1, Criteria1:="*" & X & "*"
End With
End Sub

'================================
Sub 篩選解除()
ActiveSheet.AutoFilterMode = False
End Sub
作者: 准提部林    時間: 2015-11-9 17:58

<工作表2> 

Sub 搜尋()
Dim X$, R&, xSht As Worksheet, M, j&, Jm&, xH As Range
R = ActiveSheet.UsedRange.Rows.Count
If R > 3 Then Rows("4:" & R).Delete
X = Application.InputBox("請輸入搜尋關鍵字")
If X = "" Or X = "False" Then Exit Sub
For Each xSht In Sheets(Array("工作表1", "工作表3"))
  Set xH = Range(Array("A4", "H4")(M))
  M = M + 1: Jm = 0
  With xSht
     For j = 4 To .Cells(Rows.Count, 1).End(xlUp).Row
       If InStr(.Cells(j, 1) & .Cells(j, 2), X) Then
         Jm = Jm + 1
         .Cells(j, 1).Resize(1, 4).Copy xH(Jm)
       End If
     Next j
     If Jm = 0 Then MsgBox "〔" & .Name & "〕找不到〔" & X & "〕相關資料!!":
  End With
Next
End Sub
作者: sss1159    時間: 2015-11-10 09:35

回復 8# 准提部林

實在是太感謝您了
想請教您這語法的意思是...看不太懂

1.
R = ActiveSheet.UsedRange.Rows.Count
If R > 3 Then Rows("4:" & R).Delete

這段是在 工作表2 算我表格前面留了多少列嗎?
如果我標題在行6 就改成 R>6 是這樣理解嗎?
後面的4是搜尋出來 資料顯示的起始欄位嗎?

2.
For Each xSht In Sheets(Array("工作表1", "工作表3"))
  Set xH = Range(Array("A4", "H4")(M))

如果 我還有 工作表4 工作表5
直接改成
For Each xSht In Sheets(Array("工作表1", "工作表3","工作表4", "工作表5"))
  Set xH = Range(Array("A4", "H4","O4", "U4")(M))
以此類推....??

3.
M = M + 1: Jm = 0
  With xSht
     For j = 4 To .Cells(Rows.Count, 1).End(xlUp).Row
       If InStr(.Cells(j, 1) & .Cells(j, 2), X) Then
         Jm = Jm + 1
         .Cells(j, 1).Resize(1, 4).Copy xH(Jm)
       End If


這段的4 要跟上面的
R > 3 Then Rows("4:" & R).Delete

一樣才能使用 是這樣吧?


再麻煩您指教下,非常感謝,努力學習中:$
作者: 准提部林    時間: 2015-11-10 09:56

本帖最後由 准提部林 於 2015-11-10 09:59 編輯

回復 9# sss1159


R = Range([A1], ActiveSheet.UsedRange).Rows.Count
_請改成如上,以防〔標題列〕以上未使用,UsedRange會不包涵這範圍
If R > 3 Then Rows("4:" & R).Delete
_〔標題列〕在第3列,若超過3才表示底下有資料,再清空

大凡表格結構會有〔表首〕〔標題列〕〔資料明細〕,皆以〔標題列〕為區隔線

這段是指要載入查詢資料的工作表,亦即執行vba的〔當前頁〕
作者: 准提部林    時間: 2015-11-10 10:03

回復 10# 准提部林


For j = 4 To .Cells(Rows.Count, 1).End(xlUp).Row

4為查詢資料〔來源〕工作表〔資料明細〕的〔起始列〕,與上方的4不相關,
一個是查詢表,一個是資料表,只是剛好都從第4列開始,
__不同工作表必須有固定的表格結構,否則容易出錯∼∼

其它大致都對∼∼
作者: sss1159    時間: 2015-11-10 10:35

回復 11# 准提部林

剛實際操作一遍,實在太厲害了!!!!
我後來在工作表1 新增了一個排序的功能(錄製巨集)
還沒塞選時 是能正常排序的
但我一但塞選時 再排序 EXCEL就當掉了

再麻煩您了 感謝感謝
附上語法

Sub 巨集3()
'
' 巨集3 巨集
'

'
    Range("E4:E10000").Select
    ActiveWorkbook.Worksheets("工作表1").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("工作表1").Sort.SortFields.Add Key:=Range("E4:E10000"), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("工作表1").Sort
        .SetRange Range("A3:E10000")
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    Range("E4").Select
    Selection.End(xlDown).Select
End Sub

設1萬 是怕日後資料越來越多 XD"
作者: 准提部林    時間: 2015-11-10 10:41

回復 12# sss1159

排序程式碼最上方加入:
ActiveSheet.AutoFilterMode = False

注意:篩選狀態時,若不先解除篩選,任何操作都可能造成無法彌補的錯誤(尤其是已執行了儲存結果)
作者: sss1159    時間: 2015-11-10 10:51

回復 13# 准提部林

注意:篩選狀態時,若不先解除篩選,任何操作都可能造成無法彌補的錯誤(尤其是已執行了儲存結果)

再測試時,就當了好幾次XD"

加了那段後,就不會當了,但是塞選會被取消掉,請問有辦法塞選完,再排序塞選的資料嗎?

不好意思,一直麻煩您:dizzy:
附上檔案給您看
作者: GBKEE    時間: 2015-11-10 12:50

本帖最後由 GBKEE 於 2015-11-10 12:57 編輯

回復 14# sss1159

試試看 2003的排序
  1. Option Explicit
  2. Sub 篩選()
  3.     Dim X$
  4.     X = Application.InputBox("請輸入篩選關鍵字")
  5.     If X = "" Or X = "False" Then Exit Sub   '
  6.     With Sheets("工作表1").[A3]  '
  7.         .Parent.AutoFilterMode = False
  8.         .AutoFilter Field:=1, Criteria1:="*" & X & "*"
  9.         If .End(xlDown).Row = Rows.Count Then MsgBox "找不到資料!!": Exit Sub
  10.         .CurrentRegion.Sort Key1:=.Range("A2"), Order1:=xlAscending, Key2:=.Range("B2"), Order2:=xlAscending, Header:=xlYes
  11.     End With
  12. End Sub
複製代碼

作者: sss1159    時間: 2015-11-10 13:03

回復 15# GBKEE

您好,使用了您的方法還是會跑出原本的資料
我附個示意圖=)

在麻煩了><
作者: GBKEE    時間: 2015-11-10 13:20

本帖最後由 GBKEE 於 2015-11-10 13:28 編輯

回復 16# sss1159
[新增日期]  在E欄(第5欄)修改如下:
  1. .CurrentRegion.Sort Key1:=.Range("A2"), Order1:=xlAscending, Key2:=.Range("E2"), Order2:=xlAscending, Header:=xlYes
複製代碼
  1. Sub 篩選()
  2.     Dim X$
  3.     X = Application.InputBox("請輸入篩選關鍵字")
  4.     If X = "" Or X = "False" Then Exit Sub   '
  5.     With Sheets("工作表1").[A3]  '
  6.         .Parent.AutoFilterMode = False
  7.         '篩選前也可所有資料 [新增日期]排序
  8.         '.CurrentRegion.Sort Key1:=.Range("E2"), Order1:=xlAscending, Header:=xlYes
  9.         .AutoFilter Field:=1, Criteria1:="*" & X & "*"
  10.         If .End(xlDown).Row = Rows.Count Then MsgBox "找不到資料!!": Exit Sub
  11.         '只對篩選後資料[新增日期]排序
  12.         .CurrentRegion.Sort Key1:=.Range("E2"), Order1:=xlAscending, Header:=xlYes
  13.     End With
  14. End Sub
複製代碼

作者: 准提部林    時間: 2015-11-10 13:25

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

回復 14# sss1159

Sub 排序()
Dim R&
R = [工作表1!A1].Cells(Rows.Count, 1).End(xlUp).Row
If R < 4 Then Exit Sub
With [工作表1!A3:E3].Resize(R - 2)
   .Select '這可以刪掉 
   .Sort Key1:=.Item(5), Order1:=xlAscending, Header:=xlYes, _
      OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
End With
End Sub

.Item(5) 即是E欄的標題〔新增日期〕!
再提醒:〔篩選〕狀態中,儘量不做〔排序〕,也不從它處貼資料進來,會造成資料錯亂
作者: sss1159    時間: 2015-11-10 14:31

謝謝 兩位版主抽空回覆
學到了很多,疑問也都解決了,
我再試著練習看看,非常感謝
作者: sss1159    時間: 2015-11-10 15:10

回復 17# GBKEE

馬上就有問題了....囧
由於上方註解需要多一行,變成標題欄在A4~E6
將 GBKEE大的語法稍做修正

Sub 篩選123()
    Dim X$
    X = Application.InputBox("請輸入篩選關鍵字")
    If X = "" Or X = "False" Then Exit Sub
    With Sheets("工作表3").[A4]  '
        .Parent.AutoFilterMode = False
        '篩選前也可所有資料 [新增日期]排序
        '.CurrentRegion.Sort Key1:=.Range("E2"), Order1:=xlAscending, Header:=xlYes
        .AutoFilter Field:=1, Criteria1:="*" & X & "*"
        If .End(xlDown).Row = Rows.Count Then MsgBox "找不到資料!!": Exit Sub
        '只對篩選後資料[新增日期]排序
        .CurrentRegion.Sort Key1:=.Range("C4"), Order1:=xlAscending, Header:=xlYes
    End With
End Sub

塞選後確出現標題也一併排序跑到最下面去了,導致版面亂了...
再麻煩了多次叨擾...
作者: sss1159    時間: 2015-11-10 17:00

回復 18# 准提部林

試了大大的方法,有個問題想問一下
   .Sort Key1:=.Item(6), Order1:=xlAscending, Header:=xlYes, _
      OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom


我這邊想自訂搜選的排序 "桌球","羽球","桌球","籃球"
我該如何加上上述語法呢?

麻煩了 :$
作者: 准提部林    時間: 2015-11-10 18:11

回復 21# sss1159


OFFICE 2000 沒這功能, 幫不了~~
作者: GBKEE    時間: 2015-11-11 06:25

本帖最後由 GBKEE 於 2015-11-11 06:50 編輯

回復 20# sss1159
用你的附檔 2003 沒這問題 .
回復 21# sss1159
2003 可用

[attach]22396[/attach]


[attach]22396[/attach]
作者: 准提部林    時間: 2015-11-11 11:46

回復 21# sss1159


LRR = Array("桌球", "羽球", "桌球", "籃球")  '排序清單 
Application.AddCustomList ListArray:=LRR  '建立清單 
Lx = Application.GetCustomListNum(LRR)  '取得清單位置序號 

With [工作表1!A3:F3].Resize(R - 2)
     .Select
     .Sort Key1:=.Item(6), Order1:=xlAscending, Header:=xlYes, _
           OrderCustom:=Lx + 1, MatchCase:=False, Orientation:=xlTopToBottom
End With
 
 
參考即可,這清單排序使用vba彈性並不好∼∼
作者: 准提部林    時間: 2015-11-11 11:50

回復 21# sss1159

這是較完整的做法,清單不存在,自動建立,隨後再刪掉∼∼
 
Sub 排序()
Dim R&, LRR, Lm%, Lx%
R = [工作表1!A1].Cells(Rows.Count, 1).End(xlUp).Row
If R < 4 Then Exit Sub
 
LRR = Split("藍球_排球_棒球_足球_桌球", "_")  '排序清單
With Application
   Lm = .GetCustomListNum(LRR)  '檢查清單的位置
   If Lm = 0 Then .AddCustomList ListArray:=LRR  '清單不存在,建立
   Lx = .GetCustomListNum(LRR)  '取得清單位置序號
End With
 
With [工作表1!A3:F3].Resize(R - 2)
   .Select
   .Sort Key1:=.Item(6), Order1:=xlAscending, Header:=xlYes, _
      OrderCustom:=Lx + 1, MatchCase:=False, Orientation:=xlTopToBottom
End With
 
If Lm = 0 Then Application.DeleteCustomList ListNum:=Lx  '清單若是本次建立,刪除清單
End Sub
作者: sss1159    時間: 2015-11-11 15:49

回復 25# 准提部林

非常感謝兩位板主的回覆><

Sub 排序()
Dim R&, LRR, Lm%, Lx%
R = [工作表1!A1].Cells(Rows.Count, 1).End(xlUp).Row
If R < 4 Then Exit Sub
 
LRR = Split("藍球_排球_棒球_足球_桌球", "_")  '排序清單
With Application
   Lm = .GetCustomListNum(LRR)  '檢查清單的位置
   If Lm = 0 Then .AddCustomList ListArray:=LRR  '清單不存在,建立
   Lx = .GetCustomListNum(LRR)  '取得清單位置序號
End With
 
With [工作表1!A3:F3].Resize(R - 2)
   .Select
   .Sort Key1:=.Item(6), Order1:=xlAscending, Header:=xlYes, _
      OrderCustom:=Lx + 1, MatchCase:=False, Orientation:=xlTopToBottom
End With
 
If Lm = 0 Then Application.DeleteCustomList ListNum:=Lx  '清單若是本次建立,刪除清單
End Sub



使用了這個方法確實可以順利的排序,
但只要按下存檔,整個EXCEL 就會當掉了....
看來似乎只能用GB版大 的手動資料排序了:Q
作者: sss1159    時間: 2015-11-12 16:14

HI ,玩一玩上述的公式又回來發問了:P

1.
Sub 篩選()
    Dim X$
    X = Application.InputBox("請輸入篩選關鍵字")
    If X = "" Or X = "False" Then Exit Sub
    With Sheets("工作表1").[A3]  '
        .Parent.AutoFilterMode = False
        
        .AutoFilter Field:=1, Criteria1:="*" & X & "*"
        If .End(xlDown).Row = Rows.Count Then MsgBox "找不到資料!!": Exit Sub
        .CurrentRegion.Sort Key1:=.Range("C3"), Order1:=xlAscending, Header:=xlYes
    End With
End Sub

原本搜尋的是第一欄 班級,若我想搜尋的是第四欄 性別
我該如何修改呢? 我數字都改過了><"


2.
Sub 搜尋()
Dim X$, R&, xSht As Worksheet, M, j&, Jm&, xH As Range
R = ActiveSheet.UsedRange.Rows.Count
If R > 5 Then Rows("6:" & R).Delete
X = Application.InputBox("請輸入搜尋關鍵字")
If X = "" Or X = "False" Then Exit Sub
For Each xSht In Sheets(Array("工作表1", "工作表3", "工作表4"))
    Set xH = Range(Array("A6", "I6", "P6")(M))
    M = M + 1: Jm = 0
    With xSht
          For j = 4 To .Cells(Rows.Count, 1).End(xlUp).Row
              If InStr(.Cells(j, 1) & .Cells(j, 2), X) Then
                  Jm = Jm + 1
                  .Cells(j, 1).Resize(1, 6).Copy xH(Jm)
              End If
          Next j
          If Jm = 0 Then MsgBox "〔" & .Name & "〕找不到〔" & X & "〕相關資料!!":
         
    End With
Next
End Sub

工作表2的搜尋 想增加另一種方式
不使用INPUTBOX ,直接改成 籃球或排球 兩種結果都搜尋出來
該如何修改呢


再麻煩指教,教導了,感謝再感謝
作者: 准提部林    時間: 2015-11-12 16:42

回復 27# sss1159


For j = 4 To .Cells(Rows.Count, 1).End(xlUp).Row
  If Instr("藍球排球", .Cells(j, 6)) Then
    Jm = Jm + 1
    .Cells(j, 1).Resize(1, 6).Copy xH(Jm)
  End If
Next j
作者: GBKEE    時間: 2015-11-13 06:18

本帖最後由 GBKEE 於 2015-11-13 06:25 編輯

回復 27# sss1159
  1. '最愛的運動=>F欄
  2.     .AutoFilter Field:=6, Criteria1:="=藍球", Operator:=xlOr, Criteria2:="=排球"
複製代碼
不知VBA程式碼如何編寫,可錄製巨集練習

[attach]22427[/attach]
作者: v03586    時間: 2015-11-14 10:45

請問VBA搜尋方式只能用篩選的嗎?
能不能像談出一個畫面 下面顯示你搜尋的關鍵字呢?




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