I have a form that allows the user to add records to a table. I am trying to add a button that will allow them to copy the currently displayed record to a new record.
My code is:
Private Sub Command1947_Click()
Dim currentID As Long
If IsNull(Panel_ID) Then
MsgBox prompt:="Please select the record to copy first.", buttons:=vbExclamation
Exit Sub
End If
currentID = Panel_ID
DoCmd.GoToRecord record:=acNewRec
MsgBox prompt:=DLookup("Job_Number", "Table1", "Panel_ID=" & currentID), buttons:=vbExclamation
Job_Number = DLookup("Job_Number", "Table1", "Panel_ID=" & currentID)
Date_of_MFG = DLookup("Date_of_MFG", "Table1", "Panel_ID=" & currentID)
'Build_Hours = DLookup("Build_Hours", "Table1", "Panel_ID=" & currentID)
Quality_Initials = DLookup("Quality_Initials", "Table1", "Panel_ID=" & currentID)
Builders = DLookup("Builders", "Table1", "Panel_ID=" & currentID)
'Shop_Location = DLookup("Shop_Location", "Table1", "Panel_ID=" & currentID)
Customer_Name = DLookup("Customer_Name", "Table1", "Panel_ID=" & currentID)
Customer_Part = DLookup("Customer_Part", "Table1", "Panel_ID=" & currentID)
'Ship_First_Pass = DLookup("Ship_First_Pass", "Table1", "Panel_ID=" & currentID)
LOM = DLookup("LOM", "Table1", "Panel_ID=" & currentID)
'Prints_Red_Lined = DLookup("Prints_Red_Lined", "Table1", "Panel_ID=" & currentID)
Quality_Touch_Points = DLookup("Quality_Touch_Points", "Table1", "Panel_ID=" & currentID)
Spot_Checker_Initials = DLookup("Spot_Checker_Initials", "Table1", "Panel_ID=" & currentID)
'Drawings_Highlighted = DLookup("Drawings_Highlighted", "Table1", "Panel_ID=" & currentID)
End Sub
Panel Id is my primary key and is an autogenerated sequential number.
Table1 is the name of the table that contains the data.
When I run the code Build Hours, Shop Location, Ship First Pass, Prints Red Lined, and Drawings Highlighted all give me:
Run-time error '2471': The expression you entered as a query parameter produced this error: 'Build_Hours'
Build Hours is a decimal number and the other 4 that generate the error are all short text. It seems like the code can't find these fields within the table.
In addition, when set the 5 fields that generate the error as notes and run the rest of the code, all of the other fields only seem to return null values to the new record.
Right now it seems like the MsgBox and moving to a new record after getting the Panel ID from the old record are the only parts that are working.
I learned how to use Access a long time ago but it seems to have changed a lot since and I am basically relearning it as I use it and with the help of google searches so please be patient with me.
I Assume Panel_ID is a number type. Also assume controls have same names as fields they are bound to.
If field names have space instead of underscore, enclose in [ ]. Use form prefix to reference form's fields and controls. Me can be used as alias for form name in code behind that form.
With Me
currentID = .[Panel ID]
DoCmd.GoToRecord record:=acNewRec
.[Job Number] = DLookup("[Job Number]", "Table1", "[Panel ID]=" & currentID)
...
End With
Instead of multiple calls with DLookup, do one call to open a recordset object and pull data.
Dim rs As DAO.Recordset
With Me
Set rs = CurrentDb.OpenRecordset("SELECT * FROM Table1 WHERE [Panel ID] =" & .[Panel ID])
DoCmd.GoToRecord record:=acNewRec
.[Job Number] = rs![Job Number]
...
End With
Alternatively, since data has already been pulled by bound form:
Dim JN, DOM, ...
With Me
JN = .[Job Number]
DOM = .[Date of Mfg]
...
DoCmd.GoToRecord record:=acNewRec
.[Job Number] = JN
.[Date of Mfg] = DOM
...
End With
Strongly advise not to use spaces nor punctuation/special characters in naming convention nor reserved words as names.
Related
I looks like when i use one Combo-box as a criteria works just fine however using more than that though following the same steps doesn't work . I don't use SQL i do use the Design view though.
How to make all combo boxes works together to provide the needed criteria.
If you are looking to filter a form or list box using data selected from several combo boxes, then you will need to build up the RowSource "on the fly" based on the selections made.
Below is some sample code that uses selections from 2 combo boxes (cboCountry and cboRMZone) to create the RowSource for a list box (lstCountry):
Private Sub cboCountryZone_AfterUpdate()
Call sSearchMultiple
End Sub
Private Sub cboRMZone_AfterUpdate()
Call sSearchMultiple
End Sub
Private Sub Form_Load()
Call sSearchMultiple
End Sub
Private Sub sSearchMultiple()
On Error GoTo E_Handle
Dim strSQL As String
If Not IsNull(Me!cboCountryZone) Then strSQL = strSQL & " AND CountryZone_PK=" & Me!cboCountryZone
If Not IsNull(Me!cboRMZone) Then strSQL = strSQL & " AND RMZone_PK=" & Me!cboRMZone
If Left(strSQL, 4) = " AND" Then
strSQL = " WHERE " & Mid(strSQL, 6)
End If
If Len(strSQL) > 0 Then
Me!lstCountry.RowSource = "SELECT CountryName FROM dbo_svr_Country " & strSQL & " ORDER BY CountryName ASC;"
Else
Me!lstCountry.RowSource = "SELECT CountryName FROM dbo_svr_Country ORDER BY CountryName ASC;"
End If
sExit:
On Error Resume Next
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "Form3!sSearchMultiple", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
Regards,
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
I have a combobox that builds it's list upon first usage. I know that the way I want "NotInList" to behave isn't conventional - I don't want to waste adding the item to a table separate from the needed entry, but I'd like to still warn about an item that hasn't been used yet, so that the user has to think twice before accepting the entry.
Once the user adds the item, it will automatically appear in the list next time because the data source for the combo box is as follows:
SELECT tbl_SP.PROGRAM
FROM tbl_SP
GROUP BY tbl_SP.PROGRAM
HAVING (((tbl_SP.PROGRAM) Is Not Null And (tbl_SP.PROGRAM)<>""));
I tried this:
Private Sub cmbPROGRAM_NotInList(NewData As String, Response As Integer)
If MsgBox("'" & Chr(34) & NewData & Chr(34) & " hasn't been used yet. Add to list? ", vbQuestion + vbYesNo, "Add - " & NewData & "?") = vbYes Then
Response = acDataErrAdded
End If
End Sub
but of course, Access wants the item to actually exist before it will release the error. And...if I set LimitToList to "No" then the user doesn't get a warning.
How can I achieve this behavior?
Ok, I tried this which works fine if the user selects YES, but becomes more complicated when the user selects "NO"
Public Function ReturnsRecords(strSQL As String) As Boolean
Dim d As DAO.Database
Dim arr(1 To 3) As DAO.Recordset
'Dim rs As DAO.Recordset
'assume 3 items in array above
Set d = CurrentDb
Set arr(1) = d.OpenRecordset(strSQL)
' MsgBox "Record Count is " & arr(1).RecordCount
If arr(1).RecordCount > 0 Then
ReturnsRecords = True
Else
ReturnsRecords = False
End If
Set d = Nothing
End Function
Private Sub cmbPROGRAM_BeforeUpdate(Cancel As Integer)
Dim strSQL As String
strSQL = "Select * from LU_PROGRAM where PROGRAM ='" & Me.cmbPROGRAM & "'"
If ReturnsRecords(strSQL) = False Then
If MsgBox("'" & Chr(34) & Me.cmbPROGRAM & Chr(34) & " hasn't been used yet. Add to list? ", vbQuestion + vbYesNo, "Add - " & Me.cmbPROGRAM & "?") = vbNo Then
Cancel = True
' how do I reset this? Me.cmbPROGRAM.Text = Null
End If
End If
End Sub
How do I clear the combobox if the user selects NO? If I select me.undo, that will undo all of the entries, but I just want to clear the combobox.
Incidentally, the form is totally unbound and doesn't accept an entry until the user selects "Save"
First, I'm not quite sure what you wish to achieve ...
Then, educate the users to press Escape to cancel. This is mandatory wisdom when operating an Access application.
For your code to work, you can't change the content of a control in the BeforeUpdate event. So try the AfterUpdate event with either:
Me!cmbPROGRAM.Text = ""
or:
Me!cmbPROGRAM.Value = Null
I have an app that searches through customer information on a SQL Server database.
There are three forms:
The first allows the user to lookup info based on several different criteria, like Account no, Last name Phone Number, etc.
The second form correctly displays the information from the first form.
I want to open a third form based on a value in the result set on the second form, a field called Master_ID.
I have created a Global variable that stores the contents of the Master_ID field on the second form when the Master_ID field is clicked.
Then I want to execute the on click event on a button that contains the following code:
Private Sub tranHisBtn_Click()
Dim transferSQL As String
transferSQL = "SELECT dbo_Master_Accounts.Master_ID, dbo_Master_Accounts.FirstName, dbo_Master_Accounts.LastName, dbo_Transaction_Table.Date_of_Transaction, Format([dbo_Transaction_Table]![Time_of_Transaction],""hh:nn:ss ampm"") AS TranTime, dbo_Transaction_Table.Sku, dbo_Transaction_Table.Description, Right([dbo_Transaction_Table]![Description],6) AS tranAccnt, [dbo_Transaction_Table]![ArAmt]*-1 AS Amnt, dbo_Master_Accounts.Master_ID " & vbCrLf
transferSQL = transferSQL + "FROM dbo_Master_Accounts INNER JOIN dbo_Transaction_Table ON dbo_Master_Accounts.Master_ID = dbo_Transaction_Table.Account_Number " & vbCrLf
transferSQL = transferSQL + "WHERE (((dbo_Transaction_Table.Description) Like ""%Transfer To%"") AND ((dbo_Master_Accounts.Master_ID)=" & Chr$(34) & GBL_Master_Id & Chr$(34) & ")) " & vbCrLf
transferSQL = transferSQL + "ORDER BY dbo_Transaction_Table.Date_of_Transaction, Format([dbo_Transaction_Table]![Time_of_Transaction],""hh:nn:ss ampm"");"
Dim trancon As ADODB.Connection
Set trancon = CurrentProject.Connection
Dim tranRs As New ADODB.Recordset
tranRs.ActiveConnection = trancon
tranRs.CursorType = adOpenStatic
tranRs.Open transferSQL
'DoCmd.OpenForm "TransferbyNumFM" ', , , "Master_Id = 'transRs.fields(0)'"
MsgBox "good"
End Sub
I can't figure out how to set the record source for the third form. Everything runs perfectly until I try to open the third form.
As I said: Open the form with DoCmd and set the recordsource of the Form object in the OnOpen Event of the 3rd form to the SQL string you have. No need to create a recordset, either. And never try to pass a recordsource as a filter in a DoCmd.OpenForm
Oh, and my error: since you have a global variable (i.e. a public variable declared in a module) you don't even need to pass it as an OpenArgs, you can simply do the following on Button Click
DoCmd.OpenForm "TransferbyNumFm"
and then, in the class module of Form3 do
Option Compare Database
Option Explicit
Private Sub Form_Open(Cancel As Integer)
Dim transferSQL As String
transferSQL = _
"SELECT dbo_Master_Accounts.Master_ID, " & _
"dbo_Master_Accounts.FirstName, " & _
"dbo_Master_Accounts.LastName, " & _
"dbo_Transaction_Table.Date_of_Transaction, " & _
"Format([dbo_Transaction_Table]![Time_of_Transaction],'hh:nn:ss ampm') AS TranTime, " & _
"dbo_Transaction_Table.Sku, dbo_Transaction_Table.Description, " & _
"Right([dbo_Transaction_Table]![Description],6) AS tranAccnt, " & _
"[dbo_Transaction_Table]![ArAmt]*-1 AS Amnt " & _
"FROM dbo_Master_Accounts " & _
"INNER JOIN dbo_Transaction_Table ON dbo_Master_Accounts.Master_ID = dbo_Transaction_Table.Account_Number " & _
"WHERE(((dbo_Transaction_Table.Sku) Like '%Transfer%')) " & _
"ORDER BY dbo_Transaction_Table.Date_of_Transaction"
Me.RecordSource = transferSQL
End Sub
The Recordsource of Form3 can be unassigned before this point, though you will need it to add fields (but you can remove it later on)
Copy from: https://softwareengineering.stackexchange.com/questions/158330/cascading-comboboxes
ok so i have a form, in Access 2010, with 1 Textbox and 3 ComboBoxes (1 Enabled & 2 Disabled).
the first ComboBox is not tied to the datasource but is subjective to the other 2 comboboxes. So i handled the Click event for the first Combobox to then make the other 2 enabled, and preload the 2nd ComboBox with a custom RowSource SQL Script dynamically built based on the 1st ComboBox Value.
This all works great for New information but when i goto review the information, via Form, its back to the New mode on the controls.
Question:
What event do i need to handle to check if the current Form Data contains data for the Control Source of the Controls?
As i would express it in Logic (its a mix between C & VB, i know but should get the pt acrossed):
DataSet ds = Form.RowSet
if (ds = Null) then
cbo2.enabled = false
cbo3.enabled = false
else
cbo2.rowsource = "select id, nm from table"
cbo2.value = ds(3)
cbo3.value = ds(4)
end if
... do some other logic ...
Updated Logic - Still problem, cant catch for RecordStatus for some reason (gives 3251 Run-Time Error)
Private Sub Form_Current()
Dim boolnm As Boolean: boolnm = (IsNull(txtName.Value) Or IsEmpty(txtName.Value))
Dim booltype As Boolean: booltype = IsNull(cboType.Value)
Dim boolfamily As Boolean: boolfamily = IsNull(cboType.Value)
Dim boolsize As Boolean: boolsize = IsNull(cboType.Value)
Dim rs As DAO.Recordset: Set rs = Me.Recordset
MsgBox rs.AbsolutePosition
' If rs.RecordStatus = dbRecordNew Then
' MsgBox "New Record being inserted, but not committed yet!", vbOKOnly
' Else
' MsgBox rs(0).Name & " - " & rs(0).Value & vbCrLf & _
' rs(1).Name & " - " & rs(1).Value & vbCrLf & _
' rs(2).Name & " - " & rs(2).Value & vbCrLf & _
' rs(3).Name & " - " & rs(3).Value
' End If
'MsgBox "Name: " & CStr(boolnm) & vbCrLf & _
"Type: " & CStr(booltype) & vbCrLf & _
"Family: " & CStr(boolfamily) & vbCrLf & _
"Size: " & CStr(boolsize), vbOKOnly
End Sub
Here is the final result, with Remou's assistance, and this is only a precursor to the end result (which is out of the context of the question).
Private Sub Form_Current()
If Me.NewRecord Then <=======================
cboType.Value = 0
cboType.Enabled = True
cboFamily.Enabled = False
cboSize.Enabled = False
Else
Dim rs As DAO.Recordset: Set rs = Me.Recordset
'get Family ID
Dim fid As String: fid = rs(2).Value
'Build SQL Query to obtain Type ID
Dim sql As String
sql = "select tid from tblFamily where id = " & fid
'Create Recordset
Dim frs As DAO.Recordset
'Load SQL Script and Execute to obtain Type ID
Set frs = CurrentDb.OpenRecordset(sql, dbOpenDynaset, dbReadOnly)
'Set Type ComboBox Value to Type ID
cboType.Value = frs(0)
cboType_Click 'Simulate Click Event since the Value has changed
'Make sure all 3 Comboboxes are enabled and useable
cboType.Enabled = True
End If
End Sub