Access交流中心

北京 | 上海 | 天津 | 重庆 | 广州 | 深圳 | 珠海 | 汕头 | 佛山 | 中山 | 东莞 | 南京 | 苏州 | 无锡 | 常州 | 南通 | 扬州 | 徐州 | 杭州 | 温州 | 宁波 | 台州 | 福州 | 厦门 | 泉州 | 龙岩 | 合肥 | 芜湖 | 成都 | 遂宁 | 长沙 | 株洲 | 湘潭 | 武汉 | 南昌 | 济南 | 青岛 | 烟台 | 潍坊 | 淄博 | 济宁 | 太原 | 郑州 | 石家庄 | 保定 | 唐山 | 西安 | 大连 | 沈阳 | 长春 | 昆明 | 兰州 | 哈尔滨 | 佳木斯 | 南宁 | 桂林 | 海口 | 贵阳 | 西宁 | 乌鲁木齐 | 包头 |

FIND 记录定位如何使用?

pc高手  发表于:2008-03-04 09:50:23  
复制

【tbl合同】 : 合同表里的字段:
合同号,身份证号,姓名

    Dim rs As ADODB.Recordset
    Set rs = New ADODB.Recordset
    rs.ActiveConnection = CurrentProject.Connection
    rs.Open "tbl合同", , adOpenKeyset, adLockOptimistic

    strNAME = "王红" 
    strSFZH="220102198010182835" 

    rs.find ....... .:这个句子如何写?

    要求: 用已知 strSFZH 身份证号 在 【tbl合同】表里面找到这条记录, 并将 姓名
           改为 strNAME (王红)。

类似的问题,我一直是用其他方法解决,自认为不是最佳方法, 所以要探讨一下类似 “FIND"
的用法。  我理解是: ACCESS 里的对于记录的操作远远没有 Foxpro (或 VFP) 操作方便,
没有那么得心应手。 VFP 里的 FIND , SEEK 对于记录的定位,字段的替换,特别是整条记录
的内存变量的记忆,然后将整条记录添加为新纪录(SCAT TO XXX , APPE BLAN ,GATH FROM XXX),
更是好用。
请教, 在 ACCESS 中是否也有类似的用法。  在 ACCESS 中, help 里的内容实在令人感觉不爽,
不够用, 不够详尽,很多基本用法都没有。  而且许多书中也不介绍详尽的用法, 只能靠自己去
摸索,去思考。
请高手指教!
park05@sina.com

 

 

Top
钱玉炜 发表于:2008-03-04 11:04:43

如果对find使用方法有疑问,可以考虑在rs.Open "tbl合同", , adOpenKeyset, adLockOptimistic这里就打开需要的记录

如按照你的要求可以改成  

dim strsql as string

strsql="select strNAME from tbl合同 where strSFZH="220102198010182835" "

rs.Open strsql, adOpenKeyset, adLockOptimistic

rst("strname")="王红"

rst.update

rst.close



钱玉炜 发表于:2008-03-04 11:04:59
就是麻烦了一点

pc高手 发表于:2008-03-04 13:47:18


pc高手 发表于:2008-03-04 13:48:08


pc高手 发表于:2008-03-04 13:50:02

谢谢钱玉伟指点。   由于文字太多, 分开两次上传!

我的实际程序如下:

Private Sub cmd导入到合同表_Click()
On Error GoTo ErrA
    ''' 1: [tblGZZDM合同] [ rsA. ] [ strZDM ] 【44条记录】
    Dim rsA As ADODB.Recordset
    Set rsA = New ADODB.Recordset
    rsA.ActiveConnection = CurrentProject.Connection
    rsA.Open strZDM, , adOpenKeyset, adLockOptimistic
    intZDS = rsA.RecordCount    ''' 字段个数,循环变量

    Dim BZ(Myint) As String     ''' 标准字段名 默认 200
    Dim I As Integer
    I = 0
    Dim str勾否 As String
    Dim strSCZDM As String    ''' 生成表的字段名
    DoCmd.Hourglass True        ''''开始沙漏 !!!
    Do While Not rsA.EOF
        If rsA.Fields("是否导入") = -1 Then
            str勾否 = "y"
            I = I + 1
            BZ(I) = rsA.Fields("标准表字段名")
        End If
        rsA.MoveNext
    Loop


    ''' 将 strLSB=【tblLSB合同】: 逐条导入到 【tbl合同】中,逐条检验【tbl合同】里是否已经存在该记录。
    Dim rsLSB As ADODB.Recordset   ''' 【tblLSB合同】
    Dim rsHT As ADODB.Recordset   ''' 【tbl合同】
    Set rsLSB = New ADODB.Recordset
    Set rsHT = New ADODB.Recordset
    rsLSB.Open strLSB, CurrentProject.Connection, adOpenKeyset, adLockOptimistic
    rsHT.Open "tbl合同", CurrentProject.Connection, adOpenKeyset, adLockOptimistic

    Dim strSFZH As String
    Dim J As Integer
    Dim K As Integer
    Dim N As Integer
    Dim YesNo As String
    N = 0       '''  I , N 都是:字段的个数 (不定,随用户需求变化)
    J = 0       ''' 成功
    K = 0       ''' 不成功
    DoCmd.Hourglass True    ''' 沙漏开始显示
       



pc高手 发表于:2008-03-04 13:50:39
    Do While Not rsLSB.EOF    ''' 导入数据的来源表 (经过整理过的临时表,就是最后的数据)
        strSFZH = rsLSB.Fields("身份证号")
        YesNo = "N"           ''' 在合同表中是否找到身份证号
        rsHT.MoveFirst       ''' 每次循环,都记录置顶,从头查!
        Do While Not rsHT.EOF     ''' 在目标表中逐条记录查找身份证号符合条件的记录。
            If rsHT.Fields("身份证号") = strSFZH Then
                YesNo = "Y"
                N = 0
                Do While N < I      ''' 逐个字段导入, 横向走。 每个字段逐个更新。
                    N = N + 1       ''' 如果需要判断字段类型是否能导入, 就在这里加判断句子
                    If Len(rsLSB.Fields(BZ(N))) = 0 Then
                 ''' *** IF 来源字段的值是STR,并长度=0,就不update。if 是数字、日期型,无论空否,不影响判断。 if “是否”型,并BZ(N)是文本型,就=“-1,0”。
                    Else
                        rsHT.Fields(BZ(N)) = rsLSB.Fields(BZ(N))  
                    End If
                Loop
                rsHT.Update
                Exit Do
            Else    '''没有找到
                rsHT.MoveNext
            End If
        Loop
        If YesNo = "Y" Then
            J = J + 1    ''' 找到 + 1
            rsLSB.Fields("导入报告") = "YES"
        Else
            K = K + 1 ''' 没找到 +1
            rsLSB.Fields("导入报告") = "NO"
        End If
        rsLSB.Update
        DoCmd.echo False, "正在逐人计算,请等待! 身份证号:" & Left(strSFZH & "    ", 20) & "    不成功计数: " & K & "  成功计数:" & J
        rsLSB.MoveNext
    Loop
    DoCmd.Hourglass False
    DoCmd.echo True
    MsgBox "数据导入完毕!" & Chr(10) & Chr(10) & "已经成功导入到合同表中:" & J & " 条记录!" & _
    Chr(10) & Chr(10) & "不成功的有:" & K & " 条记录!" & Chr(10) & Chr(10) & "一共搜索了:" & J + K & " 条记录!" _
    , vbInformation, "一般提示:"
    rsLSB.Close
    rsHT.Close

ExitA:
    Exit Sub
ErrA:
    Select Case Err.Number
    Case 13
        MsgBox strSFZH & ":要导入的数据不符合要求!", vbExclamation, "错误提示:需要检查一下!"
        Resume Next
    Case Else
        MsgBox Me.Name & "," & Me.cmd导入到合同表.Name & ": NO." & Err.Number & "," & Err.Description
        Call KH.myErrLog(Err.Number, Err.Description, Me.Name, Me.cmd导入到合同表.Name)
    End Select
    DoCmd.Hourglass False
    DoCmd.echo True
    rsLSB.Close
    rsHT.Close
    Resume ExitA
End Sub


**************
上述的过程, 是从整个模块中摘取的, 可能变量不全, 不要管他。 只看核心语句:
如果在     Do While Not rsHT.EOF  这层循环中,用 FIND 定位 并能对字段值操作,
就是正确的处理方式,速度就快多了。
现在, 我的程序就是按上述运行, 没有问题,但是觉得不是正确的方法!
钱玉伟的方法仅适用于一条记录的查找和更新, 我现在的要求是多条记录循环查找
和更新。 实际记录是 6000条对10000条记录的查找和更新。
请高手指教。


 



pc高手 发表于:2008-03-04 14:34:20

那段程序, 我刚刚改成功了! 达到我预期的目标。 这才是真正的程序, 正确的思路,正确的方法!

        rsHT.Find "身份证号=" & strSFZH, , adSearchForward, 1
        If rsHT.EOF Then    '''没有找到
            K = K + 1 ''' 没找到 +1
            rsLSB.Fields("导入报告") = "NO"
        Else
            N = 0
            Do While N < I      ''' 逐个字段导入, 横向走
            N = N + 1       ''' 如果需要判断字段类型是否能导入, 就在这里加判断句子
               If Len(rsLSB.Fields(BZ(N))) = 0 Then
                ''' *** IF 来源字段的值是STR,并长度=0,就不update。if 是数字、日期型,无论空否,不影响判断。 if “是否”型,并BZ(N)是文本型,就=“-1,0”。
               Else
                   rsHT.Fields(BZ(N)) = rsLSB.Fields(BZ(N))   ''' 判断后,就不会出错了!
               End If
            Loop
            rsHT.Update
            J = J + 1    ''' 找到 + 1
            rsLSB.Fields("导入报告") = "YES"
        End If



pc高手 发表于:2008-03-04 14:39:51

这个问题完美地解决了,  如同 VFP 里的 seek 的记录定位 , 找到后立即就可以

进行各个字段的更新了。

 

但是还是没有将这一类的问题彻底解决!

也就是: 类似 VFP 里的 SCAT TO XXX , APPE BLAN , GATH FROM XXX.

在 ACCESS 是否也可以找到类似的用法。

 

 



pc高手 发表于:2008-03-04 15:57:52

运行结果:


7000 条记录(rsLSB.) 逐条记录 到 目标表(rsHT.) 7000 条记录 查找

7000 X 7000 次周期查找, 速度:

1. 用 FIND : 179 秒。

2. 双层循环: 339 秒

虽然 FIND 快的多, 速度上看, 还是不理想!



总记录:9篇  页次:1/1 9 1 :