I am trying to navigate through records (next and prev) in a form that i have created in Microsoft Access 2013. The database is connected to SQL Server 2008. First i have loaded the database for the table using SQL:
Private Sub Form_Load()
Dim strSQL As String
Dim dbs As DAO.Database
Dim Rs As DAO.Recordset
Set dbs = CurrentDb()
strSQL = " SELECT [dbo_tblRank].* " & _
" FROM [dbo_tblRank] "
Set Rs = dbs.OpenRecordset(strSQL, dbOpenDynaset)
Me.rankNo.Value = Rs![rankNo]
Me.rankName.Value = Rs![rankName]
Me.rankDescription.Value = Rs![rankDescription]
Me.noOfRequiredDivings.Value = Rs![noOfRequiredDivings]
End Sub
Now i have created a 'next' button, which i would like to update the following fields to the next values. I have written the code (which doesn't do anything):
Private Sub btnNext_Click()
Me.Recordset.MoveNext
End Sub
What Am i doing wrong?
The issue is that the form is unbound. As a result of this, you've had to write more code in form_open than would have been required were the form/controls bound; Similarly then, in btnNext_Click, you will again have to write more code.
Re-create the recordset, find the current record in the recordset, then move to the next record, and then re-populate your unbound controls from the new record in this new recordset.
Another way would be for you to make you recordset public so that you don't have to reconnect each time.
You will still have to write code to find the current record so that you can move pass it in your btnNext_Click event.
The easy way would be to bound your Form...
Related
I am new to coding in MS Access VBA:I have a main form my data is collected. Then another form that forms a list by team that an action needs to be taken by my Admin team. The other form is a does a list of who has requested a password reset and the action is set to 0. Once the admin team goes in and completes the action, the action turns to a 1 showing it has been completed and an email is set back to the requester letting them know that the action has been complete. I need to know how to code the Approval action private sub where once it has been approved, it will be removed from the list but not from the original table from the first form. But I do not want to see the person in the list anymore show up after it has been approved. I have tried to set up where the approvals would write to another saved table but was told by someone else in Stack that I did not have to do that. I have 2 other forms set up similar but they are deleted from the original table because I am storing the data in another table, but that one had an extra step for the users. This one doesn't have the last step so I am confused on how to write the code to get it to do what I want. This is all I have in my sub because I am confused how to proceed. Any suggestions? Or do I even need the (Sub ProcessApproved) this step below since I have the step above it?
Private Sub ApproveNew()
Dim item As Variant
Dim lst As ListBox
Set lst = Me.lstDMIPasswordResets
For Each item In lst.ItemsSelected
If lst.Column(7) = "Assigned" Then
CurrentDb.Execute "UPDATE Tbl_DMIPasswordResets SET Request_Status =
1 WHERE Term_ID = " & lst.Column(0, item) & ";", dbFailOnError
End If
Next item
lst.Requery
End Sub
Private Sub ProcessApproved()
Dim item As Variant
Dim lst As ListBox
Dim rstNew As DAO.Recordset
Dim rstEmp As DAO.Recordset
Dim fld As DAO.Field
Dim lngFldCounter As Long
Dim rst As DAO.Recordset
Dim lngNewID As Long
Dim strSQL As String
Set lst = Me.lstDMIPasswordResets
For Each item In lst.ItemsSelected
Next item
lst.Requery
End Sub
Here is my table structure:
The first image is my table
The second image is my data in the table
SELECT Tbl_DMIPasswordResets.DMI_ResetID, Tbl_DMIPasswordResets.Date_of_DMIPasswordReset AS [Date of Request], Tbl_DMIPasswordResets.NatGen_ID, Tbl_DMIPasswordResets.FirstName, Tbl_DMIPasswordResets.LastName, Tbl_Site.Site_Name AS Site, Tbl_DMIPasswordResets.DMIMSP_ID, Tbl_DMIPasswordResets.NGLS_Email_Address, Tbl_DMIPasswordResets.Additional_Comments, IIf([Request_Status]=0,"Assigned","Completed") AS RequestStatus, Tbl_DMIPasswordResets.ID_FK, Tbl_DMIPasswordResets.Site_FK, Tbl_DMIPasswordResets.Team_Fk, Tbl_DMIPasswordResets.Request_Status
FROM (Tbl_DMIPasswordResets LEFT JOIN Tbl_Site ON Tbl_DMIPasswordResets.Site_FK = Tbl_Site.Site_ID) LEFT JOIN Tbl_Teams ON Tbl_DMIPasswordResets.Team_FK = Tbl_Teams.Team_ID
WHERE (((Tbl_DMIPasswordResets.Team_Fk)=[forms]![FrmDMIPasswordResetList].[cboTeam]) AND ((Tbl_DMIPasswordResets.Request_Status)=[forms]![FrmDMIPasswordResetList].[txtRequest_Status]));
I am building a form in MS Access using linked ODBC tables which is to become a large input basis for some of our teams. I have most of it worked out however am trying to auto generate a Primary ID for the main table and populate the text box so the agent doesn't have to. Effectively building an auto number in SQL.
I have the generation and rolling edits in the ODBC tables working and am just stuck on getting the generated code into the relevant field. I am using a macro on button click and have the following code:
Private Sub cmdSubmitDetails_Click()
Dim strSQL As String
Dim rst As Recordset
Dim db As Database
Dim para As String
para = InputBox("Please Enter Your User ID:")
strSQL = "SELECT Min([P_ID]) AS ID FROM QA_IDS WHERE EV_ID = " & para & ";"
Set db = CurrentDb
Set rst = db.OpenRecordset(strSQL)
Me.ID.Text = rst!ID
rst.Close
Set rst = Nothing
Set db = Nothing
End Sub
Me.ID is the field I am trying to populate. It is erroring out in the line
Set rst = db.OpenRecordset(strSQL)
with the error Run-time error '3464' Data type mismatch in criteria expression.
It's my first real dabble in MS Access and I've searched for the solution online. Any help would be greatly appreciated.
I managed to achieve what I was trying using a different method and thought I would post for someone to find useful in the future.
To get around the issue of inconsistent datatype I used a query to run the SQL (including inputting the User ID) , and append it to a new table. Then pull the information from that table with a DLookup, then purge that table. I ended up with the following code.
Private Sub cmdSubmitDetails_Click()
Dim x As String
Dim y As String
Dim z As String
DoCmd.SetWarnings False
DoCmd.OpenQuery ("AppendID")
x = DLookup("[ID]", "[TempID]")
Me.ID = x
y = DLookup("[EV_ID]", "[TempID]")
Me.EVALUATOR_ID = y
DoCmd.OpenQuery ("qryDELETE_TEMP_ID")
DoCmd.OpenQuery ("qryAddNextCallID")
DoCmd.OpenQuery ("qryDELETE_MINIMUM_ID")
DoCmd.SetWarnings True
End Sub
I've created a VBA script that updates the CommandText of an SQL connection in order to pass a parameter from Excel to a stored procedure - this works fine except that the query doesn't update itself..
Private Sub CommandButton1_Click()
Dim BillDate As Date
Dim BillDateFormat As String
BillDate = Sheets("Sheet1").Range("B4").Value
BillDateFormat = Format(BillDate, "yyyy-mm-dd")
With ActiveWorkbook.Connections("BillDateConnection").OLEDBConnection
.CommandText = "EXEC TTKWBillingTest #BillDate = '" & BillDateFormat & "'"
End With
ActiveWorkbook.Connections("BillDateConnection").Refresh
End Sub
I'm finding that the data only refreshes on the first refresh and subsequent refreshes update the CommandText but the data on the worksheet does not refresh.
I've tried adding..
ActiveWorkbook.RefreshAll
but this doesn't make any difference.
Any ideas?
Put code in ThieWorkbook object so that it fires when Excel opens
Private Sub Workbook_open()
For Each objConnection In ThisWorkbook.Connections
'Get current background-refresh value
bBackground = objConnection.OLEDBConnection.BackgroundQuery
'Temporarily disable background-refresh
objConnection.OLEDBConnection.BackgroundQuery = False
objConnection.Refresh 'Refresh this connection
'Set background-refresh value back to original value
objConnection.OLEDBConnection.BackgroundQuery = bBackground
Next
End sub
NB This can cause problems if the data connection is set to update on open! Best to remove this option from the connection manager!
To update via a button:
Private Sub Cmd_RefreshData_Click()
Application.Run "'" & ThisWorkbook.Name & "'!ThisWorkbook.Workbook_Open"
ActiveWorkbook.RefreshAll
Lbl_LastRefresh_Click
End Sub
Lbl_LastRefresh uses Now() to display the last refresh time
...I figured this out.
'Enable background refresh' needs to be deselected in the connection properties.
The table refreshes every time without this option.
I'm trying to fill a continuous form in access 2013 using data from a stored procedure in ms sql server 2014. The database connection works, I can use other access forms to add data to the ms sql server database. So that's not the problem.
Here's my stored procedure:
CREATE PROCEDURE spArtikelen AS
BEGIN
SELECT a.artikelnr, omschrijving, v.voorraad, p.prijs, a.leverancier
FROM artikel AS a, artikelprijs AS p, artikelvoorraad AS v
WHERE a.artikelnr = p.artikelnr
AND a.artikelnr = v.artikelnr
AND CAST(GETDATE() AS DATE) BETWEEN p.begindatum AND p.einddatum
END
And here's my vba code (I put the vba code on the LOAD event of the form):
Private Sub Form_Load()
Dim rs As ADODB.Recordset
Set rs = DbConn.Execute("EXEC spArtikelen")
Do Until rs.EOF
Me.txtArtikelnr.Value = rs!artikelnr
Me.txtOmschrijving.Value = rs!omschrijving
Me.txtVoorraad.Value = rs!voorraad
Me.txtPrijs.Value = rs!prijs
Me.txtLeverancier.Value = rs!leverancier
Debug.Print rs!artikelnr, rs!omschrijving, rs!voorraad, rs!prijs, rs!leverancier
rs.MoveNext
Loop
End Sub!
the continuous form..
How do I fix this? I've been trying to get it work all day.. without success..
Every time I run the form, I only get one record, and I can't click through the records.!
Here's the data from the stored procedure I'm trying to put into the form.
Possible solution?
Open your recordset with adUseClient for its CursorLocation property. Then set the form's Recordset property to your ADO recordset.
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open "EXEC spArtikelen", DbConn
Set Me.Recordset = rs
Then with artikelnr for txtArtikelnr.ControlSource, omschrijving for txtOmschrijving.ControlSource, and so forth the form should load with the recordset rows as you wish.
Note the data displayed within the form will be read-only. Hopefully that is not an unwelcome surprise.
Also, I suggested this approach because you already had a suitable ADO recordset. However, I think Gord's suggestion to use a pass-through query as your form's RecordSource is simpler.
I am doing some maintenance work on a linked-table application in Microsoft Access 2010 and experiencing this little gem of a problem. The application is linked to a SQL Server 2008 database. The application has a main form that allows a user to choose a combination of park code and resource and pops up an edit form for the details of that particular combination. If that combo doesn't exist in the database, the application inserts a new record in, but the issue is that 2 records get inserted.
Here's the seat of the problem code, it gets called when I need to insert a new record in a details popup form:
Private Sub New_Rec(unit_code As String, resource As String, sql As String)
DoCmd.RunSQL ("INSERT INTO PARK_RESOURCES (unit_code, resource, sensitivity) VALUES " _
& "('" & unit_code & "','" & resource & "','public')")
'Force an explicit save
'http://www.pcreview.co.uk/forums/update-cancelupdate-without-addnew-edit-t1150554.html
If Me.Dirty Then
Me.Dirty = False
End If
Me.RecordSource = sql
End Sub
Creating a "new" record results in 2 records getting inserted into the Recordset. It doesn't seem to matter if I move the explicit save code before or after setting the RecordSource. In either order (and stopping after either) produces 2 new records inserted in the database (verified by querying in SSMS).
When I set the RecordSource property and step through the code, the event chain looks like: Me.RecordSource = sql --> Form_BeforeUpdate() --> Form_AfterUpdate() --> Form_After_Insert() --> Form_Current(). The duplicate is not present at the close of BeforeUpdate, but by the time I get to AfterUpdate, the duplicate has already been inserted. What happens between BeforeUpdate and AfterUpdate that causes this to happen?
According to MSDN, the order is: BeforeInsert → BeforeUpdate → AfterUpdate → AfterInsert. They also state that setting the value of a control through Visual Basic doesn't trigger these events. But when I update the RecordSource in code, the last 3 events certainly fire; BeforeInsert is the only one that a step-through doesn't stop on.
As per Daniel Cook's request, here is the calling code.
Private Sub Form_Load()
On Error GoTo Err_Form_Load
Me.KeyPreview = True
If Not IsNull(Me.OpenArgs) Then
ProcessOpenArgs (Me.OpenArgs)
Me.lblHeader.Caption = Me.unit_code & ": Resource - " & Me.resource
Else
Me.lblHeader.Caption = "Information Needs"
End If
... (error trapping)
End Sub
And the ProcessOpenArgs sub (OpenArgs get set as "park;resource"):
Private Sub ProcessOpenArgs(open_args As String)
On Error GoTo Err_ProcessOpenArgs
Dim Args() As String
Args = Split(open_args, ";")
Me.unit_code = Args(0)
Me.resource = Args(1)
'Check to see if there are records in the database for current unit/resource combo'
Dim rs As DAO.Recordset
Dim sql As String
sql = "SELECT * FROM PARK_RESOURCES " & _
"WHERE resource='" & Me.resource & "' AND unit_code='" & Me.unit_code & "'"
Set rs = CurrentDb.OpenRecordset(sql, dbOpenDynaset, dbSeeChanges)
'if there aren''t, create a new record'
If (rs.RecordCount = 0) Then
New_Rec Me.unit_code, Me.resource, sql
Else 'go to the current listing'
Me.RecordSource = sql
End If
Exit_ProcessOpenArgs:
Exit Sub
Err_ProcessOpenArgs:
MsgBox Err.Number & Err.description
Resume Exit_ProcessOpenArgs
End Sub
I will continue to comb through the event documentation and as a last resort I may go totally nuts and just stick every possible event in my VBA code and step through them, but does anyone know what could be happening to cause the duplicates?
In your ProcessOpenArgs, the If (rs.RecordCount = 0) Then line could be a problem unless you first use rs.MoveLast - see here
When I'm setting Me.unit_code and Me.unit here:
Private Sub ProcessOpenArgs(open_args As String)
On Error GoTo Err_ProcessOpenArgs
Dim Args() As String
Args = Split(open_args, ";")
Me.unit_code = Args(0)
Me.resource = Args(1)
the code is creating 1 record and then New_Rec inserts a second record in the DB. When the Form automatically Requeries after Me.RecordSource = sql, it sticks the first record (created by the Me.xxx = yyyy statements in ProcessOpenArgs into the DB too and then pulls both back out to the Form Recordset. That's where the double insert is coming from.
In order to correct it, I changed Me.unit_code and Me.resource to local subroutine variables l_unit_code and l_resource and used those instead in ProcessOpenArgs. That took care of this problem as well as a second problem that I had with records form one resource type bleeding into other resource types.
Thanks all for the assist!