recordset.movefirst "Rowset position cannot be restarted" - vba

I have a function that runs a stored procedure that returns only a single row and column (so one result).
I'm trying to get that one result into a variable so I can return it. I'm trying to use recordset.MoveFirst but I get the "Rowset position cannot be restarted." error. I tried just removing it, since I only have one result, but I then get an overflow. My statement looks like this:
If recordset.EOF = False Then
recordset.MoveFirst
temp = rs!ID
End IF
temp is an integer. I've checked the stored procedure to make sure it only returns the single result, and it does. Am I doing something wrong? Is there a better way to pass the result into a variable? It's possible the recordset is forward only (which means it's read only?) but I can't seem to find an answer as to how to fix that.

There is usually no reason to MoveFirst if you have not previously navigated the record set.
The overflow is unrelated to the database code and is caused by rs!ID not fitting in a VBA integer (16 bit) so make temp a Long instead (32 bit) and remove MoveFirst.

Make sure you are not using a forward-only recordset. Recordsets are this way by default. Instead use a dynamic (adOpenDynamic) or static (adOpenStatic) cursor type.
You may also need to set CursorLocation = adUseClient.
Finally, check for BOF before calling MoveFirst.
Example:
...
rs.CursorType = adOpenStatic
rs.CursorLocation = adUseClient
rs.Open "SELECT * FROM MyTable"
...
If (Not rs.BOF) Then
rs.MoveFirst
End If

You can use MoveFirst for forward only recordset ONLY when you are at EOF.
Tricky, undocumented, but WORKS!!!!

Related

How to insert Listbox items in MS Access database in a single row

I have the following code:
Try
Dim queryString As String
queryString = "Insert into ServiceRecords([Personnel]) Values(#Personnels)"
command1 = New OleDbCommand(queryString, connection)
For i As Integer = 0 To Me.ListBox1.Items.Count + 1
command1.Parameters.AddWithValue("Personnels", ListBox1.Items(i))
command1.Parameters.Clear()
command1.ExecuteNonQuery()
Next
Catch ex As Exception
End Try
But I get the error below, and I don't know how to fix it. I think it happens because of my code.
And this is what I get:
Let's review.
First, as muffi suggested, use the Add method instead of .AddWithValue but instead of DBType use OLEDBType. There is not .String type in OleDBType. You will have to check your Access db to get the correct datatype. Probably VarChar. In addition, the parameter name should match the parameter name in your query string. With Access the position is the important thing but with other databases the name matters.
Second, as Charles suggested, change the plus one to minus 1. Most people start counting at one but computers usually start at zero so the upper index of the ListBox is one less than the Count (remember you are starting at zero not one).
Third , as Charles also pointed out it is wrong to clear the parameters before you execute. Then you would have nothing in your parameter. It is not necessary to clear them at all because you are overwriting the Value property with each iteration of your loop and I have set the name and datatype outside the loop because they stay the same. We don't want to reset properties for each iteration when they don't change.
command1.Parameters.Add("#Personnels", OleDbType.VarChar)
For i As Integer = 0 To ListBox1.Count -1
command1.Parameters("#Personnels").Value = ListBox1.Items(i)
command1.ExecuteNonQuery
Next

Emptying a DAO recordset or Creating an Empty DAO recordset

So this may seem a bit of an odd question. However, I am trying to make a simple If-Else statement regarding whether or not to find records.
The first part goes like this:
If String Meets Criteria
Open Recordset
Else
Recordset Is Empty
End If
I did do a bunch of searching on empty sets, and so far my answer is just to create a quick SQL statement that returns empty. Is that really the simplest way to do this? I would never have set it up this way, but this is the fastest way to fix some code after which goes:
If recordset.recordCount > 0 Then
[Rest of Code]
Is there something a little more obvious that I haven't found yet? Like:
Set Recordset = 0
If you want a recordset that doesn't contain any records and is not updateable, you can use the following code:
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("SELECT 1 From MSysObjects WHERE FALSE")
DAO recordsets are always open and linked to a data source. Something like Dim rs As New DAO.Recordset won't work (in contrast to ADO recordsets, where you can dim an unopened recordset).
If you just want a placeholder object, you can also Set rs = Nothing, but you will encounter run-time errors when trying to access properties or methods in that case.

How to debug.print a query result from the query design in VBA /Access

I want to execute a predefined query from access via VBA and print it to the debug output. The name of the query design is in a variable named report.
I was expecting that it would work with:
debug.print db.Execute report
But everytime vba autocorrects it to:
debug.print db.Execute; report
If I understand it correctly, the ; stands for a new line and makes therefore no sense in my case. But in both cases, with and without the new line I get an error. I assume that the simple problem is, that this is not the right syntax.
I could find a lot of information about how to debug print a query that is created as a string in VBA, but I can't find any hints how to output a query that is predefined in Access via a query design.
Try either:
'// You need the parentheses because the result has to be evaluated before it can be passed to the .Print() method
Debug.Print db.Execute(result)
or
Dim myResult As String
myResult = db.Execute(result)
Debug.Print myResult
In VBA you can pass arguments to a procedure/method without using parentheses, as long as the result isn't being being assigned to anything.
'// Not assigning anything
MyExampleFunction arg1, arg2, arg3
'// assigning the result, which needs to be evaluated before it can be passed to a variable.
MyResult = MyExampleFunction(arg1, arg2, arg3)
In the same way, when you call Debug.Print it assumes that db.Execute and result are actually separate arguments (it has no way of knowing that you want result to be passed to db.Execute first because there's nothing in your syntax to state that). So you have to use parentheses to let it know.
It seems as the problem was that it is only possible to call updates with db.Execute and not queries.
There is no good solution to print a whole table from a query with debug.print but using a RecordSet as seen in the following code is a possible way.
Dim rs As DAO.RecordSet
Set rs = db.OpenRecordset(Bericht)
Do Until rs.EOF = True
Debug.Print rs("Matrikelnummer"), rs("Bewertung"), rs("Termin (Datum)"), rs("Maximale Bewertung"), rs("Bestehensgrenze"), rs("Versuch"), rs("Äquivalenzleistung")
rs.MoveNext
Loop
rs.Close
Set rs = Nothing

Janus GridEX - Stored Procedure Recordset - How to edit Some Columns

I think all I need is to somehow unbind the stored procedure recordset to the Janus GridEX, but having a difficult time figuring out how. Programming language is VBA.
My grid populates as I want - no problem there. But this code will not allow me to edit the cells that I have showing (hiding some columns):
JGEX.AllowEdit = True
JGEX.Columns(4).EditType = jgexEditNone
JGEX.Columns(6).EditType = jgexEditTextBox
JGEX.Columns(7).EditType = jgexEditTextBox
JGEX.Columns(8).EditType = jgexEditTextBox
again - I think the only issue is the need to disconnect the recordset (to allow edit). The RS object is tied in like this:
Set JGEX.ADORecordset = rsStaged
Where the rsStaged is this:
Set rsStaged = New ADODB.Recordset
rsStaged.CursorLocation = adUseClient
rsStaged.Open SQL1, cnScada, adOpenStatic, adLockOptimistic
Pretty simple recordset, but comes from a stored procedure, not a direct table query.
Thanks in advance!
I fixed the issue by adding lines of code as shown below:
JGEX.AllowEdit = True
JGEX.EditMode = jgexEditModeOn
JGEX.Columns(4).EditType = jgexEditNone
JGEX.Columns(6).EditType = jgexEditTextBox
JGEX.Columns(7).EditType = jgexEditTextBox
JGEX.Columns(8).EditType = jgexEditTextBox
JGEX.Update
You can see the differences there from above. My only problem now is that when I actually edit fields (complete on a single row), I would get this:
Multiple-step operation generated errors. Check each status value.
I believe this issue is because my recordset object is bound and it is attempting to write back. Essentially, though, what I want to do is have the ability to update any row inside the table. I will handle write back by iterating through the rows and then calling a Stored Procedure as required.
thanks again.

Using GetRows on Recordset object returns no rows

I am trying to load a recordset into an array. I am using the following code:
Set rst = CurrentDb.OpenRecordset("SELECT id FROM TABLE1")
bankacid = rst.GetRows()
rst.Close
i = UBound(bankacid, 2)
MsgBox i + 1
This returns no rows. If I use "bankacid = rst.getrows(5)" it works.
I am very new to VBA and would very much
appreciate someone pointing out what I am missing.
It would be best to take a step back and say why you want an array, after all, a DAO recorset is much more functional than an array. If an array is really necessary, use ADODB. If you just want to refer to fields and rows, use Move, MoveFirst, MoveLast, MoveNext, MovePrevious and either the name of the field (column) or the ordinal position (.Field(3).