MS ACCESS VBA Run-time error '3021'; with .MoveNext - vba

this is my code
Dim Reloc, RelocPrev1, RelocPrev2 As String
Dim Blk, Blk2, Lt, Lt2, PrevDate As String
Dim LotComp, BlockComp As Integer
Dim DB As Database
Dim RS As Recordset
Private Sub SearchBtn_Click()
Reloc = Me.RArea.Value
Set DB = CurrentDb()
Set RS = DB.OpenRecordset(Reloc, dbOpenDynaset)
Blk = RS!Block
Lt = RS!Lot
Blk2 = Me.BlockTxt
Lt2 = Me.LotTxt
BlockComp = StrComp(Blk, Blk2, 1)
LotComp = StrComp(Lt, Lt2, 1)
RS.MoveFirst
Do Until BlockComp = LotComp
RS.MoveNext
Loop
Call RetrieveData
End Sub
RS!Block and RS!Lot works fine, only RS.Movenext and RS.Edit which I tried doesn't work.
My table is populated with more than 50 rows.
First item in the table can be pulled just fine, I just can't move to the next row with RS.MoveNext
Any ideas to make this work?

You apparently expect only 1 record to match criteria. It would be best to apply filter criteria to recordset SQL so only desired records are pulled then test if recordset is empty.
To go to a single record that meets criteria, instead of looping recordset use FindFirst and NoMatch.
RS.FindFirst "Block='" & Blk2 & "' AND Lot='" & Lt2 & "'"
If Not RS.NoMatch Then

Related

Access VBA After Insert Autofill?

I'm looking for a little help/input on how to have a field auto-populate after an identification number is entered in a new record.
I have an entry screen ("RetailEntry") where someone will enter a "Pack Number" once they either move to another record I'd like the "Description" field to populate with the corresponding "Description" ("qryDescriptions") for that pack number.
Example:
If I enter pack number 6781234 it would give me the Description "Test"
I'm trying to figure out the best way of doing this and I thought maybe a record loop like below where it runs a query for the pack number and description then loops through the records to fill it in. It kinda works if I only enter one pack number but adding anymore pack numbers or copy and pasting multiple pack numbers it errors with a "No Current Record" which I'm guessing has to do with the order of processes. I am really hoping there is a way to do this where it will autofill vs me having to add a button to make this work.
Any thoughts, advice or help is greatly appreciated!!
Code:
Private Sub Form_AfterInsert()
Dim db As Dao.Database
Dim Desc As String
Dim PDesc As String
Dim rs As Dao.Recordset
Dim rq As Dao.Recordset
'Set Description
Set db = CurrentDb
Set rs = CurrentDb.OpenRecordset("RetailEntry")
Set rq = CurrentDb.OpenRecordset("qryDescriptions")
PDesc = rs.Fields("Pack_Number").Value
Desc = "SELECT DISTINCT PackNum, Description " _
& " FROM PIC704Current " _
& " WHERE Packnum = '" & PDesc & "'"
strSQL = Desc
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
db.QueryDefs.Delete "qryDescriptions"
Set qdfPassThrough = db.CreateQueryDef("qryDescriptions")
qdfPassThrough.Connect = "ODBC;DSN=SupplyChainMisc;Description=SupplyChainMisc;Trusted_Connection=Yes;DATABASE=SupplyChain_Misc;"
qdfPassThrough.ReturnsRecords = True
qdfPassThrough.ODBCTimeout = 180
qdfPassThrough.SQL = strSQL
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Loop version
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If Not (rs.EOF And rs.BOF) Then
rs.MoveFirst
rq.MoveFirst
Do Until rs.EOF = True
If rs.Fields("Description").Value <> rq.Fields("Description").Value Then
Else
Me!Description.Value = rq.Fields("Description").Value
End If
rs.MoveNext
rq.MoveNext
Loop
End If
End Sub

How do I get the result of a Select SQL statement in VBA

I want to be able to use SQL to retrieve Data from a table and display to the immediate window in Access.
I am new to VBA and I can't seem to find the way of doing it
Dim strSQL As String
Dim cdb As DAO.Database
Dim result As Variant
strSQL = "SELECT x, from y WHERE z;"
Set cdb = CurrentDb
Debug.Print strSQL
result = Call cdb.Execute(strSQL)
Debug.Print result
To print value of field from only first record.
Dim strSQL As String
Dim result As DAO.Recordset
strSQL = "SELECT x FROM y WHERE z;"
Set result = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset)
Debug.Print result!x
If you want to print a value from each record, use a loop structure to move to each record like:
Do While Not result.EOF
Debug.Print result!x
result.MoveNext
Loop
Review this site http://allenbrowne.com/tips.html - look at the section 'Examples by Library' about halfway down.
To produce the result with just one line (assuming only one record is going to be returned), you can use:
Debug.Print CurrentDb.OpenRecordset("SELECT x FROM y WHERE z").Fields(0).Value
You can also use the DLookUp function, which is not SQL but you will recognise the parts:
Debug.Print DLookUp("x", "y", "z")
Alternative using With syntax ..
Dim Cnt as Long
With CurrentDb.OpenRecordset("SELECT Count(*) FROM MyTable WHERE X=2")
If Not .EOF Then
Cnt = .Fields(0).Value
End If
End With

Errors with linked tables and Ms Access ( Run-time error '3622' : dbSeeChanges/Identity column )

I am trying to output the name of all linked tables, including their fields which are Date/Time, and that fields values.
The following code can output the first table, field name and their first value, not all values, although when it gets to the next linked table, I get this error
Run-time Error '3622'
You must use the dbSeeChanges option with OpenRecordSet when accessing a SQL Server table that has an IDENTITY column.
Here is my code
Private Sub btnGetFields_Click()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim f As Field
Dim rst As DAO.Recordset
Dim numField As Integer
Set db = CurrentDb
For Each tdf In db.TableDefs
If Left$(tdf.Connect, 9) = "ODBC;DSN=" Then
Set rst = CurrentDb.OpenRecordset(tdf.Name)
numField = rst.Fields.Count
Debug.Print "Table: " & tdf.Name
For index = 0 To numField - 1
If rst.Fields(index).Type = dbDate Then
Debug.Print "Field: " & rst.Fields(index).Name; " Value : "; rst.Fields(index).Value
End If
Next
End If
Next
Set tdf = Nothing
Set db = Nothing
End Sub
I read something that if I'm using sql tables I should use ADO?
Any ideas?
You can continue to use your existing DAO code, just change
Set rst = CurrentDb.OpenRecordset(tdf.Name)
to
Set rst = CurrentDb.OpenRecordset(tdf.Name, dbOpenSnapshot)
That opens a static read-only Recordset, so dbSeeChanges is not required.

VBA Access SQL SELECT Query only returning one record

I'm working with VBA in Access 2010 and I have an odd problem. I'm trying to pull records from a table, but my SELECT query is only returning a single record.
There are three records in the table, but the recordset is only getting the first one.
Here's my code.
Dim cc As String
Dim DB As Database
Dim rst As recordset
Dim sqlstr As String
Dim e As Integer
cc = CmbClass.Text
If cc = "" Then Exit Sub
sqlstr = "SELECT * FROM Students" 'WHERE CCode ='" & cc & "'"
Set DB = CurrentDb
Set rst = DB.OpenRecordset(sqlstr)
'Debug.Print rst.Fields(0)
e = rst.RecordCount
Debug.Print e
If e = 0 Then Exit Sub
The value of e is continually 1, not 3. As you can see I originally had a more complex SQL string, but I've cut it down to the most basic while trying to troubleshoot, yet the problem persists. Does anyone know why this is happening?
Thanks,
Tam.
From memory you need to issue a rst.MoveLast before you can reliably get the record count like this:
sqlstr = "SELECT * FROM Students" 'WHERE CCode ='" & cc & "'"
Set DB = CurrentDb
Set rst = DB.OpenRecordset(sqlstr)
rst.MoveLast
e = rst.RecordCount
Also you might want to consider using SELECT COUNT(*) FROM Students and reading the value from the recordset instead of moving through the records to get the count. Using this query should be more efficient.
Another method is DCount.
e = DCount("*","Students","CCode ='" & cc & "'")
no playing around with recordsets until you really need to

Updating Multiple Rows using .edit in vba access 2007

I hope I can ask this right.
I have a listbox on a form (access 2007) and have it set on "simple" so I can multi-select.
I am trying to update multiple columns in a table, based on the selections in the listbox. I have a few textboxes that I want to use as the information to update the table.
I have a loop that is only updating the first record in the table no matter how many items are selected.
I think I understand why it's only updating the first record from my loop but am not sure
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb()
Set rs = db.OpenRecordset("Table1", dbOpenDynaset)
Dim i As Variant
For Each i In Listbox.ItemsSelected
With rs
.Edit
!Col1 = Me.Textbox1
!Col2 = Me.Textbox2
!Col3 = Me.Textbox3
.Update
End With
Next
I assume this is because I am not specifying the "where" in the loop I want my table updated, but I have no idea how to do this in this loop. I would have 3 columns in the listbox (at positions 1, 3 and 4) that all need to be included to specify which records in the table need to be updated. I have tried this as well using an sql query with DoCmd.RunSql but it seems impossible to change the focus of the ListIndex mid-query. Aplogies for my lack of knowledge I am pretty new to visual basic. Please Help
Simplified example how I would give it a try if I understood correctly:
Sub MultiSelect_Listbox()
Dim lCnt as Long
dim lID as long
dim sSQL_Update as string
dim sText_1 as String
dim sText_2 as String
dim sText_3 as String
dim bSuccess as Boolean
sText_1 = me.txt_Textbox_1
sText_2 = me.txt_Textbox_2
sText_3 = me.txt_Textbox_3
With Me.lst_Listbox
For lCnt = 1 To .ListCount
If .Selected(lCnt) Then
lID = .Column(0, lCnt - 1)
'Example update for 1 column
sSQL_Update = "UPDATE T_TABLE SET COL_TEXT_1 = '" & sText_1 & "' WHERE ID = " & lID & ";"
bSuccess = Update_Statement(sSQL_Update)
End If
Next
End With
End Sub
Public Function Update_Statement(sUpdate_Stmt) As Boolean
Dim db As Database
Set db = CurrentDb
db.Execute (sUpdate_Stmt)
Update_Statement = True
End Function