O objetivo deste artigo é o de ser uma referência para os desenvolvedores da língua portuguesa, demonstrando como usar a biblioteca DAO de forma programável, criando, apagando, modificando e listando os objetos no MS Access. Através deste artigo terá condições de manipular as tabelas, os seus campos e índices, bem como o seu relacionamento com outras tabelas. Também poderá ler e definir suas propriedades, tanto de consultas como as do banco de dados.
DAO (Data Access Objects) é a biblioteca nativa da Microsoft desenvolvida para expor o DNA do MS Access como um objeto. Todas as versões têm esta biblioteca definida por padrão, exceto o MS Access 2000 e 2002, certifique-se de fazer referência a biblioteca DAO destes se for usar essas versões.
Note: Não há explicações além de comentários numa linha, e nenhum erro de manipulação, na maioria dos exemplos.
Option Compare DatabaseOption Explicit'Constants for examining how a field is indexed.Private Const intcIndexNone As Integer = 0Private Const intcIndexGeneral As Integer = 1Private Const intcIndexUnique As Integer = 3Private Const intcIndexPrimary As Integer = 7Function CreateTableDAO()'Purpose: Create two tables using DAO.Dim db As DAO.DatabaseDim tdf As DAO.TableDefDim fld As DAO.Field'Initialize the Contractor table.Set db = CurrentDb()Set tdf = db.CreateTableDef("tblDaoContractor")'Specify the fields.With tdf'AutoNumber: Long with the attribute set.Set fld = .CreateField("ContractorID", dbLong)fld.Attributes = dbAutoIncrField + dbFixedField.Fields.Append fld'Text field: maximum 30 characters, and required.Set fld = .CreateField("Surname", dbText, 30)fld.Required = True.Fields.Append fld'Text field: maximum 20 characters..Fields.Append .CreateField("FirstName", dbText, 20)'Yes/No field..Fields.Append .CreateField("Inactive", dbBoolean)'Currency field..Fields.Append .CreateField("HourlyFee", dbCurrency)'Number field..Fields.Append .CreateField("PenaltyRate", dbDouble)'Date/Time field with validation rule.Set fld = .CreateField("BirthDate", dbDate)fld.ValidationRule = "Is Null Or <=Date()"fld.ValidationText = "Birth date cannot be future.".Fields.Append fld'Memo field..Fields.Append .CreateField("Notes", dbMemo)'Hyperlink field: memo with the attribute set.Set fld = .CreateField("Web", dbMemo)fld.Attributes = dbHyperlinkField + dbVariableField.Fields.Append fldEnd With'Save the Contractor table.db.TableDefs.Append tdfSet fld = NothingSet tdf = NothingDebug.Print "tblDaoContractor created."'Initialize the Booking tableSet tdf = db.CreateTableDef("tblDaoBooking")With tdf'AutonumberSet fld = .CreateField("BookingID", dbLong)fld.Attributes = dbAutoIncrField + dbFixedField.Fields.Append fld'BookingDate.Fields.Append .CreateField("BookingDate", dbDate)'ContractorID.Fields.Append .CreateField("ContractorID", dbLong)'BookingFee.Fields.Append .CreateField("BookingFee", dbCurrency)'BookingNote: Required.Set fld = .CreateField("BookingNote", dbText, 255)fld.Required = True.Fields.Append fldEnd With'Save the Booking table.db.TableDefs.Append tdfSet fld = NothingSet tdf = NothingDebug.Print "tblDaoBooking created."'Clean upApplication.RefreshDatabaseWindow 'Show the changesSet fld = NothingSet tdf = NothingSet db = NothingEnd FunctionFunction ModifyTableDAO()'Purpose: How to add and delete fields to existing tables.'Note: Requires the table created by CreateTableDAO() above.Dim db As DAO.DatabaseDim tdf As DAO.TableDefDim fld As DAO.Field'InitializeSet db = CurrentDb()Set tdf = db.TableDefs("tblDaoContractor")'Add a field to the table.tdf.Fields.Append tdf.CreateField("TestField", dbText, 80)Debug.Print "Field added."'Delete a field from the table.tdf.Fields.Delete "TestField"Debug.Print "Field deleted."'Clean upSet fld = NothingSet tdf = NothingSet db = NothingEnd FunctionFunction DeleteTableDAO()DBEngine(0)(0).TableDefs.Delete "DaoTest"End FunctionFunction MakeGuidTable()'Purpose: How to create a table with a GUID field.Dim db As DAO.DatabaseDim tdf As DAO.TableDefDim fld As DAO.FieldDim prp As DAO.PropertySet db = CurrentDb()Set tdf = db.CreateTableDef("Table8")With tdfSet fld = .CreateField("ID", dbGUID)fld.Attributes = dbFixedFieldfld.DefaultValue = "GenGUID()".Fields.Append fldEnd Withdb.TableDefs.Append tdfEnd FunctionFunction CreateIndexesDAO()Dim db As DAO.DatabaseDim tdf As DAO.TableDefDim ind As DAO.Index'InitializeSet db = CurrentDb()Set tdf = db.TableDefs("tblDaoContractor")'1. Primary key index.Set ind = tdf.CreateIndex("PrimaryKey")With ind.Fields.Append .CreateField("ContractorID").Unique = False.Primary = TrueEnd Withtdf.Indexes.Append ind'2. Single-field index.Set ind = tdf.CreateIndex("Inactive")ind.Fields.Append ind.CreateField("Inactive")tdf.Indexes.Append ind'3. Multi-field index.Set ind = tdf.CreateIndex("FullName")With ind.Fields.Append .CreateField("Surname").Fields.Append .CreateField("FirstName")End Withtdf.Indexes.Append ind'Refresh the display of this collection.tdf.Indexes.Refresh'Clean upSet ind = NothingSet tdf = NothingSet db = NothingDebug.Print "tblDaoContractor indexes created."End FunctionFunction DeleteIndexDAO()DBEngine(0)(0).TableDefs("tblDaoContractor").Indexes.Delete "Inactive"End FunctionFunction CreateRelationDAO()Dim db As DAO.DatabaseDim rel As DAO.RelationDim fld As DAO.Field'InitializeSet db = CurrentDb()'Create a new relation.Set rel = db.CreateRelation("tblDaoContractortblDaoBooking")'Define its properties.With rel'Specify the primary table..Table = "tblDaoContractor"'Specify the related table..ForeignTable = "tblDaoBooking"'Specify attributes for cascading updates and deletes..Attributes = dbRelationUpdateCascade + dbRelationDeleteCascade'Add the fields to the relation.'Field name in primary table.Set fld = .CreateField("ContractorID")'Field name in related table.fld.ForeignName = "ContractorID"'Append the field..Fields.Append fld'Repeat for other fields if a multi-field relation.End With'Save the newly defined relation to the Relations collection.db.Relations.Append rel'Clean upSet fld = NothingSet rel = NothingSet db = NothingDebug.Print "Relation created."End FunctionFunction DeleteRelationDAO()DBEngine(0)(0).Relations.Delete "tblDaoContractortblDaoBooking"End FunctionFunction DeleteQueryDAO()DBEngine(0)(0).QueryDefs.Delete "qryDaoBooking"End FunctionFunction SetPropertyDAO(obj As Object, strPropertyName As String, intType As Integer, _varValue As Variant, Optional strErrMsg As String) As BooleanOn Error GoTo ErrHandler'Purpose: Set a property for an object, creating if necessary.'Arguments: obj = the object whose property should be set.' strPropertyName = the name of the property to set.' intType = the type of property (needed for creating)' varValue = the value to set this property to.' strErrMsg = string to append any error message to.If HasProperty(obj, strPropertyName) Thenobj.Properties(strPropertyName) = varValueElseobj.Properties.Append obj.CreateProperty(strPropertyName, intType, varValue)End IfSetPropertyDAO = TrueExitHandler:Exit FunctionErrHandler:strErrMsg = strErrMsg & obj.Name & "." & strPropertyName & " not set to " & varValue & _". Error " & Err.Number & " - " & Err.Description & vbCrLfResume ExitHandlerEnd FunctionPublic Function HasProperty(obj As Object, strPropName As String) As Boolean'Purpose: Return true if the object has the property.Dim varDummy As VariantOn Error Resume NextvarDummy = obj.Properties(strPropName)HasProperty = (Err.Number = 0)End FunctionFunction StandardProperties(strTableName As String)'Purpose: Properties you always want set by default:' TableDef: Subdatasheets off.' Numeric fields: Remove Default Value.' Currency fields: Format as currency.' Yes/No fields: Display as check box. Default to No.' Text/memo/hyperlink: AllowZeroLength off,' UnicodeCompression on.' All fields: Add a caption if mixed case.'Argument: Name of the table.'Note: Requires: SetPropertyDAO()Dim db As DAO.Database 'Current database.Dim tdf As DAO.TableDef 'Table nominated in argument.Dim fld As DAO.Field 'Each field.Dim strCaption As String 'Field caption.Dim strErrMsg As String 'Responses and error messages.'Initalize.Set db = CurrentDb()Set tdf = db.TableDefs(strTableName)'Set the table's SubdatasheetName.Call SetPropertyDAO(tdf, "SubdatasheetName", dbText, "[None]", _strErrMsg)For Each fld In tdf.Fields'Handle the defaults for the different field types.Select Case fld.TypeCase dbText, dbMemo 'Includes hyperlinks.fld.AllowZeroLength = FalseCall SetPropertyDAO(fld, "UnicodeCompression", dbBoolean, _True, strErrMsg)Case dbCurrencyfld.DefaultValue = 0Call SetPropertyDAO(fld, "Format", dbText, "Currency", _strErrMsg)Case dbLong, dbInteger, dbByte, dbDouble, dbSingle, dbDecimalfld.DefaultValue = vbNullStringCase dbBooleanCall SetPropertyDAO(fld, "DisplayControl", dbInteger, _CInt(acCheckBox))End Select'Set a caption if needed.strCaption = ConvertMixedCase(fld.Name)If strCaption <> fld.Name ThenCall SetPropertyDAO(fld, "Caption", dbText, strCaption)End If'Set the field's Description.Call SetFieldDescription(tdf, fld, , strErrMsg)Next'Clean up.Set fld = NothingSet tdf = NothingSet db = NothingIf Len(strErrMsg) > 0 ThenDebug.Print strErrMsgElseDebug.Print "Properties set for table " & strTableNameEnd IfEnd FunctionFunction ConvertMixedCase(ByVal strIn As String) As String'Purpose: Convert mixed case name into a name with spaces.'Argument: String to convert.'Return: String converted by these rules:' 1. One space before an upper case letter.' 2. Replace underscores with spaces.' 3. No spaces between continuing upper case.'Example: "FirstName" or "First_Name" => "First Name".Dim lngStart As Long 'Loop through string.Dim strOut As String 'Output string.Dim boolWasSpace As Boolean 'Last char. was a space.Dim boolWasUpper As Boolean 'Last char. was upper case.strIn = Trim$(strIn) 'Remove leading/trailing spaces.boolWasUpper = True 'Initialize for no first space.For lngStart = 1& To Len(strIn)Select Case Asc(Mid(strIn, lngStart, 1&))Case vbKeyA To vbKeyZ 'Upper case: insert a space.If boolWasSpace Or boolWasUpper ThenstrOut = strOut & Mid(strIn, lngStart, 1&)ElsestrOut = strOut & " " & Mid(strIn, lngStart, 1&)End IfboolWasSpace = FalseboolWasUpper = TrueCase 95 'Underscore: replace with space.If Not boolWasSpace ThenstrOut = strOut & " "End IfboolWasSpace = TrueboolWasUpper = FalseCase vbKeySpace 'Space: output and set flag.If Not boolWasSpace ThenstrOut = strOut & " "End IfboolWasSpace = TrueboolWasUpper = FalseCase Else 'Any other char: output.strOut = strOut & Mid(strIn, lngStart, 1&)boolWasSpace = FalseboolWasUpper = FalseEnd SelectNextConvertMixedCase = strOutEnd FunctionFunction SetFieldDescription(tdf As DAO.TableDef, fld As DAO.Field, _Optional ByVal strDescrip As String, Optional strErrMsg As String) _As Boolean'Purpose: Assign a Description to a field.'Arguments: tdf = the TableDef the field belongs to.' fld = the field to document.' strDescrip = The description text you want.' If blank, uses Caption or Name of field.' strErrMsg = string to append any error messages to.'Notes: Description includes field size, validation,' whether required or unique.If (fld.Attributes And dbAutoIncrField) > 0& ThenstrDescrip = strDescrip & " Automatically generated " & _"unique identifier for this record."Else'If no description supplied, use the field's Caption or Name.If Len(strDescrip) = 0& ThenIf HasProperty(fld, "Caption") ThenIf Len(fld.Properties("Caption")) > 0& ThenstrDescrip = fld.Properties("Caption") & "."End IfEnd IfIf Len(strDescrip) = 0& ThenstrDescrip = fld.Name & "."End IfEnd If'Size of the field.'Ignore Date, Memo, Yes/No, Currency, Decimal, GUID,' Hyperlink, OLE Object.Select Case fld.TypeCase dbByte, dbInteger, dbLongstrDescrip = strDescrip & " Whole number."Case dbSingle, dbDoublestrDescrip = strDescrip & " Fractional number."Case dbTextstrDescrip = strDescrip & " " & fld.Size & "-char max."End Select'Required and/or Unique?'Check for single-field index, and Required property.Select Case IndexOnField(tdf, fld)Case intcIndexPrimarystrDescrip = strDescrip & " Required. Unique."Case intcIndexUniqueIf fld.Required ThenstrDescrip = strDescrip & " Required. Unique."ElsestrDescrip = strDescrip & " Unique."End IfCase ElseIf fld.Required ThenstrDescrip = strDescrip & " Required."End IfEnd Select'Validation?If Len(fld.ValidationRule) > 0& ThenIf Len(fld.ValidationText) > 0& ThenstrDescrip = strDescrip & " " & fld.ValidationTextElsestrDescrip = strDescrip & " " & fld.ValidationRuleEnd IfEnd IfEnd IfIf Len(strDescrip) > 0& ThenstrDescrip = Trim$(Left$(strDescrip, 255&))SetFieldDescription = SetPropertyDAO(fld, "Description", _dbText, strDescrip, strErrMsg)End IfEnd FunctionPrivate Function IndexOnField(tdf As DAO.TableDef, fld As DAO.Field) _As Integer'Purpose: Indicate if there is a single-field index _' on this field in this table.'Return: The constant indicating the strongest type.Dim ind As DAO.IndexDim intReturn As IntegerintReturn = intcIndexNoneFor Each ind In tdf.IndexesIf ind.Fields.Count = 1 ThenIf ind.Fields(0).Name = fld.Name ThenIf ind.Primary ThenintReturn = (intReturn Or intcIndexPrimary)ElseIf ind.Unique ThenintReturn = (intReturn Or intcIndexUnique)ElseintReturn = (intReturn Or intcIndexGeneral)End IfEnd IfEnd IfNext'Clean upSet ind = NothingIndexOnField = intReturnEnd FunctionFunction CreateQueryDAO()'Purpose: How to create a query'Note: Requires a table named MyTable.Dim db As DAO.DatabaseDim qdf As DAO.QueryDefSet db = CurrentDb()'The next line creates and automatically appends the QueryDef.Set qdf = db.CreateQueryDef("qryMyTable")'Set the SQL property to a string representing a SQL statement.qdf.SQL = "SELECT MyTable.* FROM MyTable;"'Do not append: QueryDef is automatically appended!Set qdf = NothingSet db = NothingDebug.Print "qryMyTable created."End FunctionFunction CreateDatabaseDAO()'Purpose: How to create a new database and set key properties.Dim dbNew As DAO.DatabaseDim prp As DAO.PropertyDim strFile As String'Create the new database.strFile = "C:\SampleDAO.mdb"Set dbNew = DBEngine(0).CreateDatabase(strFile, dbLangGeneral)'Create example properties in new database.With dbNewSet prp = .CreateProperty("Perform Name AutoCorrect", dbLong, 0).Properties.Append prpSet prp = .CreateProperty("Track Name AutoCorrect Info", _dbLong, 0).Properties.Append prpEnd With'Clean up.dbNew.CloseSet prp = NothingSet dbNew = NothingDebug.Print "Created " & strFileEnd FunctionFunction ShowDatabaseProps()'Purpose: List the properies of the current database.Dim db As DAO.DatabaseDim prp As DAO.PropertySet db = CurrentDb()For Each prp In db.PropertiesDebug.Print prp.NameNextSet db = NothingEnd FunctionFunction ShowFields(strTable As String)'Purpose: How to read the fields of a table.'Usage: Call ShowFields("Table1")Dim db As DAO.DatabaseDim tdf As DAO.TableDefDim fld As DAO.FieldSet db = CurrentDb()Set tdf = db.TableDefs(strTable)For Each fld In tdf.FieldsDebug.Print fld.Name, FieldTypeName(fld)NextSet fld = NothingSet tdf = NothingSet db = NothingEnd FunctionFunction ShowFieldsRS(strTable)'Purpose: How to read the field names and types from a table or query.'Usage: Call ShowFieldsRS("Table1")Dim rs As DAO.RecordsetDim fld As DAO.FieldDim strSql As StringstrSql = "SELECT " & strTable & ".* FROM " & strTable & " WHERE (False);"Set rs = DBEngine(0)(0).OpenRecordset(strSql)For Each fld In rs.FieldsDebug.Print fld.Name, FieldTypeName(fld), "from " & fld.SourceTable & "." & fld.SourceFieldNextrs.CloseSet rs = NothingEnd FunctionPublic Function FieldTypeName(fld As DAO.Field)'Purpose: Converts the numeric results of DAO fieldtype to text.'Note: fld.Type is Integer, but the constants are Long.Dim strReturn As String 'Name to returnSelect Case CLng(fld.Type)Case dbBoolean: strReturn = "Yes/No" ' 1Case dbByte: strReturn = "Byte" ' 2Case dbInteger: strReturn = "Integer" ' 3Case dbLong ' 4If (fld.Attributes And dbAutoIncrField) = 0& ThenstrReturn = "Long Integer"ElsestrReturn = "AutoNumber"End IfCase dbCurrency: strReturn = "Currency" ' 5Case dbSingle: strReturn = "Single" ' 6Case dbDouble: strReturn = "Double" ' 7Case dbDate: strReturn = "Date/Time" ' 8Case dbBinary: strReturn = "Binary" ' 9 (no interface)Case dbText '10If (fld.Attributes And dbFixedField) = 0& ThenstrReturn = "Text"ElsestrReturn = "Text (fixed width)"End IfCase dbLongBinary: strReturn = "OLE Object" '11Case dbMemo '12If (fld.Attributes And dbHyperlinkField) = 0& ThenstrReturn = "Memo"ElsestrReturn = "Hyperlink"End IfCase dbGUID: strReturn = "GUID" '15'Attached tables only: cannot create these in JET.Case dbBigInt: strReturn = "Big Integer" '16Case dbVarBinary: strReturn = "VarBinary" '17Case dbChar: strReturn = "Char" '18Case dbNumeric: strReturn = "Numeric" '19Case dbDecimal: strReturn = "Decimal" '20Case dbFloat: strReturn = "Float" '21Case dbTime: strReturn = "Time" '22Case dbTimeStamp: strReturn = "Time Stamp" '23'Constants for complex types don't work prior to Access 2007.Case 101&: strReturn = "Attachment" 'dbAttachmentCase 102&: strReturn = "Complex Byte" 'dbComplexByteCase 103&: strReturn = "Complex Integer" 'dbComplexIntegerCase 104&: strReturn = "Complex Long" 'dbComplexLongCase 105&: strReturn = "Complex Single" 'dbComplexSingleCase 106&: strReturn = "Complex Double" 'dbComplexDoubleCase 107&: strReturn = "Complex GUID" 'dbComplexGUIDCase 108&: strReturn = "Complex Decimal" 'dbComplexDecimalCase 109&: strReturn = "Complex Text" 'dbComplexTextCase Else: strReturn = "Field type " & fld.Type & " unknown"End SelectFieldTypeName = strReturnEnd FunctionFunction DAORecordsetExample()'Purpose: How to open a recordset and loop through the records.'Note: Requires a table named MyTable, with a field named MyField.Dim rs As DAO.RecordsetDim strSql As StringstrSql = "SELECT MyField FROM MyTable;"Set rs = DBEngine(0)(0).OpenRecordset(strSql)Do While Not rs.EOFDebug.Print rs!MyFieldrs.MoveNextLooprs.CloseSet rs = NothingEnd FunctionFunction ShowFormProperties(strFormName As String)On Error GoTo Err_Handler'Purpose: Loop through the controls on a form, showing names and properties.'Usage: Call ShowFormProperties("Form1")Dim frm As FormDim ctl As ControlDim prp As PropertyDim strOut As StringDoCmd.OpenForm strFormName, acDesign, WindowMode:=acHiddenSet frm = Forms(strFormName)For Each ctl In frmFor Each prp In ctl.PropertiesstrOut = strFormName & "." & ctl.Name & "." & prp.Name & ": "strOut = strOut & prp.Type & vbTabstrOut = strOut & prp.ValueDebug.Print strOutNextIf ctl.ControlType = acTextBox Then StopNextSet frm = NothingDoCmd.Close acForm, strFormName, acSaveNoExit_Handler:Exit FunctionErr_Handler:Select Case Err.NumberCase 2186:strOut = strOut & Err.DescriptionResume NextCase ElseMsgBox "Error " & Err.Number & ": " & Err.Description, vbExclamation, "ShowFormProperties()"Resume Exit_HandlerEnd SelectEnd FunctionPublic Function ExecuteInTransaction(strSql As String, Optional strConfirmMessage As String) As LongOn Error GoTo Err_Handler'Purpose: Execute the SQL statement on the current database in a transaction.'Return: RecordsAffected if zero or above.'Arguments: strSql = the SQL statement to be executed.' strConfirmMessage = the message to show the user for confirmation. Number will be added to front.' No confirmation if ZLS.' -1 on error.' -2 on user-cancel.Dim ws As DAO.WorkspaceDim db As DAO.DatabaseDim bInTrans As BooleanDim bCancel As BooleanDim strMsg As StringDim lngReturn As LongConst lngcUserCancel = -2&Set ws = DBEngine(0)ws.BeginTransbInTrans = TrueSet db = ws(0)db.Execute strSql, dbFailOnErrorlngReturn = db.RecordsAffectedIf strConfirmMessage <> vbNullString ThenIf MsgBox(lngReturn & " " & Trim$(strConfirmMessage), vbOKCancel + vbQuestion, "Confirm") <> vbOK ThenbCancel = TruelngReturn = lngcUserCancelEnd IfEnd If'Commmit or rollback.If bCancel Thenws.RollbackElsews.CommitTransEnd IfbInTrans = FalseExit_Handler:ExecuteInTransaction = lngReturnOn Error Resume NextSet db = NothingIf bInTrans Thenws.RollbackEnd IfSet ws = NothingExit FunctionErr_Handler:MsgBox "Error " & Err.Number & ": " & Err.Description, vbExclamation, "ExecuteInTransaction()"lngReturn = -1Resume Exit_HandlerEnd FunctionFunction GetAutoNumDAO(strTable) As String'Purpose: Get the name of the AutoNumber field, using DAO.Dim db As DAO.DatabaseDim tdf As DAO.TableDefDim fld As DAO.FieldSet db = CurrentDb()Set tdf = db.TableDefs(strTable)For Each fld In tdf.FieldsIf (fld.Attributes And dbAutoIncrField) <> 0 ThenGetAutoNumDAO = fld.NameExit ForEnd IfNextSet fld = NothingSet tdf = NothingSet db = NothingEnd Function
Nenhum comentário:
Postar um comentário