Userform度用keyword搜ws的資料放係listbox的方法

Alex Chan 0 信譽點數
2026-09-17T04:23:26.1133333+00:00

我試過呢個唔太work

Option Explicit

Private Sub SearchRecords()

Dim ws As Worksheet

Dim lastRow As Long

Dim dataArr As Variant

Dim resultArr() As Variant

Dim i As Long, j As Long, matchCount As Long

Dim searchKey As String

Dim tempDate As Variant, tempDetail As Variant



On Error GoTo ErrorHandler



' 1. 取得關鍵字

searchKey = Trim(Me.FileNo.Text)

If searchKey = "" Then

    Me.ListBox1.Clear

    Exit Sub

End If



' 2. 指定工作表

Set ws = ThisWorkbook.Worksheets("past")

lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

If lastRow < 2 Then

    Me.ListBox1.Clear

    Exit Sub

End If



' 3. 讀入記憶體陣列加速處理

dataArr = ws.Range("A2:C" & lastRow).Value



' 4. 設定 ListBox 格式:只顯示 2 欄 (Col A 日期時間, Col C Detail)

With Me.ListBox1

    .Clear

    .ColumnCount = 2

    .ColumnWidths = "120 pt;250 pt" ' 依畫面寬度自行微調

End With



' 5. 篩選完全吻合的記錄

ReDim resultArr(1 To 2, 1 To UBound(dataArr, 1))

matchCount = 0



For i = 1 To UBound(dataArr, 1)

    ' StrComp = 0 代表文字完全一致(vbTextCompare 忽略大小寫;如需分大小寫請改用 vbBinaryCompare)

    If StrComp(Trim(CStr(dataArr(i, 2))), searchKey, vbTextCompare) = 0 Then

        matchCount = matchCount + 1

        resultArr(1, matchCount) = dataArr(i, 1) ' 日期時間

        resultArr(2, matchCount) = dataArr(i, 3) ' Detail

    End If

Next i



' 若無匹配記錄則結束

If matchCount = 0 Then Exit Sub



' 縮減陣列至實際筆數

ReDim Preserve resultArr(1 To 2, 1 To matchCount)



' 6. 依日期時間由新到舊排序(Bubble Sort,適合清單資料量)

If matchCount > 1 Then

    For i = 1 To matchCount - 1

        For j = i + 1 To matchCount

            ' 如果後面的時間比前面新,就對調

            If CDate(resultArr(1, j)) > CDate(resultArr(1, i)) Then

                tempDate = resultArr(1, i)

                tempDetail = resultArr(2, i)

                

                resultArr(1, i) = resultArr(1, j)

                resultArr(2, i) = resultArr(2, j)

                

                resultArr(1, j) = tempDate

                resultArr(2, j) = tempDetail

            End If

        Next j

    Next i

End If



' 7. 填入 ListBox

For i = 1 To matchCount

    With Me.ListBox1

        .AddItem Format(resultArr(1, i), "yyyy-mm-dd hh:mm") ' 格式化時間

        .List(i - 1, 1) = CStr(resultArr(2, i))              ' Detail

    End With

Next i



Exit Sub

ErrorHandler:

MsgBox "搜尋處理時發生錯誤:" & Err.Description, vbCritical, "錯誤"

End Sub

Microsoft 365 與 Office | Excel | 家用版 | Windows
0 則留言 沒有留言

1 個回答

排序依據: 最實用
  1. Lychee-Ng 30,400 信譽點數 Microsoft 外部員工 仲裁者
    2026-09-17T08:52:11.48+00:00

    此答案已自動翻譯。因此,可能會出現語法錯誤或措詞不當的情況。


    我理解您的整體思路,Alex Chan,方法似乎也可行。

    但首先有一個重要問題需要確認:您​​所說的「關鍵字搜尋」是什麼意思?因為您目前的程式碼並沒有執行關鍵字/包含搜尋。這行程式碼只接受精確比對:

    If StrComp(Trim(CStr(dataArr(i, 2))), searchKey, vbTextCompare) = 0 Then
    

    例如,如果 B 列包含 ABC-12345,則搜尋 12345 將不會傳回任何結果。因此,如果您希望 FileNo 作為針對 B 列的關鍵字搜索,請改用 InStr:

    If InStr(1, CStr(dataArr(i, 2)), searchKey, vbTextCompare) > 0 Then
    

    基本上,請查看現有程式碼中的這部分:

    For i = 1 To UBound(dataArr, 1)
        ' StrComp = 0 代表文字完全一致(vbTextCompare 忽略大小寫;如需分大小寫請改用 vbBinaryCompare)
        If StrComp(Trim(CStr(dataArr(i, 2))), searchKey, vbTextCompare) = 0 Then
            matchCount = matchCount + 1
            resultArr(1, matchCount) = dataArr(i, 1) ' 日期時間
            resultArr(2, matchCount) = dataArr(i, 3) ' Detail
        End If
    

    替換該過濾部分使用以下程式碼:

    For i = 1 To UBound(dataArr, 1)
        If InStr(1, CStr(dataArr(i, 2)), searchKey, vbTextCompare) > 0 Then
            matchCount = matchCount + 1
            resultArr(1, matchCount) = dataArr(i, 1) ' 日期時間
            resultArr(2, matchCount) = dataArr(i, 3) ' Detail
        End If
    
    

    如果您希望 FileNo 與 B 列中的整個值完全匹配,那麼您最初的 StrComp(...)=0 條件已經是正確的方法。在這種情況下,請詳細描述您執行程式碼時發生的情況,例如沒有結果、結果不正確或出現特定的 VBA 錯誤訊息。

    此回答有幫助嗎?


您的回答

答案可由問題作者標示為「已接受」,而由仲裁者標示為「推薦」,這可協助使用者知道答案解決了作者的問題。