Error while creating table on TableDefs.Append showing Invalid Argument - vba

I am writing a program in Access 2013. If it is the first time they will install the program, it will create an external database (that will be linked later) and will create the tables needed. In the attached code, I am running through an array that has a list of all the tables needed and using an internal (local) table that has all the fields associated with the particular table. It runs through the code and creates all the fields just fine, but once it gets to the line db1.TableDefs.Append newTable it throws the Invalid Argument error. I have searched as much as I can and it appears that my setup is the same as all others and cannot figure out what the issue is.
Function CreateDataTables()
Dim db As Database
Dim db1 As Database
Dim rst As Recordset
Dim tblCount As Integer
Dim rst1 As Recordset
Dim newTable As TableDef
Dim newField As Field
Dim newIdx As Index
Dim newType As Variant
Dim newLength As Variant
Dim newPK As String
Dim sysTable As String
Dim SQLstr As String
Dim x As Integer
Dim tblNames() As Variant
Stop
SQLstr = "SELECT DISTINCT tableName "
SQLstr = SQLstr + "FROM sysdata;"
Set db = DBEngine(0)(0)
Set rst = db.OpenRecordset(SQLstr, dbOpenSnapshot, dbSeeChanges)
tblCount = rst.RecordCount
'Creating array to house table names
ReDim tblNames(tblCount)
tblNames() = rst.GetRows(tblCount)
Set db = Nothing
Set rst = Nothing
Set db = DBEngine(0)(0)
Set rst = db.OpenRecordset("sysdata", dbOpenSnapshot, dbSeeChanges)
'Create database reference to newly created database in prior function
Set db1 = OpenDatabase(dbFileLoc)
For x = 1 To tblCount
'Create new tabledef
Set newTable = db1.CreateTableDef(tblNames(0, (x - 1)))
'Loop through each record of particular table (named in rst) to create each field
Do While rst.Fields("tableName") = tblNames(0, (x - 1))
newType = rst.Fields("typeData")
newLength = rst.Fields("lengthField")
newPK = Nz(rst.Fields("PKey"), "No")
Set newField = newTable.CreateField(rst.Fields("fieldName"))
With newField
.Type = newType
If Not IsNull(newLength) Then .Size = newLength
'If field is indicated as a PK, this will create the PK
If newPK = "Yes" Then
With newTable
newField.Attributes = dbAutoIncrField
Set newIdx = .CreateIndex("PrimaryKey")
newIdx.Fields.Append newIdx.CreateField(tblNames(0, (x - 1)))
newIdx.Primary = True
.Indexes.Append newIdx
End With
End If
End With
'Append field
newTable.Fields.Append newField
rst.MoveNext
If rst.EOF Then Exit Do
Loop
MsgBox "Table " + newTable.NAME + " create", vbOKOnly 'Placed to verify loop was completed and showing table name
'''The line below gives the Invalid Argument error
'''Do not know what is causing this
db1.TableDefs.Append newTable
db1.TableDefs.Refresh
Next

I finally ended up figuring out that the numbers in my sysdata table that was designating the Field Type were wrong. I even got the from a MSDN site. I ran through a loop to determine the actual number of the data types and then placed them in the table and it worked! I also located another bug in the code having to do with the Primary Key. Where I'm appending the Index, in the CreateField I have the Table name and not the Field name. Once I changed that, the PK populated as it should too.

Related

MS Access SQL to Update a RecordSet in Table/Query

I need help regarding the WHERE clause of an SQL statement to UPDATE field values [olnAg] in a query (qryCLFull same as tblCLFull). The field [olnAg] should be updated to the second text of [cellLine] field. So for example if [cellLine] has "
This is the cellLine field
[olnAg] should have
is
Getting the recordset and values has been successful with the code below (with the click of a button on frmSecWord but the issue with UPDATE of the [olnAg] field.
Private Sub btnBySpace_Click()
Dim rsON As DAO.Recordset
Dim rsNN As DAO.Recordset
Dim db2 As Database
Dim sqlON As String
Dim sqlNN As String
Dim newVal As String
Dim arr As Variant
sqlON = " SELECT cellLine FROM qryCLFull"
sqlNN = " SELECT olnAg FROM qryCLFull"
Set db2 = CurrentDb
Set rsON = db2.OpenRecordset(sqlON)
Set rsNN = db2.OpenRecordset(sqlNN)
arr = Split(rsON!cellline, " ")
If IsNull(arr(1)) Then
newVal = arr(0)
Else: newVal = arr(1)
End If
Do Until rsON.EOF
If Not IsNull(rsON.Fields(0).Value) Then
sqlstr = "UPDATE qryCLFull SET qryCLFull.olnAg = '" & newVal & "'
db2.Execute sqlstr
End If
rsON.MoveNext
rsNN.MoveNext
Loop
rsON.Close
rsNN.Close
Set rsNN = Nothing
Set rsNN = Nothing
Set db2 = Nothing
End Sub
Now with this UPDATE and SQL code, all the records of [olNAg] are changed to "is" instead of records WHERE [CellLine] has the text "This is the cellLine field" I have tried severally to adjust the WHERE clause but I haven't been able to write a correct clause. This sql updates [olnAg] for all records in the table instead of just for instances where we find that particular rsON!CellLine. Help will be greatly appreciated.

Excel SQL import - Error 3704 Operation not allowed when object is closed

When trying to execute a sub in an Excel model I receive an error message saying:
Operation not allowed when object is closed.
I have written code like this before in order to import data from a SQL database and never had any problems. I'm guessing the issue with this sub is that the sql query is making a temporary table, with a result from a stored procedure, of which I just want the 4 most recent data points.
The sub looks like this:
Sub sqlImport()
Dim dbConn As ADODB.connection
Set dbConn = New ADODB.connection
dbConn.ConnectionString = "Provider=SQLOLEDB;Integrated Security=SSPI;Network=dbmssocn;Initial Catalog=Funds;Data Source=" & Data_Source_Prod02
dbConn.CursorLocation = adUseServer
dbConn.Open
'Define cell - top left in table
Dim startCell As Range
Set startCell = Import.Range("tableTopLeft")
'Clear the table
Range(startCell, startCell.End(xlDown).End(xlToRight)).ClearContents
'Setup SQL import
Dim CmdSP As New ADODB.Command
CmdSP.CommandType = adCmdText
CmdSP.CommandText = "CREATE TABLE #tmpBus2 (FundID INT, PortfolioDate date, TotalFundValueBillionSEK float, NAVSEK float, FundShares float)" & _
"INSERT INTO #tmpBus2 EXEC Funds.Analysi.Fund_Size #FundId = 4235 " & _
"SELECT TOP 4 PortfolioDate, NAVSEK, FundShares FROM #tmpBus2 ORDER BY PortfolioDate DESC"
CmdSP.ActiveConnection = dbConn
'Execute command
Dim dbList As ADODB.Recordset
Set dbList = CmdSP.Execute
'Print table data
Dim row As Integer, col As Integer
row = 1
While Not dbList.EOF
For col = 0 To dbList.Fields.Count - 1
startCell.Offset(row, col) = dbList(col)
Next col
dbList.MoveNext
row = row + 1
Wend
dbConn.Close
End Sub
The error occurs at
While Not dbList.EOF
Anyone have a solution?
I can't rewrite the stored procedure. And the result I get from the stored procedure is quite a big dataset, that's why I want to just select the top 4 rows.

Updating table with VBA

I have been struggling with getting this code to work for a few days. If you could offer any solutions I would really appreciate it.
Private Sub Command0_Click()
If IsNull(NewSupBox.Value) Or IsNull(NewNumberBox.Value) Then
MsgBox ("All fields must be filled")
GoTo ErrorExit
End If
If Not IsNull(DLookup("SupplierNumber", "SupGenInfo ", "SupGenInfo.SupplierNumber =" & NewSupBox)) = Then
MsgBox ("This supplier number already exists. You can edit the current record on the Edit supplier page.")
GoTo ErrorExit
End If
Dim db As Database
Dim rec As Recordset
Set db = CurrentDb
Set rec = db.OpenRecordset("select * from SupGenInfo")
rec.AddNew
rec("SupplierNumber") = Me.NewSupBox.Value
rec("SupplierName") = Me.NewNameBox.Value
rec.Update
Set rec = Nothing
Set db = Nothing
MsgBox "Records added successfully."
ErrorExit:
End Sub
Edit: Forgot to mention that I am not getting any error message. The command will simply not add a new record to my table.
Edit2: The code above will output the msg "Records Added Successfully" when i remove the following block of code.
Dim db As Database
Dim rec As Recordset
Set db = CurrentDb
Set rec = db.OpenRecordset("SupGenInfo")
rec.AddNew
rec("SupplierNumber") = Me.NewSupBox
rec("SupplierName") = Me.NewNameBox
rec.Update
Set rec = Nothing
Set db = Nothing
It is when this code is included that my command click becomes unresponsive.
I believe, you are reading a table (for display purposes) with your select * ... statement, then you're adding a new record to that list rather than the actual database. When you open OpenRecordset, just supply the table name, not a whole SQL query shebang...
I created a new table, so edit this code to match your parameters/values, otherwise this has been tested to work:
Dim db As Database
Dim rec As Recordset
Set db = CurrentDb
Set rec = db.OpenRecordset("Table1")
rec.AddNew
rec("Field1") = 1234
rec("Field2") = "blah2"
rec("Field3") = "blah3"
rec.Update
Set rec = Nothing
Set db = Nothing
Hope this helps.

Errors with linked tables and Ms Access ( Run-time error '3622' : dbSeeChanges/Identity column )

I am trying to output the name of all linked tables, including their fields which are Date/Time, and that fields values.
The following code can output the first table, field name and their first value, not all values, although when it gets to the next linked table, I get this error
Run-time Error '3622'
You must use the dbSeeChanges option with OpenRecordSet when accessing a SQL Server table that has an IDENTITY column.
Here is my code
Private Sub btnGetFields_Click()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim f As Field
Dim rst As DAO.Recordset
Dim numField As Integer
Set db = CurrentDb
For Each tdf In db.TableDefs
If Left$(tdf.Connect, 9) = "ODBC;DSN=" Then
Set rst = CurrentDb.OpenRecordset(tdf.Name)
numField = rst.Fields.Count
Debug.Print "Table: " & tdf.Name
For index = 0 To numField - 1
If rst.Fields(index).Type = dbDate Then
Debug.Print "Field: " & rst.Fields(index).Name; " Value : "; rst.Fields(index).Value
End If
Next
End If
Next
Set tdf = Nothing
Set db = Nothing
End Sub
I read something that if I'm using sql tables I should use ADO?
Any ideas?
You can continue to use your existing DAO code, just change
Set rst = CurrentDb.OpenRecordset(tdf.Name)
to
Set rst = CurrentDb.OpenRecordset(tdf.Name, dbOpenSnapshot)
That opens a static read-only Recordset, so dbSeeChanges is not required.

Updating Multiple Rows using .edit in vba access 2007

I hope I can ask this right.
I have a listbox on a form (access 2007) and have it set on "simple" so I can multi-select.
I am trying to update multiple columns in a table, based on the selections in the listbox. I have a few textboxes that I want to use as the information to update the table.
I have a loop that is only updating the first record in the table no matter how many items are selected.
I think I understand why it's only updating the first record from my loop but am not sure
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb()
Set rs = db.OpenRecordset("Table1", dbOpenDynaset)
Dim i As Variant
For Each i In Listbox.ItemsSelected
With rs
.Edit
!Col1 = Me.Textbox1
!Col2 = Me.Textbox2
!Col3 = Me.Textbox3
.Update
End With
Next
I assume this is because I am not specifying the "where" in the loop I want my table updated, but I have no idea how to do this in this loop. I would have 3 columns in the listbox (at positions 1, 3 and 4) that all need to be included to specify which records in the table need to be updated. I have tried this as well using an sql query with DoCmd.RunSql but it seems impossible to change the focus of the ListIndex mid-query. Aplogies for my lack of knowledge I am pretty new to visual basic. Please Help
Simplified example how I would give it a try if I understood correctly:
Sub MultiSelect_Listbox()
Dim lCnt as Long
dim lID as long
dim sSQL_Update as string
dim sText_1 as String
dim sText_2 as String
dim sText_3 as String
dim bSuccess as Boolean
sText_1 = me.txt_Textbox_1
sText_2 = me.txt_Textbox_2
sText_3 = me.txt_Textbox_3
With Me.lst_Listbox
For lCnt = 1 To .ListCount
If .Selected(lCnt) Then
lID = .Column(0, lCnt - 1)
'Example update for 1 column
sSQL_Update = "UPDATE T_TABLE SET COL_TEXT_1 = '" & sText_1 & "' WHERE ID = " & lID & ";"
bSuccess = Update_Statement(sSQL_Update)
End If
Next
End With
End Sub
Public Function Update_Statement(sUpdate_Stmt) As Boolean
Dim db As Database
Set db = CurrentDb
db.Execute (sUpdate_Stmt)
Update_Statement = True
End Function