home *** CD-ROM | disk | FTP | other *** search
- VERSION 1.0 CLASS
- BEGIN
- MultiUse = -1 'True
- END
- Attribute VB_Name = "GenericDB"
- Attribute VB_Creatable = True
- Attribute VB_Exposed = False
- '*********************************************************************
- ' GENERIC.CLS - A database class with a set of common routines.
- '*********************************************************************
- Option Explicit
- '*********************************************************************
- ' Class data members
- '*********************************************************************
- Private WSpace As Workspace ' Class Workspace
- Private DBase As Database ' Class Database
- Private RecSet As Recordset ' Main Class RecordSet
- Private DBFileName As String ' Filename of the database
- Private TBDef As TableDef ' For creating new tables
- Private FieldName As Field ' For creating new fields
- '*********************************************************************
- ' This Procedure creates the default workspace
- '*********************************************************************
- Private Sub Class_Initialize()
- Set WSpace = DBEngine.Workspaces(0)
- End Sub
- '*********************************************************************
- ' The Recordset, Database, and Workspace are closed when the object
- ' goes out of scope to prevent corrupting the database.
- '*********************************************************************
- Private Sub Class_Terminate()
- On Error Resume Next
- RecSet.Close
- DBase.Close
- WSpace.Close
- End Sub
- '*********************************************************************
- ' Returns a reference to the workspace.
- '*********************************************************************
- Public Property Get GetWorkspace() As Workspace
- Set GetWorkspace = WSpace
- End Property
- '*********************************************************************
- ' Returns a reference to the database.
- '*********************************************************************
- Public Property Get GetDatabase() As Database
- Set GetDatabase = DBase
- End Property
- '*********************************************************************
- ' Returns the filename of the database that is currently open.
- '*********************************************************************
- Public Property Get FileName() As String
- FileName = DBFileName
- End Property
- '*********************************************************************
- ' Opens a database for use with this class.
- '*********************************************************************
- Public Sub OpenDB(File$, Optional OpenExclusive, Optional OpenReadOnly)
- Dim res%
- '*****************************************************************
- ' If any arguments are missing, add default values.
- '*****************************************************************
- On Error Resume Next
- If Not IsMissing(File) Then DBFileName = File
- If IsMissing(OpenExclusive) Then OpenExclusive = False
- If IsMissing(OpenReadOnly) Then OpenReadOnly = False
- '*****************************************************************
- ' Convert the arguments into valid booleans.
- '*****************************************************************
- OpenExclusive = CBool(OpenExclusive)
- OpenReadOnly = CBool(OpenReadOnly)
- '*****************************************************************
- ' Open the database.
- '*****************************************************************
- Set DBase = WSpace.OpenDatabase(DBFileName, OpenExclusive, _
- OpenReadOnly)
- '*****************************************************************
- ' If the database is corrupted, then prompt to repair it.
- '*****************************************************************
- If Err = 3049 Then
- res = MsgBox(Error & vbLf & vbLf & _
- "Would you like attempt to repair this database?", _
- vbQuestion + vbYesNo)
- '*************************************************************
- ' If no, then bug out.
- '*************************************************************
- If res = vbNo Then Exit Sub
- '*************************************************************
- ' Otherwise repair it, clear the error flag, and try again.
- '*************************************************************
- Repair DBFileName: Err = 0
- Set DBase = WSpace.OpenDatabase(DBFileName, OpenExclusive, _
- OpenReadOnly)
- '*************************************************************
- ' If there is another error, then give up.
- '*************************************************************
- If Err Then
- MsgBox "An attempt to open the database failed!", vbCritical
- End If
- '*****************************************************************
- ' If some other error, then just report it.
- '*****************************************************************
- ElseIf Err <> 0 And Err <> 3049 Then
- MsgBox Error, vbExclamation
- End If
- End Sub
- '*********************************************************************
- ' Creates a Recordset for use with this class.
- '*********************************************************************
- Public Sub CreateRecordSet(Source$, Optional ViewType, Optional Options)
- '*****************************************************************
- ' If any arguments are missing, add default values.
- '*****************************************************************
- If IsMissing(ViewType) Then ViewType = dbOpenDynaset
- If IsMissing(Options) Then
- Set RecSet = DBase.OpenRecordset(Source, CInt(ViewType))
- Else
- Set RecSet = DBase.OpenRecordset(Source, CInt(ViewType), _
- CInt(Options))
- End If
- End Sub
- '*********************************************************************
- ' Returns a reference to the currently open Recordset.
- '*********************************************************************
- Public Property Get Data() As Recordset
- Set Data = RecSet
- End Property
- '*********************************************************************
- ' Creates a new database.
- '*********************************************************************
- Public Sub Create(File$)
- If Not IsMissing(File) Then DBFileName = File
- Set DBase = WSpace.CreateDatabase(DBFileName, dbLangGeneral)
- End Sub
- '*********************************************************************
- ' Creates a TableDef.
- '*********************************************************************
- Public Sub MakeTable(TableName As String)
- Set TBDef = DBase.CreateTableDef(TableName)
- End Sub
- '*********************************************************************
- ' Returns a reference to the open TableDef.
- '*********************************************************************
- Public Property Get NewTable() As TableDef
- Set NewTable = TBDef
- End Property
- '*********************************************************************
- ' Writes the TableDef to the table, so a new table can be created.
- '*********************************************************************
- Public Sub AddTable()
- DBase.TableDefs.Append TBDef
- Set TBDef = Nothing
- End Sub
- '*********************************************************************
- ' Creates a new field definintion. Other attributes should be set by
- ' obtaining the NewField reference, and make the changes directly.
- '*********************************************************************
- Public Sub MakeField(FName$, FType%, Optional FSize)
- Set FieldName = TBDef.CreateField(FName, FType)
- If Not IsMissing(FSize) Then FieldName.Size = CInt(FSize)
- End Sub
- '*********************************************************************
- ' Returns a reference to the currently open field definition.
- '*********************************************************************
- Public Property Get NewField() As Field
- Set NewField = FieldName
- End Property
- '*********************************************************************
- ' Writes the field definition to the current TableDef.
- '*********************************************************************
- Public Sub AddField()
- TBDef.Fields.Append FieldName
- Set FieldName = Nothing
- End Sub
- '*********************************************************************
- ' Writes a index to a TableDef.
- '*********************************************************************
- Public Sub MakeIndex(FldName$, PrimaryKey As Boolean, UniqueKey As Boolean)
- Dim NewIndex As New Index ' For creating new indexes
- With NewIndex
- .Name = "idx" & FldName
- .Fields = FldName
- .Primary = PrimaryKey
- .Unique = IIf(PrimaryKey, True, UniqueKey)
- End With
- TBDef.Indexes.Append NewIndex
- End Sub
- '*********************************************************************
- ' Returns all (up to ~32k) of the records of a field in a delimited
- ' string. This is a useful feature for inserting data into a text box.
- '*********************************************************************
- Public Function GetData(FName$, ByVal Delimiter$) As String
- Dim res$, retStr$
- '*****************************************************************
- ' Move to the first record.
- '*****************************************************************
- On Error Resume Next
- RecSet.MoveFirst
- '*****************************************************************
- ' Build a large (<=~32k) delimited string of the records.
- '*****************************************************************
- Do While Not RecSet.EOF
- res = Trim(RecSet(FName))
- If Len(res) + Len(retStr) > 32001 Then Exit Do
- retStr = retStr & res & Delimiter
- RecSet.MoveNext
- Loop
- '*****************************************************************
- ' Return to the first record, and return the results.
- '*****************************************************************
- RecSet.MoveFirst
- GetData = retStr
- End Function
- '*********************************************************************
- ' Same as GetData, but the data is stored in an array.
- '*********************************************************************
- Public Sub GetArrayData(FName$, retArray() As String)
- Dim res$, retStr$, i%
- On Error Resume Next
- Erase retArray
- RecSet.MoveFirst
- Do While Not RecSet.EOF
- res = Trim(RecSet(FName))
- If Len(res) + Len(retStr) > 32001 Then Exit Do
- If Not IsNull(res) Then
- retStr = retStr & res
- ReDim Preserve retArray(i + 1)
- retArray(i) = res
- i = i + 1
- End If
- RecSet.MoveNext
- Loop
- RecSet.MoveFirst
- End Sub
- '*********************************************************************
- ' Same as GetData, but the data is loaded into a control. The control
- ' MUST either be a list or combo box in order for this method to work.
- '*********************************************************************
- Public Sub GetControlData(FName$, CtrlName As Control)
- Dim res, retStr$
- On Error Resume Next
- RecSet.MoveFirst
- Do While Not RecSet.EOF
- res = Trim(RecSet(FName))
- If Len(res) + Len(retStr) > 32001 Then Exit Do
- If Not IsNull(res) Then
- retStr = retStr & res
- CtrlName.AddItem res
- End If
- RecSet.MoveNext
- Loop
- CtrlName.ListIndex = 0
- RecSet.MoveFirst
- End Sub
- '*********************************************************************
- ' Adds a new record, or edits an existing one. This method should not
- ' be used when adding or editing > 20 records (for performance reasons).
- '*********************************************************************
- Public Sub AddOrEditRecord(ByVal AddRec As Boolean, _
- ParamArray FieldPipeValue())
- Dim NumItems%, i%, where%, FName$, FValue
- '*****************************************************************
- ' Find out how many parameters were passed. If none, then exit.
- '*****************************************************************
- On Error Resume Next
- NumItems = UBound(FieldPipeValue)
- If IsEmpty(FieldPipeValue(0)) Then Exit Sub
- '*****************************************************************
- ' Determine whether to add or edit the record.
- '*****************************************************************
- If AddRec Then
- RecSet.AddNew
- Else
- RecSet.Edit
- '*************************************************************
- ' If there was no current record, then notify the user.
- '*************************************************************
- If Err = 3021 Then
- MsgBox "Since there is no current record, it can not be edited." _
- , vbCritical
- Exit Sub
- End If
- End If
- '*****************************************************************
- ' If loop through each parameter.
- '*****************************************************************
- For i = 0 To NumItems
- '*************************************************************
- ' Separate the field name from its value.
- '*************************************************************
- FName = FieldPipeValue(i)
- where = InStr(FName, "|")
-
- If where = 0 And i > 1 Then
- Exit For
- ElseIf where = 0 And i < 1 Then
- Exit Sub
- End If
-
- FValue = Mid(FName, where + 1)
- FName = CStr(Left(FName, where - 1))
- '*************************************************************
- ' Determine the record type, and convert the value.
- '*************************************************************
- Select Case RecSet(FName).Type
- Case dbBoolean
- RecSet(FName) = CBool(FValue)
- Case dbByte, dbInteger
- RecSet(FName) = CInt(FValue)
- Case dbLong
- RecSet(FName) = CLng(FValue)
- Case dbCurrency
- RecSet(FName) = CCur(FValue)
- Case dbSingle
- RecSet(FName) = CSng(FValue)
- Case dbDouble
- RecSet(FName) = CDbl(FValue)
- '*********************************************************
- ' Otherwise it must be a dbDate, dbText, dbLongBinary, &
- ' dbMemo.
- '*********************************************************
- Case Else
- where = RecSet(FName).Size
- '*****************************************************
- ' If the record is too long, then clip it.
- '*****************************************************
- If where And (Len(FValue) > where) Then
- FValue = Left(FValue, where)
- ElseIf Len(FValue) > 32000 Then
- FValue = Left(FValue, 32000)
- End If
- RecSet(FName) = FValue
- End Select
- Next i
- '*****************************************************************
- ' Complete the transaction.
- '*****************************************************************
- RecSet.Update
- End Sub
- '*********************************************************************
- ' Move to the first record.
- '*********************************************************************
- Public Function MFirst(Optional FName) As String
- On Error Resume Next
- If RecSet.Type = 2 Then Exit Function
- RecSet.MoveFirst
- If Not IsMissing(FName) Then
- MFirst = Trim(RecSet(CStr(FName)))
- End If
- End Function
- '*********************************************************************
- ' Move to the last record.
- '*********************************************************************
- Public Function MLast(Optional FName) As String
- On Error Resume Next
- RecSet.MoveLast
- If Not IsMissing(FName) Then
- MLast = Trim(RecSet(CStr(FName)))
- End If
- End Function
- '*********************************************************************
- ' Move to the next record.
- '*********************************************************************
- Public Function MNext(Optional FName) As String
- On Error Resume Next
- RecSet.MoveNext
- If RecSet.EOF Then RecSet.MoveLast
- If Not IsMissing(FName) Then
- MNext = Trim(RecSet(CStr(FName)))
- End If
- End Function
- '*********************************************************************
- ' Move to the previous record.
- '*********************************************************************
- Public Function MPrev(Optional FName) As String
- On Error Resume Next
- If RecSet.Type = 2 Then Exit Function
- RecSet.MovePrevious
- If RecSet.BOF Then RecSet.MoveFirst
- If Not IsMissing(FName) Then
- MPrev = Trim(RecSet(CStr(FName)))
- End If
- End Function
- '*********************************************************************
- ' Locates a record, and returns its result.
- '*********************************************************************
- Public Function FindRecord(FName$, FindWhat, Optional ByVal _
- ExactMatch) As Variant
- '*****************************************************************
- ' Determine wheter to find a similar or exact match.
- '*****************************************************************
- On Error Resume Next
- ExactMatch = IIf(IsMissing(ExactMatch), True, ExactMatch)
- '*****************************************************************
- ' Start at the beginning, and find the record.
- '*****************************************************************
- RecSet.MoveFirst
- If ExactMatch Then
- RecSet.FindFirst FName & " = '" & FindWhat & "'"
- Else
- RecSet.FindFirst "[" & FName & "] LIKE '" & FindWhat & "'"
- End If
- '*****************************************************************
- ' If no match, then return "".
- '*****************************************************************
- FindRecord = IIf(RecSet.NoMatch, "", FindRecord = RecSet(FName))
- End Function
- '*********************************************************************
- ' Returns a record from a specific field.
- '*********************************************************************
- Public Function GetRecord(FName$) As Variant
- On Error Resume Next
- GetRecord = RecSet(FName)
- End Function
- '*********************************************************************
- ' Repairs and Compacts a damaged database.
- '*********************************************************************
- Public Sub Repair(FileName$)
- Dim BakFileName$, res%
- '*****************************************************************
- ' Make a copy of the database to work on.
- '*****************************************************************
- On Error Resume Next
- BakFileName = Left(FileName, InStr(FileName, ".")) & "BAK"
- FileCopy FileName, BakFileName
- DBEngine.RepairDatabase BakFileName
- '*****************************************************************
- ' If it was successfully repaired, then kill the orginal.
- '*****************************************************************
- If Err = 0 Then
- Kill FileName
- '*************************************************************
- ' Repaired databases should be compacted, so do it now.
- '*************************************************************
- DBEngine.CompactDatabase BakFileName, FileName
- '*************************************************************
- ' If it succeeded, then ask the user if they want to delete
- ' the backup copy.
- '*************************************************************
- If Err = 0 Then
- If MsgBox("Would you like to delete the backup file?", _
- vbYesNo + vbQuestion) = vbYes Then Kill BakFileName
- End If
- End If
- End Sub
-