How to use "INSERT INTO" command from Access VBA to Sharepoint - ms-access

I'm using a MS Access database linked with a Sharepoint Server. MS Access Forms as FrontEnd and Sharepoint Lists as BackEnd.
Today i can see all the informations from the lists using access forms, without problems.
What i need:
I'm trying to insert new registers on the list, using a SQL command: "INSERT INTO..."
if there is another possibility to insert the record in the list, may be useful
What's happening?
When i call the DoCmd.RunSQL(txtsql), i receive a runtime error 3999 saying i'm disconnected from the server.
My code now:
I tried using recordsets, but didn't succeed.
I need to run this SQL many times, changing the string "txtSql" inside a loop. Like this:
Dim MaxSonda As Integer
'Get the max ID from the list
MaxSonda = Nz(DMax("IdSonda", "Sondas", "((Sondas.[Tipo Sonda])<>1 Or (Sondas.[Tipo Sonda]) Is Null)"), 0)
MsgBox "MaxSonda = " & MaxSonda
'Run the code for each "sonda"
Do While MaxSonda > 1
If Nz(DLookup("[Tipo Sonda]", "Sondas", "Sondas!IdSonda = " & MaxSonda), 1) <> 1 Then
DoCmd.OpenTable "Resumo", acViewNormal, acAdd
DoCmd.GoToRecord acDataTable, "Resumo", acNewRec
txtSql = "INSERT INTO Resumo ( Data, Sonda, Status ) SELECT #" & LastData + 1 & "#, " & MaxSonda & ", 0;"
MsgBox txtSql
DoCmd.RunSQL txtSql
DoCmd.Close acTable, "Resumo", acSaveYes
End If
MaxSonda = MaxSonda - 1
Loop
P.S.: The MsgBox is just for check the steps
thanks for help

You don't need to open the list/table to insert a record. I don't know why you are using loop to insert rows but if that is your intention try this SQL_COMMAND within your loop:
If Nz(DLookup("[Tipo Sonda]", "Sondas", "[IdSonda] = " & MaxSonda), 1) <> 1 Then
txtSql = "INSERT INTO Resumo ( Data, Sonda, Status ) VALUES ('" & LastData + 1 & "'," & MaxSonda & ",0);"
MsgBox txtSql
DoCmd.RunSQL txtSql
End If
also note #tags are used to insert dates in Access, if you are intend to save dates save them in international format as strings like
vba.Format$([date_field],"yyyy-mm-dd hh:mm:ss")
this way you can just save as string without using the #tags.

Maybe this could help somebody. I did have the same problem and i solved it removing the sharepoint list from access and add it again. Take a seconds to make a sql query but it works.
greet

Related

Updating Issues with MySQL and Access

So this is a problem which started happening a day ago.
I have an Access database file which stores a form for creating jobs, updating job sector, and deleting it from the MySQL table.
There are two tables that are used for this form: a local one stored in Access called "Job Route" and another through MYSQL ODBC Driver, ANSI 5.3 version called "To Do". The local table stores user-submitted data containing information on all job areas and state, while the MYSQL table only shows one job area at a time.
When a new entry is created, the text box details from the Access form are being stored onto both tables. Where each job contains up to 4 different sectors (e.g. [start date], [area1], [person in charge 1], [description1], ... [area4], [person in charge 4], [description4]). Whenever the data is being updated to its next state, in the local table only the job counter field is incremented, while every field in the MYSQL table called "To Do" is updated to its next state fields.
Connection to the server is good, and everything was running fine until an issue popped up in the updating function.
Basically how that function works is that on a listbox control, all current job data is being queried from the "To Do" table. The user selects an entry, and hits a button which loads the next sector information data from "Job Route", onto various textbox controls. The user can change those textbox inputs if they want - the only thing that is changed when the function runs is the "To Do". The information in "Job Route" remains the same. When the user hits the update button, the next sector field data is updated to "To Do", while only a counter in "Job Route" is being incremented to signify the current sector.
My problem is this. For the most part almost everything is running fine, but for one of the fields in "To Do" table does not update with the values it should from the textbox. So for instance if the textbox control was set to "Wyntile", the field name should be set to that, but for some reason a different value shows up instead, example="Apples". Here is the code:
Private Sub moveJob2_Click()
'get the job number
JobNum = Text31
CurrArea = DLookup("[Area]", "[To_Do]", "[Job_Number] =""" & JobNum & """")
area1 = DLookup("[Area1]", "[Job Route]", "[Job Number] =""" & JobNum & """")
area2 = DLookup("[Area2]", "[Job Route]", "[Job Number] =""" & JobNum & """")
area3 = DLookup("[Area3]", "[Job Route]", "[Job Number] =""" & JobNum & """")
area4 = DLookup("[Area4]", "[Job Route]", "[Job Number] =""" & JobNum & """")
'get what the current area is
Current = DLookup("[Current]", "[Job Route]", "[Job Number] =""" & JobNum & """")
'if the current area is the first area then check to make sure there is a second
'if so, then set the new area to it
If Current = 1 Then
If area2 = "---" Then
MsgBox area1 + " was the last area in the route. The job cannot be moved."
Exit Sub
End If
newArea = area2
ElseIf Current = 2 Then
If area3 = "---" Then
MsgBox area2 + " was the last area in the route. The job cannot be moved."
Exit Sub
End If
newArea = area3
ElseIf Current = 3 Then
If area4 = "---" Then
MsgBox area3 + " was the last area in the route. The job cannot be moved."
Exit Sub
End If
newArea = area4
Else
MsgBox area4 + " was the last area in the route. The job cannot be moved."
Exit Sub
End If
'set up link to both the To_Do and Job Route tables
Dim dbJobNumbers As DAO.Database
Dim rstJob As DAO.Recordset
Dim jobRoute As DAO.Recordset
Set dbJobNumbers = CurrentDb
Set rstJob = dbJobNumbers.OpenRecordset("To_Do")
Set jobRoute = dbJobNumbers.OpenRecordset("Job Route")
' >> Edit the job in the To_Do table
****' ERROR: Out of all these, only [Person_In_Charge] is being set to something
****' completely different from Text33, which wasn't changed by the user.
rstJob.FindFirst "[Job_Number]=""" + Text31 + """"
rstJob.Edit
rstJob("[Area]").Value = newArea
rstJob("[Person_In_Charge]").Value = Text33
rstJob("[Equipment]").Value = Text37
rstJob("[Description]").Value = Text35
rstJob.Update
'update the current area for the Job Route
jobRoute.FindFirst "[Job Number]=""" + Text31 + """"
jobRoute.Edit
jobRoute("[Current]").Value = CInt(Current) + 1
jobRoute.Update
'success message
MsgBox Text31 + " has been moved from " + CurrArea + " to " + newArea + "."
'requery the listboxes
Dim selectParas As String
selectParas = "SELECT [a].[Job_Number] as [Job Number], [a].[Description], [a].[Person_In_Charge] as [Person in Charge], [a].[Area] " & _
" FROM [To_Do] As [a];"
listRemoveJobs.RowSource = selectParas
listRemoveJobs.Requery
listChangeJobArea.RowSource = selectParas
listChangeJobArea.Requery
End Sub
The function has been running fine, and even now when I test it again it runs as programmed. Though today I recieved the "ODBC Insert on 'To Do' has failed" error, but that's for a different function. So I was thinking that something is wrong in the ODBC connection/MySQL table, but when I checked the table in phpmyadmin for the most part that table follows a similar format of other mysql tables used in Access.
Also to note, the person who had told me this issue runs on an old Windows XP version, where once before on that computer there were known issues of the defined OBDC ANSI 5.3 Driver instance completely disappearing from Access' Data Source list before. (The driver is still installed on Windows). That time, apparently the driver instance later re-appeared again magically in the D.S. list when that computer was restarted. ... I know this is rather long, but I can't seem to find the cause of why this updating error in Access is happening. Is there a known issue of ODBC having stability issues in connection? Why is the value changed to something completely different on update? Any insight would be appreciated.
While there is no reproducible example to help with your specific situation, consider running pure SQL UPDATE queries with binded parameters. Your area conditional logic can be rewritten into nested IIF expression. Possibly, this will simplify your problem and streamline your needs without DLookup or multiple recordset updates. Also, your re-assignment to RowSource is not necessary. Below utilizes parameterization, a best practice when running SQL in application layer:
SQL (save both below as Access queries)
mySavedJoinUpdateQuery
PARAMETERS Text33Param Text(255), Text35Param Text(255)
Text37Param Text(255), JobNumberParam Text(255);
UPDATE [To_Do] d
INNER JOIN [Job Route] r
ON d.Job_Number = r.Job_Number
SET [Area] = IIF([Current] = 1 AND [Area2] != '---', [Area2],
IIF([Current] = 2 AND [Area3] != '---', [Area3],
IIF([Current] = 3 AND [Area4] != '---', [Area4], [Area1)
)
),
[Person_In_Charge] = Text33Param,
[Equipment] = Text37Param,
[Description] = Text35Param
WHERE r.[Job Number] = JobNumberParam;
mySavedSimpleUpdateQuery
PARAMETERS JobNumberParam Text(255);
UPDATE [Job Route] r
SET r.[Current] = r.[Current] + 1
WHERE r.[Job Number] = JobNumberParam;
VBA
Private Sub moveJob2_Click()
Dim qdef As QueryDef
Dim selectParas As String
' UPDATE JOIN QUERY
Set qdef = CurrentDb.QueryDefs("mySavedJoinUpdateQuery")
qdef!JobNumberParam = Text31
qdef!Text33Param = Text33
qdef!Text35Param = Text35
qdef!Text37Param = Text37
qdef.Execute dbFailOnError
Set qdef = Nothing
' UPDATE SIMPLE QUERY
Set qdef = CurrentDb.QueryDefs("mySavedSimpleUpdateQuery")
qdef!JobNumberParam = Text31
qdef.Execute dbFailOnError
Set qdef = Nothing
' REQUERY LIST BOXES
listRemoveJobs.Requery
listChangeJobArea.Requery
End Sub

MS Access VBA working with AbsolutePosition

I have a situation where I need to run a pass through append/insert query of values from MS-Access 2010 VBA to SQL Server 2012, which I have working fine, but that may at some future point need to work with over 1000 records, so I need to make sure my code will accommodate that. My idea was to use modulo to determine when I hit the 1000th record to add a new ; insert ...., to the pass through string, not sure if it's the best approach anyway but I'm struggling to work with .AbsolutePosition.
So far I have:
Dim rs As DAO.Recordset
Dim strsql As String
Set rs = CurrentDb.OpenRecordset("MyTable")
strsql = "insert into [dbo].[SomeTable](field1, field2) values"
If Not (rs.EOF And rs.BOF) Then
rs.MoveFirst
Do Until rs.EOF = True
msgbox rs.AbsolutePosition 'error with whatever I do here
'Something like the below is what I actually want to get to
'If rs.AbsolutePosition Mod 999 = 0 Then strsql = Left(strsql, Len(strsql) - 1) & "; insert into [dbo].[SomeTable](field1, field2) values"
strsql = strsql & " (" & rs!field1 & "," & rs!field2 & "'),"
rs.MoveNext
Loop
strsql = Left(strsql, Len(strsql) - 1) & ";"
Else
MsgBox "No Data"
Exit Sub
End If
I keep getting an error operation is not supported for this type of object when either trying to return or perform a calculation using rs.AbsolutePosition
From the documentation:
The AbsolutePosition property isn't available on forward–only–type Recordset objects, or on Recordset objects opened from pass-through queries against Microsoft Access database engine-connected ODBC databases.
Why not simply use a running counter?
Do Until rs.EOF = True
i = i + 1
If i Mod 1000 = 0 Then
' ...
Edit
/Fail. Your rs isn't from a Pass-Through query, so that's not the issue. Nevertheless, the running counter seems like the easiest option.

DoCmd.OutputTo fails intermitantly on different items within a list - Error 2501

The DoCmd.OutputTo command fails on different items within a list with Error 2501. Pictured below is my subroutine (much code removed). It loops through a list of vendors, sending invoices via email. We are running Access 365 with linked tables to a SQL Server 2008R2. Each time I run the routine, the code fails on a different supplier (sometimes no failures). There is one attachment per outgoing email. Each attachment has a unique file name. Attachments are written to the hard drive to avoid network lag. The report is fairly complex, sometimes calling functions which hit linked tables. Need help with how to make the function more robust to not fail.
Sub EmailInvoices()
InvFilePath = "C:\temp\"
On Error GoTo EmailInvoicesProblem
' loop through the list of suppliers, this invoice type, this date
For x = 1 To SupplierCount
SQLStr3 = "SELECT * from " & RptTypeDtlQry & WhereClause
DoCmd.OpenReport RptName, acViewDesign, , , acHidden
Set Inv_rpt = Reports(RptName)
Inv_rpt.RecordSource = SQLStr3
Inv_rpt.Caption = "Supplier " & rst!supplier_code & " " & InvType & " Invoices"
DoCmd.Close acReport, RptName, acSaveYes
'image the invoice, attach the invoice to the email, and then delete the image
InvFileName = InvFilePath & rst!supplier_code & ".pdf"
TryAgain:
DoCmd.OutputTo acOutputReport, RptName, acFormatPDF, InvFileName, False
objOutlookMsg.Attachments.Add (InvFileName)
fso.DeleteFile (InvFileName)
' send all the invoices of this supplier, this invoice type, this date in a single email.
objOutlookMsg.Send
NextSupplier:
rst.MoveNext
Next x
rst.Close
Exit Sub
End Sub 'EmailInvoices()
Perhaps the report file name has invalid characters? (would have posted this as a comment but don't have enough points)
Can you put some Debug.Print statements in to show what the variables are when it works and when it doesn't?

currentdb execute does not insert

I'm having trouble with Access VBA. I made the following code to insert some data to my SQL DB.
Private Sub btnFilmKijkenKlant_Click()
CurrentDb.Execute "INSERT INTO watchhistory (movie_id, customer_mail_address, watch_date, price, invoiced) VALUES (" & movie_id.Value & ", '" & Me.txtEmail & "', Date(),'" & price.Value & "', '0')"
End Sub
When the user hits the button I want some data to be transferred to the DB.
I don't get any errors but it just doesn't insert...
I made txtEmail field for testing. I got an e-mail field in another form that I want to use as customer_mail_address.
When I include the dbFailOnError option with CurrentDb.Execute, Access complains "ODBC Call failed", but I don't understand why.
Dim db as Database
Set db = CurrentDb()
db.execute(......)

How can I check for null values in Access?

I am new to Access. I have a table full of records. I want to write a function to check if any id is null or empty. If so, I want to update it with xxxxx.
The check for id must be run through all tables in a database.
Can anyone provide some sample code?
I'm not sure if you are going to be able to find all tables in the database with Access SQL. Instead, you might want to write up some VBA to loop through the tables and generate some SQL for each table. Something along the lines of:
update TABLE set FIELD = 'xxxxxx' where ID is null
Check out the Nz() function. It leaves fields unaltered unless they're null, when it replaces them by whatever you specify.
For reasonable numbers and sizes of tables, it can be quicker to just
open them
sort by each field in turn
inspect for null values and replace manually
It's good practice to find out where the nulls are coming from and stop them - give fields default values, use Nz() on inputs. And have your code handle any nulls that slip through the net.
I'm calling it the UpdateFieldWhereNull Function, and shown is a Subroutine which calls it (adapted from http://www.aislebyaisle.com/access/vba_backend_code.htm)
It updates all tables in the DbPath parameter (not tested, handle with care):
Function UpdateFieldWhereNull(DbPath As String, fieldName as String, newFieldValue as String) As Boolean
'This links to all the tables that reside in DbPath,
' whether or not they already reside in this database.
'This works when linking to an Access .mdb file, not to ODBC.
'This keeps the same table name on the front end as on the back end.
Dim rs As Recordset
On Error Resume Next
'get tables in back end database
Set rs = CurrentDb.OpenRecordset("SELECT Name " & _
"FROM MSysObjects IN '" & DbPath & "' " & _
"WHERE Type=1 AND Flags=0")
If Err <> 0 Then Exit Function
'update field in tables
While Not rs.EOF
If DbPath <> Nz(DLookup("Database", "MSysObjects", "Name='" & rs!Name & "' And Type=6")) Then
'UPDATE the field with new value if null
DoCmd.RunSQL "UPDATE " & acTable & " SET [" & fieldName & "] = '" & newFieldValue & "' WHERE [" & fieldName & "] IS NULL"
End If
rs.MoveNext
Wend
rs.Close
UpdateFieldWhereNull = True
End Function
Sub CallUpdateFieldWhereNull()
Dim Result As Boolean
'Sample call:
Result = UpdateFieldWhereNull("C:\Program Files\Microsoft Office\Office\Samples\Northwind.mdb", "ID", "xxxxxx")
Debug.Print Result
End Sub