本文介绍了DAO的包装!好吧,差不多......的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

致全部,


首先,您对我的一些回复已通过

DevelopersDex发布,而这些回复并未在USENET上发布给全世界到

见。 DevelopersDex似乎试图劫持USENET,尽管有一些更好的解释可能会让我失望。如果您希望

世界看到您的回复,那么您应该将它们直接发布到

USENET。但是,无论哪种方式,我都会看到它们。


经过多年的DAO挫折之后,我突然意识到它可能会写出一个可能的b $ b DAO的合理包装可以隐藏乱七八糟的东西!我做了

就是这样并将其附在下面。它对我的

应用程序来说已经足够了,但修复剩余的问题会有很多帮助。


这些问题在其中的评论中有所解释。它们大多与
有关,需要与OpenRecordset方法进行交互。显然,

OpenRecordset不以任何合理/经典方式处理任何

的可选参数。如果参数本身从包装器传递为

可选,则可能需要对所有可能的大量OpenRecordset用法进行编码



参数组合。然后,有一个问题是什么把

放入你不关心的论证中,但是哪一个你希望包含的论证是什么。显然必须说明这些,

但是为了说明问题的深度,第一个论点是

类型。参数,默认为各种值取决于各种各样的b / b
记录不佳的事情。哎呀,我想我刚刚介入了一些我试图隐藏的东西!


基本上,如果我能让这个工作顺利进行,这提供了一个

经典VB(不是VBA)文件般的界面,同时暴露了

记录集对象的随机定位,EOF检测和其他

重要的东西。


注意,运行的小测试例程就足够了,但

不足以识别vbReadOnly选项。


请保留所有改进建议。

...................... ..........


''modDAOinterface是Coypright? 2004年The Richfield Family

''保留所有权利。


选项比较文字

选项明确

选项基础1


Const MaxFiles = 10

Const MaxFields = 10

Dim QueryOpen(MaxFiles) )作为布尔''它是否已被打开?

Public QueryFile(MaxFiles)As Recordset''记录集。

Dim FieldName $(MaxFiles,MaxFields)''字段名称

ParamArry Args。

Dim db(MaxFiles)作为数据库

Dim qry(MaxFiles)作为QueryDef

Dim tbl(MaxFiles)As TableDef


''查询和子表单在Access中是非常奇怪的东西,通常

决定不

''评估字段或计算表达式,除非它们在

''屏幕上显示

或用于修改其他数据库对象。

''这使得一把猴子扳手变成了复杂的功能,并带来了有益的功能/>
side

''对数据库引擎可能不明显的影响。

''为了解决这个问题,这些简单的例程已经实现为

读取一个

''查询或表,好像它是一个顺序文件。

''这强迫哑巴读取和评估所有内容的操作。


Sub OpenQuery(QueryName $,File#,可选数据库作为变体,_

可选模式作为变体,可选访问作为Variant,_

可选锁定为变体,可选SQL为变体,_

可选字段为变体)


''模式,访问和锁定等待更多信息

OpenRecordset。


Dim Arg& ''考虑的数量是



Dim FieldNum& ''字段的序数。

Dim RetVal As Variant


出错时GoTo Error_Handler


如果是QueryOpen (文件#)然后_

调用CloseQuery(文件#)


如果IsMissing(数据库)那么

设置db(文件#)= CurrentDb()

否则

设置db(文件#)= OpenDatabase(CStr(数据库))

结束如果


错误GoTo TryTable

''以下似乎不适用于Jet MDB。

设置qry(文件#) = db(File#)。QueryDefs(QueryName $)


On Error GoTo Error_Handler


''输入:= Mode,Options:= Access,LockEdit:= Locks

如果IsMissing(SQL)那么

''以下行需要至少一个数字操作。

''以下行给出错误3210无效操作。

设置QueryFile(文件#)= qry(文件#).OpenRecordset(dbOpenTable)

否则

设置QueryFile(文件#)= qry(文件#)。OpenRecordset(CStr(SQL))

结束如果

GoTo GotIt


TryTable:

恢复NextLine


NextLine:

错误GoTo Error_Handler

设置tbl(文件#)= db(文件#)。TableDefs(QueryName $)


''以下OpenRecordset的参数似乎不起作用。

''(类型:=模式,选项:= Access,LockEdits:= Locks)

如果是IsMissing(SQL)那么

设置QueryFile(文件#)= tbl(文件#).OpenRecordset

否则

设置QueryFile(文件#)= tbl(文件#).OpenRecordset(CStr(SQL))

结束如果


GotIt:


''吮吸字段名称。


FieldNum& = 0

对于Arg& = LBound(Fields)到UBound(Fields)

FieldNum& = FieldNum& + 1

FieldName $(File#,FieldNum&)=字段(Arg&)

''以下简单地在此处验证字段名称。

如果不是QueryFile(文件#).EOF那么_

RetVal = QueryFile(文件#)。字段(FieldName $(文件#,

FieldNum&) )

下一个Arg&


QueryOpen(文件#)=真


退出子


Error_Handler:

如果Error_Handler(" OpenQuery",Err)= acDataErrDisplay那么

错误转到0


停止:恢复''按两次[F8]查看问题。


结束如果


End Sub


Sub ReadQuery(File#,ParamArray Fields()As Variant)


''在打电话之前总是测试EOF,使用:

''如果QueryFile(1#)。EOF那么

''调用CloseQuery(1#)


Dim Arg&

Dim FieldNum& ''该字段的序数。


出错时GoTo Error_Handler


如果不是QueryOpen(文件#)那么

调用CloseQuery(文件#)

错误17

结束如果


FieldNum& = 0

对于Arg& = LBound(Fields)到UBound(Fields)

FieldNum& = FieldNum& + 1

字段(Arg&)= QueryFile(文件#)。 _

字段(FieldName $(File#,FieldNum&))。值

下一个Arg&


QueryFile(文件# ).MoveNext


退出Sub


Error_Handler:

如果Error_Handler(" ReadQuery",Err)= acDataErrDisplay然后

错误GoTo 0


停止:恢复''按两次[F8]查看问题。


结束如果


结束子


Sub CloseQuery(文件#)


开错误GoTo Error_Handler


QueryFile(文件#)。关闭

设置qry(文件#)=无什么

设置tbl(文件#)=没什么

设置db(文件#)=没什么

QueryOpen(File#)= False


退出Sub


Error_Handler:

如果Error_Handler(" CloseQuery",Err)= acDataErrDisplay那么

On Error GoTo 0


停止:恢复''按两次[F8]查看问题。


结束如果


结束子


函数FreeQuery#()


昏暗文件&


错误GoTo Error_Handler


For File& = 1到MaxFiles

如果不是QueryOpen(文件&)然后

FreeQuery =文件&

退出

结束如果

下一页


退出功能


Error_Handler:

如果Error_Handler( FreeQuery,Err)= acDataErrDisplay然后

错误GoTo 0


停止:恢复''按两次[F8]查看问题。


结束如果


结束功能


Public Sub TestQuery()


''这只是一个愚蠢的测试程序。


Dim FileNumber#

昏暗的症状$


FileNumber#= FreeQuery


OpenQuery" Symptoms",File:= FileNumber#,Locks:= dbReadOnly,_

Fields:= Array (症状)

ReadQuery FileNumber#,症状$

停止''并检查第一个症状是否已在OK中读取。

CloseQuery FileNumber#


End Sub

解决案例




To All,

First, some of your replies to me have been posted through
DevelopersDex, and these are NOT posted on USENET for the world to
see. DevelopersDex appears to be trying to hijack USENET, though there
may be some more benign explanation that escapes me. If you want the
world to see your replies, then you should post them directly to
USENET. However, I''ll see them either way.

After years of frustration with DAO, it dawned on me that it might be
possible to write a reasonable wrapper for DAO to hide the mess! I did
just that and attached it below. It sort of works enough for my
application, but fixing its remaining problems would help a LOT.

The problems are explained in comments contained therein. Mostly they
have to do with interfacing with the OpenRecordset method. Apparently,
OpenRecordset doesn''t handle optional arguments in any
reasonable/classical way. Where the arguments are themselves passed as
optional from the wrapper, it appears that it may be necessary to code
some large number of OpenRecordset usages with all possible
combinations of arguments. Then, there is the problem of what to put
into the arguments that you don''t care about, but which lead an
argument that you wish to include. Apparently these MUST be stated,
but to illustrate the depth of the problem, the first argument, the
"type" argument, defaults to various values depending on a variety of
poorly documented things. Oops, I think I just stepped in some of the
mess that I was trying to hide!

Basically, if I can get this to work smoothly, this provides a
classical VB (not VBA) file-like interface, while exposing the
recordset object for random positioning, EOF detection, and other
important things.

Note that enough is working for the little test routine to run, but
NOT enough to recognize the vbReadOnly option.

PLEASE, all suggestions for improvement would be GREATLY appreciated.
................................

'' modDAOinterface is Coypright ? 2004 by The Richfield Family
'' with all rights reserved.

Option Compare Text
Option Explicit
Option Base 1

Const MaxFiles = 10
Const MaxFields = 10

Dim QueryOpen(MaxFiles) As Boolean '' Has it been opened?
Public QueryFile(MaxFiles) As Recordset '' The recordset.
Dim FieldName$(MaxFiles, MaxFields) '' Field nnames of
ParamArry Args.
Dim db(MaxFiles) As Database
Dim qry(MaxFiles) As QueryDef
Dim tbl(MaxFiles) As TableDef

'' Queries and subforms are very strange things in Access, often
deciding not
'' to evaluate fields or compute expressions unless they are displayed
on the
'' screen or are used to modify other database objects.
'' This throws a monkey wrench into complex functions with beneficial
side
'' effects that may not be apparent to the database engine.
'' To overcome this, these simple routines have been implemented to
read a
'' query or table as though it were a sequential file.
'' This forces "dumb" operation where everything is read and evaluated.

Sub OpenQuery(QueryName$, File#, Optional Database As Variant, _
Optional Mode As Variant, Optional Access As Variant, _
Optional Locks As Variant, Optional SQL As Variant, _
Optional Fields As Variant)

'' Mode, Access, and Locks, are inop pending more info on
OpenRecordset.

Dim Arg& '' The number of the argument being
considered.
Dim FieldNum& '' Ordinal number of the field.
Dim RetVal As Variant

On Error GoTo Error_Handler

If QueryOpen(File#) Then _
Call CloseQuery(File#)

If IsMissing(Database) Then
Set db(File#) = CurrentDb()
Else
Set db(File#) = OpenDatabase(CStr(Database))
End If

On Error GoTo TryTable
'' The following doesn''t seem to work for Jet MDBs.
Set qry(File#) = db(File#).QueryDefs(QueryName$)

On Error GoTo Error_Handler

'' Type:=Mode, Options:=Access, LockEdit:=Locks
If IsMissing(SQL) Then
'' The following line needs at least one numeric operation.
'' The following line gives an error 3210 Invalid Operation.
Set QueryFile(File#) = qry(File#).OpenRecordset(dbOpenTable)
Else
Set QueryFile(File#) = qry(File#).OpenRecordset(CStr(SQL))
End If
GoTo GotIt

TryTable:
Resume NextLine

NextLine:
On Error GoTo Error_Handler
Set tbl(File#) = db(File#).TableDefs(QueryName$)

'' Arguments to the following OpenRecordset don''t seem to work.
'' (Type:=Mode, Options:=Access, LockEdits:=Locks)
If IsMissing(SQL) Then
Set QueryFile(File#) = tbl(File#).OpenRecordset
Else
Set QueryFile(File#) = tbl(File#).OpenRecordset(CStr(SQL))
End If

GotIt:

'' Suck in the field names.

FieldNum& = 0
For Arg& = LBound(Fields) To UBound(Fields)
FieldNum& = FieldNum& + 1
FieldName$(File#, FieldNum&) = Fields(Arg&)
'' The following simply validates the field name here and now.
If Not QueryFile(File#).EOF Then _
RetVal = QueryFile(File#).Fields(FieldName$(File#,
FieldNum&))
Next Arg&

QueryOpen(File#) = True

Exit Sub

Error_Handler:
If Error_Handler("OpenQuery", Err) = acDataErrDisplay Then
On Error GoTo 0

Stop: Resume '' Press [F8] twice to view the problem.

End If

End Sub

Sub ReadQuery(File#, ParamArray Fields() As Variant)

'' Always test for EOF before calling, using:
'' If QueryFile(1#).EOF Then
'' Call CloseQuery(1#)

Dim Arg&
Dim FieldNum& '' Ordinal number of the field.

On Error GoTo Error_Handler

If Not QueryOpen(File#) Then
Call CloseQuery(File#)
Error 17
End If

FieldNum& = 0
For Arg& = LBound(Fields) To UBound(Fields)
FieldNum& = FieldNum& + 1
Fields(Arg&) = QueryFile(File#). _
Fields(FieldName$(File#, FieldNum&)).Value
Next Arg&

QueryFile(File#).MoveNext

Exit Sub

Error_Handler:
If Error_Handler("ReadQuery", Err) = acDataErrDisplay Then
On Error GoTo 0

Stop: Resume '' Press [F8] twice to view the problem.

End If

End Sub

Sub CloseQuery(File#)

On Error GoTo Error_Handler

QueryFile(File#).Close
Set qry(File#) = Nothing
Set tbl(File#) = Nothing
Set db(File#) = Nothing
QueryOpen(File#) = False

Exit Sub

Error_Handler:
If Error_Handler("CloseQuery", Err) = acDataErrDisplay Then
On Error GoTo 0

Stop: Resume '' Press [F8] twice to view the problem.

End If

End Sub

Function FreeQuery#()

Dim File&

On Error GoTo Error_Handler

For File& = 1 To MaxFiles
If Not QueryOpen(File&) Then
FreeQuery = File&
Exit For
End If
Next

Exit Function

Error_Handler:
If Error_Handler("FreeQuery", Err) = acDataErrDisplay Then
On Error GoTo 0

Stop: Resume '' Press [F8] twice to view the problem.

End If

End Function

Public Sub TestQuery()

'' This is just a stupid test routine.

Dim FileNumber#
Dim Symptom$

FileNumber# = FreeQuery

OpenQuery "Symptoms", File:=FileNumber#, Locks:=dbReadOnly, _
Fields:=Array("Symptom")
ReadQuery FileNumber#, Symptom$
Stop '' and check that the first Symptom was read in OK.
CloseQuery FileNumber#

End Sub

解决方案




这篇关于DAO的包装!好吧,差不多......的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 16:09