You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DataGrid如何实现搜索跳转目标记录且保留全量数据供浏览

核心问题排查

你现有代码无法实现需求的原因有3个:

  1. SQL逻辑完全错误:WHERE IDSIZE <> 输入值的写法会直接把和输入尺寸相等的记录排除出查询结果,和「保留全部记录」的需求完全相反。
  2. 缺失定位逻辑:数据加载排序后没有任何跳转选中目标行的代码,控件默认会从第一行开始显示。
  3. 资源释放逻辑有缺陷:数据库连接关闭逻辑写在Try块中,一旦查询中途报错,连接会一直占用无法释放。
实现代码

推荐优先用「首次加载全量数据+本地定位」的方案,不需要每次搜索都查库,响应速度更快。

方案1:本地定位(推荐)

首先在窗体加载时拉取全量数据并按尺寸升序排列,后续搜索直接在已加载的行中匹配定位:

' 窗体级数据库连接对象,连接字符串建议存放在配置文件中,不要硬编码
Private conn As New OleDb.OleDbConnection("你的数据库连接字符串")

Private Sub Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ' 初始化加载全量模具数据
    LoadAllDieRecords()
End Sub

''' <summary>
''' 加载全量模具数据,按IDSIZE升序排列
''' </summary>
Private Sub LoadAllDieRecords()
    Try
        DataGridRecords.Rows.Clear()
        conn.Open()
        ' 直接查询全量数据,在数据库端完成排序,性能优于客户端排序
        Dim cmd As New OleDb.OleDbCommand("SELECT * FROM tblDies ORDER BY IDSIZE ASC", conn)
        Dim dr = cmd.ExecuteReader()
        While dr.Read()
            DataGridRecords.Rows.Add(
                dr.Item("ID"), dr.Item("DIENUMBER"), dr.Item("DESCRIPT"), dr.Item("OLDNUMBER"),
                dr.Item("CODE"), dr.Item("QUANTITY"), dr.Item("IDSIZE"), dr.Item("ODSIZE"),
                dr.Item("HEIGHT"), dr.Item("FLANGE HT"), dr.Item("FLANGE DIA"), dr.Item("CuRef"),
                dr.Item("CUTEL"), dr.Item("CuContact"), dr.Item("Price-selling"), dr.Item("P/no"),
                dr.Item("Stoksize"), dr.Item("Material"), dr.Item("Shore"), dr.Item("DieChkd"),
                dr.Item("DIECOST"), dr.Item("DATE"), dr.Item("REMARKS"), dr.Item("PRREF")
            )
        End While
        dr.Close()
    Catch ex As Exception
        MsgBox(ex.Message)
    Finally
        ' 无论查询是否报错,都确保连接关闭释放
        If conn.State = ConnectionState.Open Then conn.Close()
    End Try
End Sub

''' <summary>
''' 搜索按钮点击事件,定位到目标尺寸行
''' </summary>
Private Sub btnSearch_Click(sender As Object, e As EventArgs) Handles btnSearch.Click
    ' 校验输入是否为合法数值
    Dim targetSize As Decimal
    If Not Decimal.TryParse(txtIdSize.Text.Trim(), targetSize) Then
        MsgBox("请输入有效的尺寸数值")
        txtIdSize.Focus()
        Return
    End If

    DataGridRecords.ClearSelection()
    Dim targetRowIndex As Integer = -1

    ' 遍历所有行,因为数据已经按升序排列,第一个IDSIZE>=目标值的行就是要定位的行
    For Each row As DataGridViewRow In DataGridRecords.Rows
        If row.IsNewRow Then Continue For ' 跳过DataGridView的新增空白行
        Dim currentSize As Decimal
        If Decimal.TryParse(row.Cells(6).Value?.ToString(), currentSize) AndAlso currentSize >= targetSize Then
            targetRowIndex = row.Index
            Exit For
        End If
    Next

    If targetRowIndex >= 0 Then
        ' 选中目标行,同时滚动到可视区域
        DataGridRecords.Rows(targetRowIndex).Selected = True
        DataGridRecords.FirstDisplayedScrollingRowIndex = targetRowIndex
    Else
        MsgBox("未找到大于等于输入尺寸的记录")
    End If
End Sub

方案2:每次搜索重新拉取全量数据后定位

如果业务要求每次搜索必须同步数据库最新数据,可以直接修改原有search过程,去掉错误的过滤条件,加载完成后追加定位逻辑:

Sub search()
    Dim targetSize As Decimal
    If Not Decimal.TryParse(txtIdSize.Text.Trim(), targetSize) Then
        MsgBox("请输入有效的尺寸数值")
        Return
    End If

    Try
        DataGridRecords.Rows.Clear()
        conn.Open()
        ' 移除错误的WHERE条件,查询全量数据并在数据库端排序
        Dim cmd As New OleDb.OleDbCommand("SELECT * FROM tblDies ORDER BY IDSIZE ASC", conn)
        dr = cmd.ExecuteReader
        While dr.Read
            DataGridRecords.Rows.Add(
                dr.Item("ID"), dr.Item("DIENUMBER"), dr.Item("DESCRIPT"), dr.Item("OLDNUMBER"),
                dr.Item("CODE"), dr.Item("QUANTITY"), dr.Item("IDSIZE"), dr.Item("ODSIZE"),
                dr.Item("HEIGHT"), dr.Item("FLANGE HT"), dr.Item("FLANGE DIA"), dr.Item("CuRef"),
                dr.Item("CUTEL"), dr.Item("CuContact"), dr.Item("Price-selling"), dr.Item("P/no"),
                dr.Item("Stoksize"), dr.Item("Material"), dr.Item("Shore"), dr.Item("DieChkd"),
                dr.Item("DIECOST"), dr.Item("DATE"), dr.Item("REMARKS"), dr.Item("PRREF")
            )
        End While
        dr.Close()

        ' 追加定位逻辑
        DataGridRecords.ClearSelection()
        Dim targetRowIndex As Integer = -1
        For Each row As DataGridViewRow In DataGridRecords.Rows
            If row.IsNewRow Then Continue For
            Dim currentSize As Decimal
            If Decimal.TryParse(row.Cells(6).Value?.ToString(), currentSize) AndAlso currentSize >= targetSize Then
                targetRowIndex = row.Index
                Exit For
            End If
        Next

        If targetRowIndex >= 0 Then
            DataGridRecords.Rows(targetRowIndex).Selected = True
            DataGridRecords.FirstDisplayedScrollingRowIndex = targetRowIndex
        Else
            MsgBox("未找到大于等于输入尺寸的记录")
        End If

    Catch ex As Exception
        MsgBox(ex.Message)
    Finally
        If conn.State = ConnectionState.Open Then conn.Close()
    End Try
End Sub
关键说明
  • 定位功能核心依赖DataGridView的FirstDisplayedScrollingRowIndex属性,设置该属性可以直接控制控件滚动到对应行索引的位置,配合Selected属性选中行即可实现不筛选数据的跳转定位效果。
  • 不建议使用字符串拼接方式构造SQL语句,后续如果需要增加查询条件,优先使用参数化查询,避免特殊字符引发SQL错误或注入风险。
  • 尺寸字段判断用>=匹配,刚好符合「有精确值就定位到精确值,没有就定位到第一个比输入值大的记录」的需求。

内容的提问来源于stack exchange,提问作者Lloyd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 15:30:05