Office中国论坛/Access中国论坛

标题: [求助]有没有能提取表中一列的字符罗列在一个文本框中的函数? [打印本页]

作者: wang1950317    时间: 2006-5-13 07:50
标题: [求助]有没有能提取表中一列的字符罗列在一个文本框中的函数?
各位老师,有一个表:

姓名               第二列            第三列。。。。。

张三             XXXXXX       XXXX

李四

王五

周七

能否把[姓名]一列全部截取,并罗列在在报表或窗体的一个文本框中:

文本框:张三 李四 王五 周七

谢谢!
作者: 情比金坚    时间: 2006-5-13 08:18
  循环一下就出来了[attach]17717[/attach]

作者: wang1950317    时间: 2006-5-13 18:14
标题: 继续求教!
谢谢情比金坚老师,代码非常管用。但是还有一个问题,它好像针对一个表1 的,如果有多个不同名称的表(各表中均有[姓名]一列),在不同的窗体中都有一个文本框来截取不同表中[姓名]一列,是不是要各写一段代码?抑或可以写一个通用代码?请情比金坚老师继续指点!谢谢![attach]17723[/attach]

作者: LucasLynn    时间: 2006-5-13 18:28
以下是引用wang1950317在2006-5-13 10:14:00的发言:


谢谢情比金坚老师,代码非常管用。但是还有一个问题,它好像针对一个表1 的,如果有多个不同名称的表(各表中均有[姓名]一列),在不同的窗体中都有一个文本框来截取不同表中[姓名]一列,是不是要各写一段代码?抑或可以写一个通用代码?请情比金坚老师继续指点!谢谢![attach]17723[/attach]





把代码中的表名提取出来作为一个参数。
作者: wang1950317    时间: 2006-5-13 19:12
谢谢总版主老师的指点,您不知道小的对代码有多菜,还望您稍加改动,小的弄了半天也不得要领。还有假如表中要截取一列中有重复的(有时必须有重复内容),在文本框中不显示重复内容,只显示一次就可以了,是不是也在代码中设定,还是在文本框中设定。谢谢!谢谢!

Function allname()
    Dim d As Recordset
    Set d = CurrentDb.OpenRecordset("表1")
    d.MoveFirst
    Do While Not d.EOF
        allname = allname & "," & d(1)
        d.MoveNext
    Loop

End Function




[此贴子已经被作者于2006-5-13 11:32:51编辑过]


作者: LucasLynn    时间: 2006-5-13 19:43
以下是引用wang1950317在2006-5-13 11:12:00的发言:


谢谢总版主老师的指点,您不知道小的对代码有多菜,还望您稍加改动,小的弄了半天也不得要领。还有假如表中要截取一列中有重复的(有时必须有重复内容),在文本框中不显示重复内容,只显示一次就可以了,是不是也在代码中设定,还是在文本框中设定。谢谢!谢谢!

Function allname()
    Dim d As Recordset
    Set d = CurrentDb.OpenRecordset("表1")
    d.MoveFirst
    Do While Not d.EOF
        allname = allname & "," & d(1)
        d.MoveNext
    Loop

End Function





Function allname(tblName as String)
    Dim d As Recordset
    Set d = CurrentDb.OpenRecordset(tblName)
    d.MoveFirst
    Do While Not d.EOF
        allname = allname & "," & d(1)
        d.MoveNext
    Loop
End Function

作者: eyewitnes    时间: 2006-5-13 19:54
以下是引用LucasLynn在2006-5-13 11:43:00的发言:








Function allname(tblName as String)
    Dim d As Recordset
    Set d = CurrentDb.OpenRecordset(tblName)
    d.MoveFirst
    Do While Not d.EOF
        allname = allname & "," & d(1)
        d.MoveNext
    Loop
End Function

现在我比较习惯地在d.movefirst之前加句 if not d.eof then  , 以防止不必要的空数据集出错
作者: wang1950317    时间: 2006-5-13 20:15
楼上诸位老师都是"大家"啊!非常好!但是怎样解决重复的字符只显示一次呢?

姓名      xxx      cccc

张三

李四

张三

王五

显示:张三  李四  王五   (张三不管重复多少,只显示一次
作者: hi-wzj    时间: 2006-5-13 20:45
方法一:

    Do While Not d.EOF

if instr(allname,d(1))>0 then goto ww:
        allname = allname & "," & d(1)
        d.MoveNext

ww:
    Loop


方法二:先建立一个联合查询(用union而不是union all来联合)然后再用如上循环代码来读取。

[此贴子已经被作者于2006-5-13 12:46:28编辑过]


作者: wang1950317    时间: 2006-5-13 23:59
hi-wzj版主您好,是这样子吗,没有响应啊。我的嫁接错在哪里?

Function allname(tblName As String)
    Dim d As Recordset
    Set d = CurrentDb.OpenRecordset(tblName)
    d.MoveFirst

Do While Not d.EOF

If InStr(allname, d(1)) > 0 Then GoTo ww:
        allname = allname & "," & d(1)
        d.MoveNext

ww:
    Loop
End Function



作者: eyewitnes    时间: 2006-5-14 00:17
以下是引用wang1950317在2006-5-13 15:59:00的发言:


hi-wzj版主您好,是这样子吗,没有响应啊。我的嫁接错在哪里?

Function allname(tblName As String)
    Dim d As Recordset
    Set d = CurrentDb.OpenRecordset(tblName)
    d.MoveFirst

Do While Not d.EOF

If InStr(allname, d(1)) > 0 Then GoTo ww:
        allname = allname & "," & d(1)
        d.MoveNext

ww:
    Loop
End Function

只需要姓名这一列吗?如果是的话就改这里 set d = currentdb.openrecordset("select distinct 姓名from tblname")然后其他代码按原来的就好

[此贴子已经被作者于2006-5-13 16:18:13编辑过]


作者: fuyvn    时间: 2006-5-14 00:19
為什么不用   

recordset.GetString
作者: wang1950317    时间: 2006-5-14 00:43
改动 set d = currentdb.openrecordset("select distinct 姓名from tblname")提示运行错误“语法错误,(操作符丢失)在查询表达式:姓名。。。。。”

recordset.GetString如何用,请朋友指点,谢谢!
作者: LucasLynn    时间: 2006-5-14 01:04
以下是引用wang1950317在2006-5-13 16:43:00的发言:


改动 set d = currentdb.openrecordset("select distinct 姓名from tblname")提示运行错误“语法错误,(操作符丢失)在查询表达式:姓名。。。。。”

recordset.GetString如何用,请朋友指点,谢谢!



GetString 方法

将 [url=mkMSITStore:C:\Program%20Files\Common%20Files\Microsoft%20Shared\OFFICE11\2052\ado210.chm::/htm/mdobjodbrec.htm]Recordset[/url] 作为字符串返回。

语法Variant = recordset.GetString(<a href="" target="_blank" >StringFormat, <a href="" target="_blank" >NumRows, <a href="" target="_blank" >ColumnDelimiter, <a href="" target="_blank" >RowDelimiter, <a href="" target="_blank" >NullExpr)

返回值

Recordset 作为值为字符串的 Variant (BSTR) 返回。

参数

<DL>

<DT>StringFormat

<DD>[url=mkMSITStore:C:\Program%20Files\Common%20Files\Microsoft%20Shared\OFFICE11\2052\ado210.chm::/htm/mdcststringformatenum.htm]StringFormatEnum[/url] 值,指定将 Recordset 转换成字符串的方式。RowDelimiterClumnDelimiterNullExpr 参数只可同 adClipStringStringFormat 一起使用。

<DT>NumRows

<DD>可选。Recordset 中要转换的行数。如果未指定 NumRows,或者其值大于 Recordset 中的总行数,那么将转换 Recordset 中的所有行。

<DT>ColumnDelimiter

<DD>可选。如果指定了分隔符,在列之间使用该分隔符,否则使用 TAB 字符。

<DT>RowDelimiter

<DD>可选。如果指定了分隔符,在行之间使用该分隔符,否则使用 CARRIAGE RETURN 字符。

<DT>NullExpr

<DD>可选。如果指定了表达式,在 NULL 值处使用该表达式,否则使用空字符串。 </DD></DL>

说明

行数据(但没有模式数据)被保存在字符串中。因此不能使用此字符串重新打开 Recordset

此方法等价于 RDO GetClipString 方法。

请参阅

[url=mkMSITStore:C:\Program%20Files\Common%20Files\Microsoft%20Shared\OFFICE11\2052\ado210.chm::/htm/mdmthgetstringx.htm]Visual Basic 范例[/url]

适用于:Recordset 对象
作者: fuyvn    时间: 2006-5-14 01:04
姓名from

中間少了空格.

recordset.GetString    的祥細說明, 可在看  ADO 的幫助.
作者: wang1950317    时间: 2006-5-14 03:38


这段代码快接近了请各位老师继续帮忙。(按楼上朋友意见加上空格也不行。LucasLynn老师与fuyvn老师指点的GetString方法小的还没有一点认识,正在学习,请继续指教,多谢!)

Function allname(tblName As String)
    Dim d As Recordset
    Set d = CurrentDb.OpenRecordset(tblName)
    d.MoveFirst

Do While Not d.EOF

If InStr(allname, d(1)) > 0 Then GoTo ww:
        allname = allname & "," & d(1)
        d.MoveNext


ww:
    Loop
End Function
[attach]17737[/attach]


[此贴子已经被作者于2006-5-13 19:45:02编辑过]


作者: fan0217    时间: 2006-5-15 00:00
先用查询,查询唯一值,再通过循环取出.
作者: wang1950317    时间: 2006-5-15 00:49
标题: 继续
谢谢fan0217老师,但是如果截取对象是一个动态的查询表,该怎样办,提示错误呀?请费神浏览一下上传的文件,看看模块中需要怎样的改动才行。谢谢![attach]17746[/attach]

作者: wang1950317    时间: 2006-5-16 05:33
顶一下!请各位专家老师再指点,截取动态查询表为什么出错?


作者: sgrshh29    时间: 2006-5-16 14:52
以下是引用wang1950317在2006-5-15 21:33:00的发言:


顶一下!请各位专家老师再指点,截取动态查询表为什么出错?

因为你在查询1中的准则引用了窗体上的变量,在窗体没有成为当前窗体以前,这个变量无法传递到查询的准则中,所以记录集无法打开.
作者: wang1950317    时间: 2006-5-16 19:20
谢谢sgrshh29老师,那么怎样解决呢?请会做的老师们指教。
作者: sgrshh29    时间: 2006-5-16 22:34
供参考:[attach]17806[/attach]

作者: wang1950317    时间: 2006-5-17 00:38
谢谢sgrshh29老师。非常好。实际上这项功能是用在报表上并且隐藏的。不知把那个命令按钮中的代码放在报表"打开"事件中号不好用,我再慢慢按照您的上传文件试试吧。另外,重复的记录只显示一条不知是否有办法解决?谢谢,谢谢!
作者: sgrshh29    时间: 2006-5-17 04:30
什么叫做"重复的记录只显示一条"?不太明白.
作者: wang1950317    时间: 2006-5-17 06:24
如 :

编号      姓名      地址

A001      张三        。。。

A002      李四  

B005      张三

c001      王五

截取“姓名”一列为:  张三  李四  张三   王五

其中张三为重复,要求所有行中重复的字符串只出现一次,结果最好为:张三   李四  王五

谢谢!
作者: 情比金坚    时间: 2006-5-17 06:33
[attach]17820[/attach]

作者: fan0217    时间: 2006-5-17 06:58
删除List1行来源,使用以下代码即可:
Private Sub List1_AfterUpdate()
Dim d As Recordset
Dim strSQL As String
Dim strName As String

Me.RecordSource = " SELECT * FROM 表1 WHERE (((表1.编号)=[Forms]![窗体]![List1]));"
Me.child1.Form.RecordSource = "SELECT * FROM 结果1 WHERE (((IsNull(结果1.结果))=False)); "
Me.Requery

strSQL = "SELECT DISTINCT * FROM 表1 "
strSQL = strSQL & "WHERE 编号='" & Me.List1 & "';"

    Set d = CurrentDb.OpenRecordset(strSQL)
    If Not d.EOF Then
        d.MoveFirst
        
        Do While Not d.EOF
            strName = strName & d("姓名") & ","
            d.MoveNext
        Loop
        
        Me.Text8 = Left(strName, Len(strName) - 1)
    End If

d.Close

End Sub


[此贴子已经被作者于2006-5-16 23:01:39编辑过]


作者: wang1950317    时间: 2006-5-17 18:41
多次得到过两位版主的热心指教,感激不尽!现在将实验结果向两位老师汇报:

情版主的方法使用很好,可以用于多个窗体指定截取不同的表(如在窗体1的一个文本框中截取表1中的一列,在窗体2中的文本框中截取表5中的一列,直接输入allname("",""))而且在报表中使用是一样的,但是对于截取有变量的查询表(查询1)重复值只保留一个还没能达到。期待情版主有空闲再指教!

fan0217版主的方法小的还没有弄懂,按照代码的意思把它放在List1更新后事件中,单击List1中的编号出现错误提示:

运行时错误 '-2147352567   (80020009)':您不能将数值指定给这个对象        按调试后转到代码:

Me.Text8 = Left(strName, Len(strName) - 1)    (Text8是控件来源为=allname("表1")的文本框)

请fan0217版主再指教!

[此贴子已经被作者于2006-5-17 14:10:25编辑过]


作者: 情比金坚    时间: 2006-5-18 02:32



[attach]17842[/attach]
Function allname(tblName As String, fieldname As String, Optional criteria As String = "")
    Dim d As Recordset
    Dim sqlstr As String
    Dim cristr As String
    If criteria = "" Then
        cristr = ""
    Else
        cristr = " where " & criteria
    End If
    sqlstr = "select " & fieldname & " from " & tblName & cristr & " GROUP BY " & fieldname
    Set d = CurrentDb.OpenRecordset(sqlstr)
    If Not d.EOF Then
    d.MoveFirst
   
    Do While Not d.EOF
        allname = allname & "," & d(0)
        d.MoveNext
    Loop
    End If
End Function

[此贴子已经被作者于2006-5-17 18:33:32编辑过]


作者: fan0217    时间: 2006-5-18 04:27
删除List1行来源
作者: wang1950317    时间: 2006-5-18 04:38
谢谢情版主不厌其烦的费心指教。小的在此鞠躬致谢。基本上可以迂回使用了。但如要直接从有变量的查询表上截取一列,还是有困难的。因为我所要的有一大部分是这种情况。[attach]17844[/attach]

作者: wuaza    时间: 2006-5-18 04:55
不知道在VBA(dao、ado)中怎样传递参数查询中的参数?
作者: 情比金坚    时间: 2006-5-18 07:54
一时没有好办法,因为你的查询是调用窗体的参数,所以无法在窗体变动时打开查询,要不你在窗体打开后用一个事件来给文本框赋值吧
作者: wang1950317    时间: 2006-5-18 18:44
谢谢啦!按道理说窗体打开单击列表框中的编号,数据就传递到了查询表,只要窗体不关,查询表中得数据始终是存在的。唉,情版主说一时没有好办法那就是没有好办法了。“窗体打开后用一个事件来给文本框赋值”如何操作?请版主帮忙帮到底吧,小的天天在这个网站上溜达,但基础差又太笨,没有多大长进,真是麻烦各位老大了。谢谢!
作者: andymark    时间: 2006-5-18 19:18
把查询中的条件去掉

[attach]17852[/attach]

作者: fan0217    时间: 2006-5-18 19:24
删除List1行来源,使用以下代码即可:
Private Sub List1_AfterUpdate()
Dim d As Recordset
Dim strSQL As String
Dim strName As String

Me.RecordSource = " SELECT * FROM 表1 WHERE (((表1.编号)=[Forms]![窗体]![List1]));"


Me.child1.Form.RecordSource = "SELECT * FROM 结果1 WHERE (((IsNull(结果1.结果))=False)); "


Me.RequerystrSQL = "SELECT DISTINCT * FROM 表1 "


strSQL = strSQL & "WHERE 编号='" & Me.List1 & "';"    Set d = CurrentDb.OpenRecordset(strSQL)


    If Not d.EOF Then


        d.MoveFirst


        


        Do While Not d.EOF


            strName = strName & d("姓名") & ","


            d.MoveNext


        Loop


        


        Me.Text8 = Left(strName, Len(strName) - 1)


    End Ifd.CloseEnd Sub
作者: wang1950317    时间: 2006-5-19 00:29
标题: 继续求救
andymark大侠的方法试了一下还没有发现出错。但是套用到工作模式中弄不清哪儿有出错了。请ndymark大侠费心再看一看。谢谢您!


fan0217版主的代码放进去后提示:方法和数据成员未找到。.RequerystrSQL =     


菜鸟对代码很不像样,就不知该怎样做下去了。谢谢版主劳心![attach]17870[/attach]



[此贴子已经被作者于2006-5-18 16:33:51编辑过]


作者: andymark    时间: 2006-5-19 00:43
把查询1中的条件 [forms]![窗体]![编号]  这句不要就可以了

上面我都提到了,你还是没看清

   
作者: fan0217    时间: 2006-5-19 02:58
发表时把空格和回车搞丢了,查看以下代码:







删除List1行来源,使用以下代码即可:

Private Sub List1_AfterUpdate()
Dim d As Recordset
Dim strSQL As String
Dim strName As String

Me.RecordSource = " SELECT * FROM 表1 WHERE (((表1.编号)=[Forms]![窗体]![List1]));"


Me.child1.Form.RecordSource = "SELECT * FROM 结果1 WHERE (((IsNull(结果1.结果))=False)); "


Me.Requery


strSQL = "SELECT DISTINCT * FROM 表1 "


strSQL = strSQL & "WHERE 编号='" & Me.List1 & "';"


  Set d = CurrentDb.OpenRecordset(strSQL)


    If Not d.EOF Then


        d.MoveFirst


          Do While Not d.EOF


            strName = strName & d("姓名") & ","


            d.MoveNext


        Loop


          Me.Text8 = Left(strName, Len(strName) - 1)


   End If


d.Close


End Sub
作者: wang1950317    时间: 2006-5-19 07:30
谢谢andymark大侠,没有弄懂您前面说的意思,现在按您的指点删除了查询的条件,一切如愿。没有了限制条件虽然把所有表中的项目都显示在查询中,但是我们的目的达到了,就不管其他的了。好像听说查询并不占多少空间?谢谢您!


也非常感谢fan0217版主的耐心指教。版主的代码同样也要删除查询1的条件,并且和列表框中的原有代码合并,窗体中的代码也免了,比较紧凑。但重复字符还是都显示,可能我在有些设置上还有问题,待我慢慢查一查。谢谢!


在这个帖子基本完成预定目的之际,也要感谢情比金坚版主完成的在固定表中截取。感谢LucasLynn   hi-wzj版主及sgrshh29大侠帮助。谢谢大家!我不太懂VB 但常把Access当作游戏来玩,我感到只要你能提出问题,Access几乎没有办不到的。这也是Access的魅力所在。谢谢!
作者: REORX    时间: 2008-3-4 16:35
先顶在下..........
作者: REORX    时间: 2008-3-4 16:36
一顶到底.............




欢迎光临 Office中国论坛/Access中国论坛 (http://www.office-cn.net/) Powered by Discuz! X3.3