I'm new to VBA. Right now, I want to create editable crosstab table using temp table. I have problem when I want to update the normalize table based on edited data. When I run my codes, I get this error, Error 3061: Too Few Parameters.Expected 2.Can somebody help me to check my codes? Thanks in advance
Public Sub Normalize()
Dim rs As DAO.Recordset
On Error GoTo EH
'delete existing data from temp table
CurrentDb.Execute "DELETE * FROM tblNormalize;", dbFailOnError + dbSeeChanges
'get a recordset of the column headers
Set rs = CurrentDb.OpenRecordset("SELECT DISTINCT newvalue FROM Table1;")
Debug.Print
rs.MoveFirst
Do While rs.EOF = False
' "un" crosstab the data from crosstab table into Normalize table
CurrentDb.Execute "INSERT INTO tblNormalize (product, spec, descr,newvalue, Rate )" & Chr(10) & _
"SELECT product,spec,descr, " & rs.Fields("newvalue") & ", [" & rs.Fields("newvalue") & "]" & Chr(10) & _
"FROM tblCrosstab;", dbFailOnError + dbSeeChanges
Debug.Print rs.Fields("newvalue")
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
'update the original normalized dataset
CurrentDb.Execute "UPDATE tblNormalize INNER JOIN Table1 t1 ON (tblNormalize.newvalue = t1.newvalue) " & _
" AND (tblNormalize.product = t1.product) AND (tblNormalize.spec = t1.spec) " & _
" AND (tblNormalize.descr = t1.descr)" & _
" SET Table1.Rate = tblNormalize.Rate;", dbFailOnError + dbSeeChanges
Exit Sub
EH:
MsgBox "Error " & Err.Number & ": " & Err.Description, vbOKOnly, "Error"
End Sub
You are creating a world of hurt for yourself. Apart from that, this:
"INSERT INTO tblNormalize (product, spec, descr,newvalue, Rate )" & Chr(10) & _
"SELECT product,spec,descr, " & rs.Fields("newvalue") & ", [" & rs.Fields("newvalue") & "]" & Chr(10) & _
"FROM tblCrosstab;"
Is going to come out all wrong.
Try:
"INSERT INTO tblNormalize (product, spec, descr,newvalue, Rate )" & _
" SELECT product,spec,descr, " & rs.Fields("newvalue") & ", [" _
& rs.Fields("newvalue") & "] FROM tblCrosstab;"
Also, use Debug.Print to write the string to the immediate window (Ctrl+G) and check if it works in the query design window. That error is usually due to misspelling of missing fields (columns).
Related
I have the following code (which a very helpful person on here wrote based on a previous question). It loops through two tables to determine if an interview is valid and then loops though a gift card table for an unused card. This all works as expected. However, I now realize I need to add a new record to a third table (Receipts) everytime a card is assigned. I have tried using "INSERT INTO..." in the loop but it never puts anything into the Receipts table. The data going to the Receipts table will need to selected from both the Interviews table and the Giftcards table.
On Error GoTo E_Handle
Dim db As DAO.Database
Dim rsInterview As DAO.Recordset
Dim rsGiftcard As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb
strSQL = "SELECT * FROM [SOR 2 UNPAID Intake Interviews]" _
& " WHERE InterviewTypeId='1' " _
& " AND ConductedInterview=1 " _
& " AND StatusId IN(2,4,5,8)" _
& " AND IsIntakeConducted='1' " _
& " ORDER BY InterviewDate ASC;"
Set rsInterview = db.OpenRecordset(strSQL)
If Not (rsInterview.BOF And rsInterview.EOF) Then
strSQL = "SELECT * FROM Giftcard_Inventory_Query" _
& " WHERE CardType=1 " _
& " AND Assigned=0 " _
& " AND Project=3 " _
& " ORDER BY DateAdded ASC, CompleteCardNumber ASC;"
Set rsGiftcard = db.OpenRecordset(strSQL)
If Not (rsGiftcard.BOF And rsGiftcard.EOF) Then
Do
rsGiftcard.Edit
rsGiftcard!DateUsed = Format(Now(), "mm/dd/yyyy")
rsGiftcard!Assigned = "1"
rsGiftcard.Update
db.Execute " INSERT INTO [SOR 2 Intake Receipts] " _
& "(PatientID,GiftCardType,GiftCardNumber,GiftCardMailedDate,InterviewDate,CreatedBy,GpraCollectorID) VALUES " _
& "(rsInterview!PatientID, rsGiftcard!CardType, rsGiftcard!CompleteCardNumber, Now(), rsInterview!InterviewDate, rsInterview!CreatedBy, rsInterview!GpraCollectorID);"
rsGiftcard.MoveNext
rsInterview.MoveNext
Loop Until rsInterview.EOF
End If
End If
sExit:
On Error Resume Next
rsInterview.Close
rsGiftcard.Close
Set rsInterview = Nothing
Set rsGiftcard = Nothing
Set db = Nothing
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sAssignGiftCards", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
I figured it out. Thanks to everyone who pushed me in the correct direction.
On Error GoTo E_Handle
Dim db As DAO.Database
Dim rsInterview As DAO.Recordset
Dim rsGiftcard As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb
strSQL = "SELECT * FROM [SOR 2 UNPAID Intake Interviews]" _
& " WHERE InterviewTypeId='1' " _
& " AND ConductedInterview=1 " _
& " AND StatusId IN(2,4,5,8)" _
& " AND IsIntakeConducted='1' " _
& " ORDER BY InterviewDate ASC;"
Set rsInterview = db.OpenRecordset(strSQL)
If Not (rsInterview.BOF And rsInterview.EOF) Then
strSQL = "SELECT * FROM Giftcard_Inventory_Query" _
& " WHERE CardType=1 " _
& " AND Assigned=0 " _
& " AND Project=3 " _
& " ORDER BY DateAdded ASC, CompleteCardNumber ASC;"
Set rsGiftcard = db.OpenRecordset(strSQL)
If Not (rsGiftcard.BOF And rsGiftcard.EOF) Then
Do
rsGiftcard.Edit
rsGiftcard!DateUsed = Format(Now(), "mm/dd/yyyy")
rsGiftcard!Assigned = "1"
rsGiftcard.Update
db.Execute " INSERT INTO [SOR 2 Intake Receipts] " _
& "(PatientID,GiftCardType,GiftCardNumber,GiftCardMailedDate,InterviewDate,CreatedBy,GpraCollectorID) VALUES " _
& "('" & rsInterview("PatientID") & "', '" & rsGiftcard("CardType") & "', '" & rsGiftcard("CompleteCardNumber") & "', Now(), '" & rsInterview("InterviewDate") & "', '" & rsInterview("CreatedBy") & "', '" & rsInterview("GpraCollectorID") & "');"
rsGiftcard.MoveNext
rsInterview.MoveNext
Loop Until rsInterview.EOF
End If
End If
sExit:
On Error Resume Next
rsInterview.Close
rsGiftcard.Close
Set rsInterview = Nothing
Set rsGiftcard = Nothing
Set db = Nothing
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sAssignGiftCards", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
So I'm a little confused as to how to handle an external database and current database within VBA code. Below is a sub whose purpose is to update the current Access database with unique entries found in the external Access database.
The external SourceDBPath and SelectedTable is passed in, and I specify the external database and table with the string variable SourceDBTable. Then, in the SQL, I try to pull out entries with values that don't match their coresponding field so only unique entries between the two DBs are inserted into the source database.
(For Example, where source = external:
NOT EXIST sourceDB.SelectedTable.Field1 = currentDB.SelectedTable.Field1 And sourceDB.SelectedTable.Field2 = currentDB.SelectedTable.Field2 And sourceDB.SelectedTable.Field3 = currentDB.SelectedTable.Field3, etc.)
SO, my questions are:
1) Do I need to specify the current database within the SQL (like currentDB.table.field), or will it default to the current database if a table or field is called without a prefix (just table or field, like in the code below)?
2) Ultimately, am I going about this in the right way?
My code:
Private Sub UpdateDatabaseTable(SourceDBPath As String, SelectedTable As String)
Dim SourceDBTable As String
On Error GoTo DBError
SourceDBTable = "[;DATABASE=" & SourceDBPath & "]." & SelectedTable
Call DoCmd.RunSQL("INSERT INTO " & SelectedTable & " " & _
"SELECT Field1, Field2, Field3 " & _
"FROM " & SourceDBTable & " " & _
"WHERE NOT EXISTS( SELECT * " & _
"FROM " & SourceDBTable & " " & _
"WHERE (Field1=" & SourceDBTable & ".Field1 And Field2=" & SourceDBTable & ".Field2 And Field3=" & SourceDBTable & ".Field3"));")
GoTo EndSub
DBError:
MsgBox "Database Error!" & vbCrLf & "Error #" & Str(Err.Number) & ": " & Err.Source & vbCrLf & Err.Description, vbExclamation, "Database Error"
EndSub:
End Sub
NOTE: I derived my SQL by extrapolating and modifying the code found in the solution HERE
You have 2 main mistakes in your code, otherwise, it should work.
Don't specify the tablename for each field. Use an alias instead
You want to escape both the tablename, and the database name, not only the database name
Private Sub UpdateDatabaseTable(SourceDBPath As String, SelectedTable As String)
Dim SourceDBTable As String
On Error GoTo DBError
SourceDBTable = "[;DATABASE=" & SourceDBPath & "].[" & SelectedTable & "]"
DoCmd.RunSQL "INSERT INTO " & SelectedTable & " t " & _
"SELECT Field1, Field2, Field3 " & _
"FROM " & SourceDBTable & " s" & _
"WHERE NOT EXISTS( SELECT * " & _
"FROM " & SourceDBTable & " s1 " & _
"WHERE (t.Field1=s1.Field1 And t.Field2=s1.Field2 And t.Field3=s1.Field3));"
GoTo EndSub
DBError:
MsgBox "Database Error!" & vbCrLf & "Error #" & Str(Err.Number) & ": " & Err.Source & vbCrLf & Err.Description, vbExclamation, "Database Error"
EndSub:
End Sub
I've also removed the deprecated Call keyword. Optionally, you can adjust this further by using CurrentDb.Execute, but that's not needed
Following code from my db SENDS data to OTHER db:
strExtract = gstrBasePath & "Program\Editing\ConstructionExtract.accdb"
CurrentDb.Execute "INSERT INTO Bituminous IN '" & strExtract & "' SELECT * FROM ConstructionBIT;"
gstrBasePath is a Global constant declared in a general module:
Global Const gstrBasePath = "\\servernamehere\Crm\Lab\Database\"
You can use literal string path within your procedure.
Following PULLS data from OTHER db:
CurrentDb.Execute "INSERT INTO Employees SELECT * FROM Employees IN '\\servername\filename.accdb'"
This is wrecking my brains for 4 hours now,
I have a Table named BreakSked,
and I this button to update the table with the break end time with this sql:
strSQL1 = "UPDATE [BreakSked] SET [BreakSked].[EndTime] = " & _
Me.Text412.Value & " WHERE [BreakSked].AgentName = " & Me.List423.Value _
& " AND [BreakSked].ShiftStatus = '1'"
CurrentDB.Execute strSQL1
Text412 holds the current system time and List423 contains the name of the person.
I'm always getting this
"Run-time error 3075: Syntax Error (missing operator) in query
expression '03:00:00 am'
Any help please?
EDIT: Thanks, now my records are updating. But now its adding another record instead of updating the record at hand. I feel so silly since my program only has two buttons and I can't figure out why this is happening.
Private Sub Form_Load()
DoCmd.GoToRecord , , acNewRec
End Sub
Private Sub Command536_Click()
strSQL1 = "UPDATE BreakSked SET BreakSked.EndTime = '" & Me.Text412.Value & "',BreakSked.Duration = '" & durationz & "' " & vbCrLf & _
"WHERE (([BreakSked].[AgentID]='" & Me.List423.Value & "'));"
CurrentDb.Execute strSQL1
CurrentDb.Close
MsgBox "OK", vbOKOnly, "Added"
End Sub
Private Sub Command520_Click()
strSql = "INSERT INTO BreakSked (ShiftDate,AgentID,StartTime,Status) VALUES ('" & Me.Text373.Value & "', '" & Me.List423.Value & "', '" & Me.Text373.Value & "','" & Me.Page657.Caption & "')"
CurrentDb.Execute strSql
CurrentDb.Close
MsgBox "OK", vbOKOnly, "Added"
End Sub
You wouldn't need to delimit Date/Time and text values if you use a parameter query.
Dim strUpdate As String
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
strUpdate = "PARAMETERS pEndTime DateTime, pAgentName Text ( 255 );" & vbCrLf & _
"UPDATE BreakSked AS b SET b.EndTime = [pEndTime]" & vbCrLf & _
"WHERE b.AgentName = [pAgentName] AND b.ShiftStatus = '1';"
Debug.Print strUpdate ' <- inspect this in Immediate window ...
' Ctrl+g will take you there
Set db = CurrentDb
Set qdf = db.CreateQueryDef("", strUpdate)
qdf.Parameters("pEndTime").Value = Me.Text412.Value
qdf.Parameters("pAgentName").Value = Me.List423.Value
qdf.Execute dbFailOnError
And if you always want to put the current system time into EndTime, you can use the Time() function instead of pulling it from a text box.
'qdf.Parameters("pEndTime").Value = Me.Text412.Value
qdf.Parameters("pEndTime").Value = Time() ' or Now() if you want date and time
However, if that is the case, you could just hard-code the function name into the SQL and dispense with one parameter.
"UPDATE BreakSked AS b SET b.EndTime = Time()" & vbCrLf & _
As I said in my comment you need to wrap date fields in "#" and string fields in escaped double quotes
strSQL1 = "UPDATE [BreakSked] SET [BreakSked].[EndTime] = #" & _
Me.Text412.Value & "# WHERE [BreakSked].AgentName = """ & Me.List423.Value & _
""" AND [BreakSked].ShiftStatus = '1'"
Here is what I have, I'm trying to take fields from an Access form (data comes from one linked sql table) and insert them into another linked sql table:
StrSQL = "INSERT INTO [dbo_Expense_Projection] ([StatusID],[TravellerUFID],[Email]) " & _
VALUES(" & Me.StatusID & ", " Me.TravellerUFID & ", " Me.SubmitterUFID & ", " Me.email & ")
DoCmd.RunSQL StrSQL
But I am getting this error
Compile error: Sub or Function not defined
I think you are just missing some double quotes:
StrSQL = "INSERT INTO [dbo_Expense_Projection] ([StatusID],[TravellerUFID],[Email]) " & _
"VALUES(" & Me.StatusID & ", " Me.TravellerUFID & ", " Me.SubmitterUFID & ", """ & Me.email & """)"
DoCmd.RunSQL StrSQL
You can try to print the contents of StrSQL and check the query before running it:
Debug.Print StrSQL
but I prefer not to create SQL strings with concatenated values (what happens if Me.StravellerUFID contains a double quote?)
I would suggest you to insert data using DAO:
Dim rs as Recordset
Set rs = CurrentDb.OpenRecordset("dbo_Expense_Projection")
rs.AddNew
rs!StatusID = Me.StatusID
rs!TravellerUFID = Me.TravellerUFID
' ...other fields
rs.Update
rs.Close
There are also some ampersands missing in the SQL-String:
StrSQL = "INSERT INTO [dbo_Expense_Projection] ([StatusID],[TravellerUFID],[Email]) " & _
"VALUES(" & Me!StatusID & ", " & Me!TravellerUFID & ", " & Me!SubmitterUFID & ", """ & Me!email & """)"
And I think you should use exclamation mark between "Me" and fieldname. But I do not want to argue with the experts here about that... ;)
Here is what ended up working:
Dim StrSQL As String
StrSQL = "INSERT INTO dbo_Expense_Projection (StatusID,TravellerUFID,Email)
VALUES('" & Form!StatusID & "','" & Form!TravellerUFID & "','" & Form!Email & "')"
DoCmd.SetWarnings False
DoCmd.RunSQL StrSQL
DoCmd.SetWarnings True
I'm trying to write a query in MS Access 2010 in order to use it to print a report, but it gives me "missing parameter" error in "set qd" line, hereunder is the code i wrote, can you please help me and tell me what is wrong with my code:
`Private Sub Command5_Click()
Dim qd As DAO.QueryDef
Dim rs As DAO.Recordset
Dim strSql As String
Dim strFrom, strTo As String
strFrom = [Forms]![FrmPrintSelection]![txtFrom]
strTo = [Forms]![FrmPrintSelection]![txtTo]
strSql = "SELECT tblInvoiceHead.CustomerNumber,
tblCustomers.AccountName,tblCustomers.Address,
tblCustomers.Phone1, tblCustomers.Phone2," _
& "tblCustomers.Mobile1, tblCustomers.Mobile2, tblInvoiceHead.InvoiceNumber,
tblInvoiceHead.InvoiceDate, tblInvoiceHead.TotalInvoice," _
& "tblInvoiceHead.CashDiscount, TblInvoiceDetails.Item, TblInvoiceDetails.Unit,
TblInvoiceDetails.Qtn, TblInvoiceDetails.Price," _
& "TblInvoiceDetails.[Discount%], TblInvoiceDetails.CashDiscount,
TblInvoiceDetails.NetUnitPrice, TblInvoiceDetails.TotalPrice, tblInvoiceHead.InvoiceType" _
& "FROM (tblCustomers INNER JOIN tblInvoiceHead ON tblCustomers.AccountNumber =
tblInvoiceHead.CustomerNumber) INNER JOIN TblInvoiceDetails" _
& "ON tblInvoiceHead.InvoiceNumber = TblInvoiceDetails.InvoiceNumber" _
& "WHERE (((tblInvoiceHead.InvoiceNumber) Between " & strFrom & " And " & strTo & "))"
Set qd = CurrentDb.CreateQueryDef("RepInv", strSql)
Set rs = qd.OpenRecordset
'DoCmd.OpenQuery "repinv", strSql
Reports!repinvoicetest.RecordSource = "repinv"
DoCmd.OpenReport "repinvoicetest", acViewPreview
End Sub
`
Usually the error "missing parameter" means that you spelled one of your columns wrong. If you take your sql and paste it into a new query (temp, don't save) and run it, the misspelled column will pop up a window asking you to provide a value for that "parameter" (because MSAccess is assuming that you never would misspell a column name).
In your query above, you might have copy/pasted it wrong, but if not, then you don't have enough spaces between your words as you continue them on the next line. For instance, your SQL string would end up having some stuff in it like "InvoiceTypeFROM", because you didn't have an extra (necessary) space in there.
Try this query instead:
strSql = "SELECT tblInvoiceHead.CustomerNumber, " _
& " tblCustomers.AccountName,tblCustomers.Address, " _
& " tblCustomers.Phone1, tblCustomers.Phone2, " _
& " tblCustomers.Mobile1, tblCustomers.Mobile2, tblInvoiceHead.InvoiceNumber, " _
& " tblInvoiceHead.InvoiceDate, tblInvoiceHead.TotalInvoice, " _
& " tblInvoiceHead.CashDiscount, TblInvoiceDetails.Item, TblInvoiceDetails.Unit, " _
& " TblInvoiceDetails.Qtn, TblInvoiceDetails.Price, " _
& " TblInvoiceDetails.[Discount%], TblInvoiceDetails.CashDiscount, " _
& " TblInvoiceDetails.NetUnitPrice, TblInvoiceDetails.TotalPrice, " _
& " tblInvoiceHead.InvoiceType " _
& " FROM (tblCustomers INNER JOIN tblInvoiceHead " _
& " ON tblCustomers.AccountNumber = tblInvoiceHead.CustomerNumber) " _
& " INNER JOIN TblInvoiceDetails " _
& " ON tblInvoiceHead.InvoiceNumber = TblInvoiceDetails.InvoiceNumber " _
& " WHERE (((tblInvoiceHead.InvoiceNumber) Between " & strFrom & " And " & strTo & "))"
Notice how I added a lot of unncessary spaces at the begining and end of each line. All of those extra spaces will be ignored. However, if there are too few, then you will get errors. It is a simple trick that I stick-with.