Need to Pass multiple results from query back into one memo cell - sql

I have been all over the web for days searching for a way to accomplish the following, and I am praying some experts can help me figure it out! I have a client that wants to dynamically build a shipping "approval" email by pulling various text statements in, based on the results of queries. The shipping details will be in one table, and the statements will be in another table. There could be multiple statements returned for each shipment (e.g. several training statements, several general statements). Each of these statements needs to be added into a memo cell (created to hold each type of statement) which will then be pulled into the email template for that shipment. The table structures are as follows.
Shipment_Table
*ID
*Shipment Type - Query Criteria
*Material Category - Query Criteria
*Permit Required - Query Criteria
*General Statement (memo field to hold all general statements that match criteria)
*Training Statement (memo field to hold all training statements that match criteria)
*Approval Statement (memo field to hold all approval statements that match criteria)
Statement_Table
*Statement Type (e.g. General, Training, Approval)
*Shipment Type - Query Criteria
*Material Category - Query Criteria
*Permit Required - Query Criteria
I successfully have a query (titled StatementSearch) that joins the two and pulls in the correct statements. I can't figure out how to take the multiple query results and append them into the memo cells for the shipment.
The code that has come close is below. It seems to correctly run my query and return the results, but is not putting the results into the memo field for my test record (ID =1 just to test the code, it will eventually run off of a form and the statements will generate off the click of a button).
I hope this isn't too confusing!
Option Explicit
Function StatementUpdate()
Dim dbs As DAO.Database
Dim rstStatements As DAO.Recordset
Dim rstCBG As DAO.Recordset
Set dbs = CurrentDb()
Set rstStatements = dbs.OpenRecordset("StatementSearch")
Set rstCBG = dbs.OpenRecordset("select [St_General]from
[Cross_Border_Grid_Table] where [ID]= 1")
rstCBG.MoveFirst
'loop through each record in the CBG that matches select query
Do Until rstCBG.EOF
rstStatements.MoveFirst
Do Until rstStatements.EOF
rstCBG.Edit
rstCBG![St_General] = rstStatements
rstCBG.Update
rstStatements.MoveNext
Loop
rstCBG.MoveNext
Loop
rstCBG.Close
rstStatements.Close
Set rstStatements = Nothing
Set rstCBG = Nothing
Set dbs = Nothing
Debug.Print "Done"
End Function

Try this for your loops
Dim concStatement as String
rstCBG.MoveFirst
Do Until rstCBG.EOF
concStatement = ""
rstStatements.MoveFirst
Do Until rstStatements.EOF
concStatement = concStatement & vbCrLF & rstStatements(0)
rstStatements.MoveNext
Loop
rstCBG.Edit
rstCBG![St_General] = concStatement
rstCBG.Update
rstCBG.MoveNext
Loop
I assume, your "StatementSearch" is a query that finds all statements according to ID=1. If there is more than one recordsets "rstCBG", you have to requery rstStatements in each loop step.
EDIT:
Changed rstStatement to rstStatement(0).
Also rstStatements(0) could be wrong: Change index = 0 to the index of the field in your query. As stated, the query is not visible in your question, so I do not know the right index number.

Related

Return Query Value Using VBA function in Access

I'm currently working on a project and I've been having trouble trying to get a function that is able to return the value of a query, which I do need in order to display it on a textbox.
The current code is like this:
Public Function rubrieknaamSQL() As String
Dim rst As DAO.Recordset
Dim strSQL As String
strSQL = "SELECT T_Train.trainPlate, T_Category.categoryName FROM T_Category INNER JOIN T_Train ON T_Category.id = T_Train.category_id WHERE (((T_Train.trainPlate)=[Forms]![F_Comboio]![Combo_Search_Comboio]));"
Set rst = CurrentDb.OpenRecordset(strSQL)
rubrieknaamSQL = rst!categoryName
rst.Close
End Function
I should say that the code is copied from other publisher and I do not own its rights. However, it still won't work when I try to run it and the error displayed goes like this:
Run-Time Error 3061 : Too few parameters. Expected 1
and it happens in Set rst command.
For a SELECT query to set a recordset object, concatenate variable:
" ... WHERE T_Train.trainPlate=" & [Forms]![F_Comboio]![Combo_Search_Comboio]
If trainPlate is a text field, need apostrophe delimiters (date/time field needs # delimiter):
" ... WHERE T_Train.trainPlate='" & [Forms]![F_Comboio]![Combo_Search_Comboio] & "'"
For more info about parameters in Access SQL constructed in VBA, review How do I use parameters in VBA in the different contexts in Microsoft Access?
There are ways to pull this single value without VBA.
make combobox RowSource an SQL that joins tables and textbox simply references combobox column by its index - index is 0 based so if categoryName field is in third column, its index is 2: =[Combo_Search_Comboio].Column(2)
include T_Category in form RecordSource and bind textbox to categoryName - set as Locked Yes and TabStop No
build a query object that joins tables without filter criteria and use DLookup() expression in textbox
=DLookup("categoryName", "queryname", "trainPlate='" & [Combo_Search_Comboio] & "'")

How do I update a single field of a single record with data from another table with VBA in MS Access

In MS Access, I have a table called "Products". It contains quality testing parameters, as well as fields for "Part_No" and "Last_Test_Date". The "Last_Test_Date" field being the last time that the specific product was tested.
I have another table (Trend001) that is live updated with the actual test data from a hydraulic test machine, as well as the "Part_No" being tested and a current "Time_Stamp".
I would like to update the "Last_Test_Date" of the specific "Part_No" being tested with the "Time_Stamp" from the "Trend001" table.
That way the user knows the last time that the Part was tested.
I found this on Stackoverflow, but I don't know enough about the language to apply it to my project.
Updating existing records and adding new records in table (MS Access VBA)
'''
Public Sub UpdateExistingRecords()
On Error GoTo ErrTrap
Dim rs As DAO.Recordset
Set rs = CurrentDb().OpenRecordset("SELECT * FROM tblTempData", dbOpenSnapshot)
Set rsCommon = CurrentDb().OpenRecordset("SELECT * FROM tblCommon", dbOpenDynaset)
Dim idx As Long
For idx = 1 To rs.RecordCount
If ExistsInCommon(rs![Item ID]) Then
If Not Update(rs) Then
MsgBox "Failed to update.", vbExclamation
GoTo Leave
End If
'''
You don't need VBA to do the update, just use a SQL update. This SQL will update all the parts in the Products table that exist in the Trend001 table.
UPDATE Products INNER JOIN Trend001 ON Products.Part_No = Trend001.Part_No
SET Products.Last_Test_Date = Trend001.Time_Stamp;
PLEASE - Remember to back up your database before running this update. A small typo could delete your data.

Setting listboxes in MS access form - row by row

I have a requirement in MS Access where a table is displayed as several rows in the form. I have created one form detail record(several fields) that will repeat for each row in the Table1. Lets say I have five columns in the Table1. Based on Column3 value, I would like to have a list of value for Column4 and Column5 during form_load. I have also created a separate Table2 to establish relationship between Column3, Column4 and Column5. I have set up Event procedure to populate the values using sub function. The challenge I have is, not being able to set up different listbox 'value list' for different rows. Any tips on populationg form fields IMRecomExIns and AmendReasonExIns by processing each row in Table1 would be a great help.
Private Sub IMRecomExIns_Click()
Dim CoverType As String
Dim ListRecomm As String
Dim ListAmend As String
Dim db As DAO.Database
Dim tablevar As Recordset
Set db = CurrentDb
Set tablevar = db.OpenRecordset("Table2")
CoverType = "*" & Me.CoverTypeExIns.Value & "*"
ListRecomm = ""
ListAmend = ""
If tablevar.EOF = False And tablevar.BOF = False Then
tablevar.MoveFirst
Do Until tablevar.EOF
If tablevar!CoverType Like CoverType Then
ListRecomm = tablevar!Recommendation
ListAmend = tablevar!AmendReason
tablevar.MoveLast
End If
tablevar.MoveNext
Loop
End If
Me.IMRecomExIns.RowSourceType = "Value list"
Me.IMRecomExIns.RowSource = ListRecomm
Me.AmendReasonExIns.RowSourceType = "Value list"
Me.AmendReasonExIns.RowSource = ListAmend
End Sub
1) I have stored all the value list in a single cell. For example tablevar!Recommendation will have all the values for Me.IMRecomExIns.RowSource, which means the output is will look like "Rec1";"Rec2";"Rec3";etc... Same applies for tablevar!AmendReason "AR1";"AR2';"AR3";ETC... Understand this is not the normalized form of storing data. I want to POC to work before building a full solution with normalized tables.
2) Answered earlier.. the rowsource will be set with all the possible values at the first match, so no point in going all the way to the end of the table
3) CoverTypeExIns is a string, Table 2 have many different possibilities such as "Mortgage Income" and "Family Income", however the Recommendation and Amendreason are same for all "Income" category that comes from Table1. Thats why the wildcard search.
My problem is not with setting the RowSource for a single row, but setting up RowSource for multiple occurrence in of the same IMRecommmendation and AmendReason in MS Access screen.
Here is the design view of the form. This form is linked to MS Access table. For multiple rows the Detail record will repeat itself as many times.
An example of two rows displayed in the screen.
I'm not sure exactly what you are asking/trying to do here.
I can see at several problems with the code that you have:
You are using tablevar.MoveLast in the loop, whic would automatically take you to the end of the recordset.
Also, you are not concatenating (joining together) ListRecomm/ListAmend, you are just setting them equal to a value, so each loop that matches will overwrite any previous value.
Finally, I am not sure what you are doing with trying to find CoverTypeExIns - you are using LIKE, which would indicate that it is text, but not wrapping the value in single quotes. If it is a numeric value, then you should be using "=".
However, rather than opening a recordset, looping it and checking for a match to build up a list of values, it is better to just set the RowSource of listboxes equal to a SQL string (effectively a query).
Something like (assuming CoverType is numeric):
Private Sub IMRecomExIns_Click()
Dim strSQL As String
strSQL = "SELECT Recommendation FROM Table2 WHERE CoverType=" & Me!CoverTypeExIns
Me!AmendReasonExIns.RowSource = strSQL
End Sub
I prefer to declare a string to hold the SQL statement rather than setting the .RowSource directly, as it makes troubleshooting easier.
Regards,
Based on the new information given, below is some VBA code that opens up a recordset based on the information entered in "Cover", and then sets the .RowSource property of the two combo boxes to be the value lists. In my example, don't bother setting the .RowSourceType, as this should be done at design time:
Private Sub IMRecomExIns_Click()
Dim db As DAO.Database
Dim rsData As DAO.Recordset
Dim strSQL As String
Set db = DBEngine(0)(0)
strSQL = "SELECT Recommendation, AmendReason FROM Table2 WHERE CoverType LIKE '*" & Me!cboCover & "*';"
Set rsData = db.OpenRecordset(strSQL)
If Not (rsData.BOF And rsData.EOF) Then
Me!IMRecomExIns.RowSource = rsData!Recommendation
Me!AmendReasonExIns.RowSource = rsData!AmendReason
End If
rsData.Close
Set rsData = Nothing
Set db = Nothing
End Sub
As I have previously stated, you should really normalize the design of your database now, rather than getting in so far that it requires a major re-write.
Regards,

SQL Select statement suddenly retrieving wrong value only when selecting form another query

I have a order creation form in an Access database where the user selects a product and VBA code is triggered with SQL select statement to retrieve the current availability of that product. This is how it's set up:
I have a Packages table where products batches are added to inventory.
I have an OrderDetail table where items from product batches are allocated to orders.
I have a InventoryPrep query with a the total packaged per batch and field that sums the number of allocated products per batch from the OrderDetail table.
Then I have an Inventory query that that has a calculated field that takes the TotalPackaged field from the InventoryPrep query and subtracts the TotalAllocated field from the InventoryPrep query.
Here is the VBA code in my form, triggered by an update to the [Batch] combo box:
Dim VBatch As String
VBatch = Me.Batch.Value
Dim VAvail As Double
Dim mySQL As String
Dim conn1 As ADODB.Connection
Set conn1 = CurrentProject.Connection
Dim rs1 As New ADODB.Recordset
rs1.ActiveConnection = conn1
mySQL = "SELECT Available FROM Inventory WHERE BatchID = " & "'" & VBatch & "'"
rs1.Open mySQL
rs1.MoveFirst
VAvail = rs1.Fields("Available").Value
Forms!ChangeOrders.ChangeOrderSubform.Form.Availability.Value = VAvail
rs1.Close
conn1.Close
Set rs1 = Nothing
Set conn1 = Nothing
This has been working just fine for weeks, retreiving the correct available amount as packaged items are added to the Packages table and orders are being added in the OrderDetail table. Yesterday it started returning the Packaged field from the InventoryPrep query instead.
I tried a bunch of things and then created a table from the query and used the SELECT statement to look it up in the table. That worked. There is something about my query set up that has caused it to stop recognizing my calculated field. I need help!
This is my first time posting and I hope this is enough information. I'm pretty new to Access and VBA but I've learned a lot from reading in this forum. I hope someone can help or let me know what other information could shed light on the problem.
To read a single value from a table or query, your code is a bit over the top.
For this scenario, Access has the DLookup function.
VAvail = DLookup("Available", "Inventory", "BatchID = '" & VBatch & "'")
Forms!ChangeOrders.ChangeOrderSubform.Form.Availability.Value = VAvail
That's all that is needed.

Run time error 3021- no current record

I want to link the result of a query to a Textbox but I get this error: here is my code:
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("SELECT XValue, YValue,Wert FROM tb_DCM_Daten WHERE (FzgID=" & Forms!frm_fahrzeug!ID & " AND Name='" & List2.Value & "')")
Text10.Text = rst!XValue //error in this line
It should be return c.a 20 record
Why do I get this error and how can I solve it?
One possible reason for the error is that Name is a reserved word in Access, so you should use
... & " AND [Name]='" & ...
You could also test for rst.EOF before trying to use rst!XValue. That is, to verify whether or not your query is returning at least one row you can add the code
If rst.EOF Then
MsgBox "The Recordset is empty."
End If
immediately after the .OpenRecordset call. If the Recordset is empty, then you'll need to verify your SQL statement as described by #GregHNZ in his comment above.
Usually, I would do this. Create a new query in Access , switch to SQL View , Paste my code there and go to Design >> Run.
SELECT XValue, YValue,Wert FROM [tb_DCM_Daten] WHERE [FzgID]=12 AND [Name]='ABC';
if your query syntax is correct you should see the result otherwise error mssg will tell where you are wrong. I used to debug a much more complicated query than yours and this is the way that I've done.
If there is still error, maybe you should try
Dim sql as String
sql = "SELECT...."
Set rst = CurrentDb.OpenRecordset(sql)
Another possible reason might be your table name. I just wonder what is your table name exactly ? if your table contains white space you should make it like this [DCM Daten].
One more thing I like to add that may cause this, is your returning a sets of resultset that has "Reserved word" fields, for example:
Your "Customers" table has field name like the following:
Custnum | Date | Custname
we know that Date field is a reserved word for most database
so when you get the records using
SELECT * FROM Customers
this will possible return "No Current Record", so instead selecting all fields for that table, just minimize your field selection like this:
SELECT custnum, custname FROM Customers
After trying the solutions above to no avail, I found another solution: Yes/No fields in Access tables cannot be Null (See allenbrowne.com/bug-14)
Although my situation was slightly different in that I only got the "No current record." error when running my query using GROUPBY, my query worked after temporary eliminating the Yes/No field.
However, my Yes/No field surprisingly did not contain any Nulls. But, troubleshooting led me to find an associated error that was indeed populating my query result with Null Yes/No values. Fixing that associated error eliminated the Null Yes/No values in my results, thus eliminating this error.
I got the same error in the following situation:
In my case the recordset returned one record including some fields with Null value.
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("SELECT * FROM tbl WHERE (criteria)", dbOpenDynaset)
Textbox1 = rst!field1 'error in this line - Non-Null value
Textbox2 = rst!field2 'Null value
Textbox3 = rst!field1 'Null value
Viewing Locals when rst is opened and before asignments, shows the recordset as I expect it to be. The error is thrown when trying to a asign a value from this recordset.
What fixed this, is ensuring that all fields contained non-Null values.
Just posting this for future seekers.