Database Dynamic Table Creation
Encapsulation is taking a beating here:


Public fieldName As String
Public fieldType As ADOX.DataTypeEnum
Public fieldProperties As String
Public fieldPropertiesValue
Public fieldIndex As Boolean
Public fieldUnique As Boolean
Public fieldKey As Boolean



You have a public constructor for assigning these fields, but the instance fields are all Public, which completely defeats the purpose of encapsulation. Fields should be Private, and ideally read-only (I'm a C# guy, not sure how/whether VB.NET implements this but in C# that would be private readonly [type] [name];).

It gets worse:


Public Shared IDOwner As classObjectField = New classObjectField("IDOwner", ADOX.DataTypeEnum.adInteger, "AutoIncrement", True, True, True, True)
Public Shared OwnerAccount As classObjectField = New classObjectField("OwnerAccount", ADOX.DataTypeEnum.adVarWChar, fieldIndex:=True)
Public Shared OwnerName As classObjectField = New classObjectField("OwnerName", ADOX.DataTypeEnum.adVarWChar, fieldIndex:=True)
Public Shared OwnerMail As classObjectField = New classObjectField("OwnerMail", ADOX.DataTypeEnum.adVarWChar, fieldIndex:=True, fieldUnique:=True)



Beyond the constructor [made redundant by public fields], nothing in this class seems to justify having an instance: literally everything is Shared! These public shared object fields are statically initialized but, being fields, any calling code can swap the reference at any time, and because the fields are Shared, every single instance out there suddenly finds itself with a modified IDOwner.

Expose properties, not fields; and only expose Property Get if outside/calling code shouldn't be allowed to tamper with the encapsulated values and references.

OOP is about objects. Shared makes a member belong to a type, not an object instance: Shared is essentially the complete opposite of Object-Oriented.

Seems you mean to use the Public Shared fields as a way to return "canned" instances of this classObjectField class - that's not an awful idea, but then the constructor should be Private.

classObjectField is a bad name for a class. "class" is perfectly redundant and has nothing to do in the name of the type, and class and member names should be PascalCase, so that would be ClassObjectField, and CreateDbTable.



VB.NET isn't just Object-Oriented: it's also *strongly-typed.


Public Shared ArrayTableOwners = New Object(3) {
    IDOwner, OwnerAccount, OwnerName, OwnerMail
}



This is an array of Object references; in .NET everything is an Object - from a simple String to any class instance. Exposing Object on your public API is considered bad practice, because the caller has no idea what they're getting. This would be better (failed encapsulation aside):

Public Shared ArrayTableOwners = New classObjectField(3) {
    IDOwner, OwnerAccount, OwnerName, OwnerMail
}


Now the caller knows they're getting an array of classObjectField objects.


Public Shared Function createDBTable(Cat As ADOX.Catalog, tableName As String, objField As Object) As Boolean



I don't see a reason not to rename Cat to adoxCatalog - it's a catalog, not a cat. And objField is terribly misleading.

The signature says objField As Object, implying ONE object is expected. But then...


    For Each valueField In objField



If you expect an array, make the signature say so! This is what I meant with an object can be literally anything. And for performance reasons you should iterate arrays with a For loop, not For Each.

Actually, keep the For Each. Because you don't need an array here - you need anything that can be iterated. The .NET framework gives you the generic IEnumerable(Of T) interface for that: objField should be plural, to indicate it can "contain" many objects, and then instead of As Object it should be As IEnumerable(Of classObjectField), so that you can't give it a String and still happily compile and run the project.

The function shouldn't return a Boolean. Even your sample usage code doesn't care about the return value:


createDBTable(objCat, "OWNERLIST", ArrayTableOwners)
createDBTable(objCat, "USERLIST", ArrayTableUser)



Truth is, nobody will either, for you've already handled the exception and displayed a message box - and that's not your job!

Instead, make the function a Sub, and let exceptions bubble up the call stack, so that the calling code is responsible for handling exceptions and deciding whether they want to display a message box or log an entry to some text file or whatever. .NET works with exceptions, not return codes.

That said if I had to return a Boolean value for success, I'd default it to False and only switch it to True when I'm absolutely certain that my function did what it had to do. Here you're defaulting to True and switching it to False when an exception is thrown, which only works because you're catching all exceptions - but best practices tell us that we should only be catching the most specific exceptions we can, and let everything else bubble up - and if you did that, your function could return True when it really actually failed. confirm sounds like some flag that would be True when the user confirmed some prompt; success would be a better name for it. But that's moot anyway, as I said it's not that function's job to handle all possible exceptions and display a message box.