Results 1 to 2 of 2

Thread: FYI: Creating and verifying Access Tables from scratch

  1. #1

    Thread Starter
    C# Aficionado Lord_Rat's Avatar
    Join Date
    Sep 2001
    Location
    Cave
    Posts
    2,497

    FYI: Creating and verifying Access Tables from scratch

    I spent all day trying to make my program create a table dynamically and fix fields if they are not of a type I am expecting.

    I couldn't find a case of someone already doing this, so this is an FYI post for any who are looking to do the same thing.

    I like to keep my code as easy (for me) to use, so here is how you check a table:

    VB Code:
    1. 'This code assumes a 'backup' folder exists under the sDataSet location
    2.         Dim sDataSet As String = Application.ExecutablePath
    3.         sDataSet = sDataSet.Remove(InStrRev(Application.ExecutablePath, "\"), Len(Application.ExecutablePath) - InStrRev(Application.ExecutablePath, "\")) 'defines the folder where the data is
    4.         Dim tdTable As New TableDescription()
    5.         With tdTable
    6.             .PriKey = "PriKey" 'Primary Key field. Can be left blank
    7.             .TableName = "Locations" 'Name of table to check
    8.             .Fields = MakeArray("Location_Description", "Location_Database") 'field names
    9.             .FieldTypes = MakeADOXArray(ADOX.DataTypeEnum.adVarWChar, ADOX.DataTypeEnum.adVarWChar) 'Field types of fields
    10.             .MissingIsFatal = MakeBooleanArray(False, False) 'whether to throw an error is a field doesn't match
    11.         End With
    12.  
    13.         VerifyDataBase("dataset.mdb", tdTable) 'Now verify the 'dataset.mdb' database

    And the TableDescription Class...

    VB Code:
    1. Public Class TableDescription
    2.     Private TName As String
    3.     Private aFields() As String
    4.     Private MFatal() As Boolean
    5.     Private FTypes() As ADOX.DataTypeEnum
    6.     Private PKey As String
    7.  
    8.     Property TableName() As String
    9.         Get
    10.             Return TName
    11.         End Get
    12.         Set(ByVal Value As String)
    13.             TName = Value
    14.         End Set
    15.     End Property
    16.  
    17.     Property Fields() As String()
    18.         Get
    19.             Return aFields
    20.         End Get
    21.         Set(ByVal Value() As String)
    22.             aFields = Value
    23.         End Set
    24.     End Property
    25.  
    26.     Property MissingIsFatal() As Boolean()
    27.         Get
    28.             Return MFatal
    29.         End Get
    30.         Set(ByVal Value() As Boolean)
    31.             MFatal = Value
    32.         End Set
    33.     End Property
    34.  
    35.     Property FieldTypes() As ADOX.DataTypeEnum()
    36.         Get
    37.             Return FTypes
    38.         End Get
    39.         Set(ByVal Value() As ADOX.DataTypeEnum)
    40.             FTypes = Value
    41.         End Set
    42.     End Property
    43.  
    44.     Property PriKey() As String
    45.         Get
    46.             Return PKey
    47.         End Get
    48.         Set(ByVal Value As String)
    49.             PKey = Value
    50.         End Set
    51.     End Property
    52. End Class
    Need to re-register ASP.NET?
    C:\WINNT\Microsoft.NET\Framework\v#VERSIONNUMBER#\aspnet_regiis -i

    (Edit #VERSIONNUMBER# as needed - do a DIR if you don't know)

  2. #2

    Thread Starter
    C# Aficionado Lord_Rat's Avatar
    Join Date
    Sep 2001
    Location
    Cave
    Posts
    2,497
    Due to message length, I had to make two posts:

    And the functions:
    VB Code:
    1. Private Sub VerifyDataBase(ByVal dbName As String, ByVal tdTable As TableDescription)
    2.         Dim objFile As Scripting.File
    3.         Dim sDataSet As String = Application.ExecutablePath
    4.         Dim sDataSet1 As String = ""
    5.         Dim AcApp As New ADOX.Catalog()
    6.         Dim oColumn As New ADOX.Column()
    7.         Dim objTable As New ADOX.Table()
    8.  
    9.         If tdTable.Fields.GetUpperBound(0) <> tdTable.FieldTypes.GetUpperBound(0) Then
    10.             throwError("VerifyDataBase Fields not FieldTypes")
    11.             Exit Sub
    12.         End If
    13.         If tdTable.Fields.GetUpperBound(0) <> tdTable.MissingIsFatal.GetUpperBound(0) Then
    14.             throwError("VerifyDataBase Fields not MissingIsFatal")
    15.             Exit Sub
    16.         End If
    17.  
    18.         sDataSet = sDataSet.Remove(InStrRev(Application.ExecutablePath, "\"), Len(Application.ExecutablePath) - InStrRev(Application.ExecutablePath, "\"))
    19.         sDataSet1 = sDataSet & dbName
    20.         If Not VerifyDataSource(sDataSet1) Then
    21.             'The datasource could not be opened, so we are going to back it up if it exists and recreate it.
    22.             If objFS.FileExists(sDataSet1) Then
    23.                 Try
    24.                     objFS.CopyFile(sDataSet1, sDataSet & "\backup\" & System.DateTime.Now.ToFileTime().ToString() & ".mdb", True)
    25.                 Catch
    26.                 End Try
    27.                 objFile = objFS.GetFile(sDataSet1)
    28.                 objFile.Delete(True)
    29.             End If
    30.             Try
    31.  
    32.                 AcApp.Create("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & sDataSet1)
    33.  
    34.                 With objTable
    35.                     .Name = tdTable.TableName
    36.                     With .Columns
    37.                         Dim iCounter As Integer
    38.                         For iCounter = 0 To tdTable.Fields.GetUpperBound(0)
    39.                             Select Case tdTable.FieldTypes(iCounter)
    40.                                 Case ADOX.DataTypeEnum.adInteger
    41.                                     .Append(tdTable.Fields(iCounter), tdTable.FieldTypes(iCounter), 255)
    42.                                 Case Else
    43.                                     .Append(tdTable.Fields(iCounter), tdTable.FieldTypes(iCounter))
    44.                             End Select
    45.                         Next
    46.                     End With
    47.                 End With
    48.                 AcApp.Tables.Append(objTable)
    49.  
    50.                 If tdTable.PriKey <> "" Then
    51.                     ' Create a new AutoNumber ID Column
    52.                     With oColumn
    53.                         .Name = tdTable.PriKey
    54.                         .Type = ADOX.DataTypeEnum.adInteger
    55.                         .ParentCatalog = AcApp     ' Must set before setting properties
    56.                         .Properties("AutoIncrement").Value = True
    57.                     End With
    58.                     AcApp.Tables(tdTable.TableName).Columns.Append(oColumn)
    59.                     objTable.Keys.Append(tdTable.TableName, ADOX.KeyTypeEnum.adKeyPrimary, tdTable.PriKey)
    60.                 End If
    61.  
    62.             Catch ee As Exception
    63.                 throwError(sDataSet1 & vbCrLf & vbCrLf & ee.Message & vbCrLf & vbCrLf & "The file could not be opened. A new one could not be created either.")
    64.                 MyBase.Dispose()
    65.                 Exit Sub
    66.             End Try
    67.             throwError(sDataSet1 & vbCrLf & vbCrLf & "The file could not be opened. A new version has been created.")
    68.         Else
    69.             'Database exists, so check it to see if the fields are OK
    70.             Dim AcConn As New ADODB.Connection()
    71.             Dim modsMade As Boolean = False
    72.             AcConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & sDataSet1
    73.             AcConn.Open()
    74.             AcApp.ActiveConnection = AcConn
    75.             Try
    76.                 objTable = AcApp.Tables(tdTable.TableName)
    77.             Catch
    78.                 objTable = New ADOX.Table()
    79.                 objTable.Name = tdTable.TableName
    80.                 AcApp.Tables.Append(objTable)
    81.             End Try
    82.             Dim objColumn As ADOX.Column
    83.             Dim iCount As Integer
    84.             Dim bFound() As Boolean
    85.             ReDim bFound(tdTable.Fields.GetUpperBound(0) + 1)
    86.             For iCount = 0 To tdTable.Fields.GetUpperBound(0)
    87.                 For Each objColumn In objTable.Columns
    88.                     With objColumn
    89.                         If .Name = tdTable.Fields(iCount) AndAlso .Type = tdTable.FieldTypes(iCount) Then
    90.                             bFound(iCount) = True
    91.                             Exit For
    92.                         End If
    93.                     End With
    94.                 Next
    95.             Next
    96.  
    97.             Dim bFound2 As Boolean
    98.             Dim objKey As ADOX.Key
    99.             oColumn = New ADOX.Column()
    100.             For Each objKey In objTable.Keys
    101.                 With objKey
    102.                     If .Columns(0).Name = tdTable.PriKey AndAlso .Type = ADOX.KeyTypeEnum.adKeyPrimary AndAlso objTable.Columns(objKey.Columns(0).Name).Properties("AutoIncrement").Value = True Then
    103.                         bFound2 = True
    104.                         Exit For
    105.                     End If
    106.                 End With
    107.             Next
    108.  
    109.             If Not bFound2 Then
    110.                 'The datasource could not be opened, so we are going to back it up if it exists and recreate it.
    111.                 If objFS.FileExists(sDataSet1) Then
    112.                     Try
    113.                         objFS.CopyFile(sDataSet1, sDataSet & "\backup\" & System.DateTime.Now.ToFileTime().ToString() & ".mdb", True)
    114.                     Catch
    115.                     End Try
    116.                     modsMade = True
    117.                 End If
    118.  
    119.                 With oColumn
    120.                     .Name = tdTable.PriKey
    121.                     .Type = ADOX.DataTypeEnum.adInteger
    122.                     .ParentCatalog = AcApp     ' Must set before setting properties
    123.                     .Properties("AutoIncrement").Value = True
    124.                 End With
    125.                 Try
    126.                     AcApp.Tables(tdTable.TableName).Columns.Delete(oColumn.Name)
    127.                     AcApp.Tables.Refresh()
    128.                 Catch
    129.                 End Try
    130.                 AcApp.Tables(tdTable.TableName).Columns.Append(oColumn)
    131.                 objTable.Keys.Append(tdTable.TableName, ADOX.KeyTypeEnum.adKeyPrimary, tdTable.PriKey)
    132.             End If
    133.             For iCount = 0 To tdTable.Fields.GetUpperBound(0)
    134.                 If Not bFound(iCount) Then
    135.                     If tdTable.MissingIsFatal(iCount) Then
    136.                         throwError(sDataSet1 & vbCrLf & vbCrLf & "Column " & tdTable.Fields(iCount) & " of type " & tdTable.FieldTypes(iCount) & " not found.")
    137.                         AcConn.Close()
    138.                         Exit Sub
    139.                     Else
    140.                         'We are changing the data, including deleting a column, so make a backup:
    141.                         If objFS.FileExists(sDataSet1) AndAlso Not modsMade Then
    142.                             Try
    143.                                 objFS.CopyFile(sDataSet1, sDataSet & "\backup\" & System.DateTime.Now.ToFileTime().ToString() & ".mdb", True)
    144.                             Catch
    145.                             End Try
    146.                             modsMade = True
    147.                         End If
    148.                         Try
    149.                             AcApp.Tables(tdTable.TableName).Columns.Delete(tdTable.Fields(iCount))
    150.                             AcApp.Tables.Refresh()
    151.                         Catch
    152.                         End Try
    153.                         Select Case tdTable.FieldTypes(iCount)
    154.                             Case ADOX.DataTypeEnum.adVarWChar
    155.                                 objTable.Columns.Append(tdTable.Fields(iCount), tdTable.FieldTypes(iCount), 255)
    156.                             Case Else
    157.                                 objTable.Columns.Append(tdTable.Fields(iCount), tdTable.FieldTypes(iCount))
    158.                         End Select
    159.                     End If
    160.                 End If
    161.             Next
    162.             AcConn.Close()
    163.         End If
    164.     End Sub
    165.  
    166.     Private Sub throwError(ByVal inText)
    167.         MsgBox(inText)
    168.     End Sub
    169.  
    170.     Private Function MakeArray(ByVal ParamArray inObjects() As String) As String()
    171.         Return inObjects
    172.     End Function
    173.  
    174.     Private Function MakeADOXArray(ByVal ParamArray inObjects() As ADOX.DataTypeEnum) As ADOX.DataTypeEnum()
    175.         Return inObjects
    176.     End Function
    177.  
    178.     Private Function MakeBooleanArray(ByVal ParamArray inObjects() As Boolean) As Boolean()
    179.         Return inObjects
    180.     End Function
    181.  
    182.     Private Function VerifyDataSource(ByVal inMDBPath As String) As Boolean
    183.         If objFS.FileExists(inMDBPath) Then
    184.             objConn = New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & _
    185.                 inMDBPath)
    186.             Try
    187.                 objConn.Open()
    188.             Catch
    189.                 Return False
    190.             End Try
    191.         Else
    192.             Return False
    193.         End If
    194.  
    195.         VerifyDataSource = True
    196.     End Function

    Please recognize the author (me), Keith Ratliff, if you use the code or a majority of the code as-is.
    Need to re-register ASP.NET?
    C:\WINNT\Microsoft.NET\Framework\v#VERSIONNUMBER#\aspnet_regiis -i

    (Edit #VERSIONNUMBER# as needed - do a DIR if you don't know)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width