OpenRecordset on a Linked Table? - ms-access

I split off a few large tables from my AccessDB to a backend database without issue.
Next, I need to open a recordset to replace various troublesome characters. The following snippet worked fine when the table was local, but Access complains now that the table is LINKED, but provides no detail.
Dim rs3 As DAO.Recordset
'Step thru the Item table fix ' & " characters
Set rs3 = db.OpenRecordset("Item", dbOpenTable)
Do While Not rs3.EOF
strDesc = Replace(Nz(rs3!DESC), Chr(39), Chr(39) & Chr(39))
strDesc = Replace(Nz(rs3!DESC), Chr(34), "")
rs3.MoveNext
Loop
Set rs3 = Nothing
Any suggestions for accomplishing this task with a LINKED table?

dbOpenTable can only be used with a local table; it can not be used with a linked table.
'Set rs3 = db.OpenRecordset("Item", dbOpenTable)
Set rs3 = db.OpenRecordset("Item")

'I allways use this format scheme, and it works perfectly, with local or
'linked tables (In fact, I always use linked tables...):
Dim bd As Database
Dim reg As Recordset
Private Sub Form_Load()
Set bd = CurrentDb
Set reg = bd.OpenRecordset("Select * from Pacientes", dbOpenDynaset)
end sub
' for a new record
reg.AddNew
' for updates
reg.Update
' for delete
reg.Delete
' to fill a table record
reg("Dni") = txtDni
' to read a table record
txtDni = reg("Dni")
' txtDni is the field's name in the form
' Dni is the field's name in the table
' to find a record
Dim Finder As String
Finder = InputBox("Dni: ")
If Finder <> "" Then
reg.FindFirst "Dni=" & Trim(Finder)
Private Sub cmdClose_Click()
reg.Close
bd.Close
DoCmd.Close
End Sub

Related

VBA The object you entered is not a valid recordset property

Ok so what I am trying to do is assign a ADODB.Recordset to a ListBox in VBA. I am getting the Error: "The object you entered is not a valid recordset property".. What am I doing wrong here?
Note: adoConn is valid and set somewhere else in the code.
Private Sub Form_Load()
' Error Management
On Error GoTo ErrHandler:
Dim adoRS As New ADODB.Recordset
Dim sqlStmt As String
' Create the SQL statement
sqlStmnt = "SELECT GroupName FROM tblGroups"
' Execute the statement
adoRS.Open sqlStmnt, adoConn
' Add items to the lstGroups
If (adoRS.RecordCount <> 0) Then
Set lstGroups.Recordset = adoRS
End If
' Clean up
adoRS.Close
Set adoRS = Nothing
Exit Sub
ErrHandler:
' Clean up
If (adoRS.State = adStateOpen) Then
adoRS.Close
End If
Set adoRS = Nothing
If Err <> 0 Then
MsgBox Err.Source & "-->" & Err.Description, , "Error"
End If
End Sub
This is how ADO is opened
Public Sub openConnection()
' The path to the database
Dim strDBPath As String
strDBPath = "C:\Users\Vincent\****\****\"
' The database name to connect to
Dim strDBName As String
strDBName = "Permissions_be.accdb"
' Full path to the database
Dim strDBFull As String
strDB = strDBPath & "\" & strDBName
' Instantiate an ADO object
Set adoConn = New ADODB.Connection
' Connect to database
With adoConn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Mode = adModeShareDenyNone
.Open (strDBPath & strDBName)
End With
End Sub
Update
So if anyone comes across this problem on Access 2010/13.
- Set the list box to a values list.
- Then on the VBA side loop through the recordset
' Add items to the lstGroups
If (adoRS.RecordCount <> 0) Then
Do While Not adoRS.EOF
' This is how to add two columns to one listbox if you need only
' one then put only the (adoRS.Fields(0))
lstGroups.AddItem (adoRS.Fields(0) & ";" & adoRS.Fields(1))
adoRS.MoveNext
Loop
lstGroups.Requery
End If
The problem is this line
Set lstGroups.Recordset = adoRS
If you look at the documentation you will notice that the is not a "Recordset" property in the list.
There is a property of the ListBox called List and it accepts a variant array. You can get the values from the record set and put them into an array and then onto the List.
Something like
' Add items to the lstGroups
If (adoRS.RecordCount <> 0) Then
lstGroups.List= adoRS.GetRows
End If
I did not test any of this but it might get you in the right track.
Also if you do not get it to work with the list this link has a very good example on how to add them one by one
enter link description here
how do you set you adoConn ? should be something like below :-
Dim cnn As ADODB.Connection
Set adoConn= New ADODB.Connection
With adoConn
.Provider = "Microsoft.Access.OLEDB.10.0"
.Properties("Data Provider").Value = "SQLOLEDB"
.Properties("Data Source").Value = "10.******"
.Properties("User ID").Value = "*****readonly"
.Properties("Password").Value = "*****readonly"
.Open
End With

Duplicate records in Subform to New record

I have a table for my assemblies in a manufacturing process [Shedmodels]. The components are listed in a separate table [ShedModelsComponents]. The primary key in [ShedModels] is [ModelNumber]. There is a field in [ShedModelsComponents] also called [ModelNumber]. Each component is thus assigned to a certain Assembly in table [ShedModels]. Next I have created a form for [ShedModels] with a subform for [ShedModelsComponents] embedded. All the components for the assembly appear like I want. So far, so good. Now many of my assemblies use almost the same components, so I would like to copy or perhaps append all the components from one assembly to a new record in [Shed Models]. I have found this code on MS website.
Private Sub btnDuplicate_Click()
Dim dbs As DAO.Database, Rst As DAO.Recordset
Dim F As Form
' Return Database variable pointing to current database.
Set dbs = CurrentDb
Set Rst = Me.RecordsetClone
On Error GoTo Err_btnDuplicate_Click
' Tag property to be used later by the append query.
Me.Tag = Me![ModelNumber]
' Add new record to end of Recordset object.
With Rst
.AddNew
!ModelNumber = Me!ModelNumber
!ModelDesc = Me!ModelDesc
!ModelSalePrice = Me!ModelSalePrice
.Update ' Save changes.
.Move 0, .LastModified
End With
Me.Bookmark = Rst.Bookmark
' Run the Duplicate Order Details append query which selects all
' detail records that have the OrderID stored in the form's
' Tag property and appends them back to the detail table with
' the OrderID of the duplicated main form record.
DoCmd.SetWarnings False
DoCmd.OpenQuery "Duplicate Shed Models Components"
DoCmd.SetWarnings True
'Requery the subform to display the newly appended records.
Me![Shed_Models_Query].Requery
Exit_btnduplicate_Click:
Exit Sub
Err_btnDuplicate_Click:
MsgBox Error$
Resume Exit_btnduplicate_Click:
End Sub
but it returns the error that this would create duplicate Model numbers, which I don't doubt. How can I copy my assembly with all the components to a new record, but change the Model Number (which would be user entered)?
First, copy the parent record (like you do). But don't let the form move to the new record.
Next, obtain the new PK.
Then, copy the child records using the new PK. This is a skeleton - you would use the RecordsetClone of the subform. See below.
Finally, move the parent form to the new record. The subform will automatically update.
Public Sub CopyRecords()
Dim rstSource As DAO.Recordset
Dim rstInsert As DAO.Recordset
Dim fld As DAO.Field
Dim strSQL As String
Dim lngLoop As Long
Dim lngCount As Long
strSQL = "SELECT * FROM tblStatus WHERE Location = '" & _
"DEFx" & "' Order by Total"
' Change this to the RecordsetClone of the subform.
Set rstInsert = CurrentDb.OpenRecordset(strSQL)
Set rstSource = rstInsert.Clone
With rstSource
lngCount = .RecordCount
For lngLoop = 1 To lngCount
With rstInsert
.AddNew
For Each fld In rstSource.Fields
With fld
If .Attributes And dbAutoIncrField Then
' Skip Autonumber or GUID field.
ElseIf .Name = "ParentID" ' Name of FK.
rstInsert.Fields(.Name).Value = NewID ' The new ID of the parent.
ElseIf .Name = "Total" Then
' Insert some default value.
rstInsert.Fields(.Name).Value = 0
ElseIf .Name = "PROCESSED_IND" Then
' Empty a field.
rstInsert.Fields(.Name).Value = Null
Else
' Copy field content.
rstInsert.Fields(.Name).Value = .Value
End If
End With
Next
.Update
End With
.MoveNext
Next
rstInsert.Close
.Close
End With
Set rstInsert = Nothing
Set rstSource = Nothing
End Sub

access vba - grab the results in the code

I am working on an access application and I am trying to do the following:
the user insert input to a search, and then I search in my db, and I want to manipulate the results (generate an html file and put the results in there).
so I have a form with one input, there the user insert something he wants to search.
then it redirects to another form, with following on_load code:
Private sub form_load()
dim str as string
set frm = screen.activeForm 'gets the last form
str = frm!search 'the input the user entered
task = "SELECT * FROM results WHERE (condition)" 'some query with the db and the input
Me.recordSource = taks
end sub
this form gets the results and prints them.
now, I see the results on my form. but, what I want is: to get the results and manipulate them in the code, for example, make an array with all the results ids and not to print it to the user.
is that possible?
You should open a Recordset with your query, loop on it's results,and apply your logic within the loop.
For instance, you can call my sub below after your :
Me.recordSource = taks
For_Instance taks ' Call my sub and pass it your SQL instruction
And here's the sub in question that you purt in your form and containing your logic:
Private Sub For_Instance(strSQL As String)
Dim DB As dao.Database
Dim RST As dao.Recordset
Dim lngID As Long
Dim strMyField As String
Dim lngCount As Long
Dim i As Long
Set DB = CurrentDb
Set RST = DB.OpenRecordset(strSQL)
If RST.BOF Then Exit Sub ' no records found, stop.
' If you want to know how many record you have prior to loop, do:
RST.MoveLast
lngCount = RST.RecordCount
Debug.Print "There are " & lngCount & " to process."
' Let's loop on your recordset now...
' first, reposition on first record:
RST.MoveFirst
' Then start to loop
While Not RST.EOF
' This is where you do your stuff with the records
' You can grab the data that is in the current line of you recordset like this:
' RST!name_of_the_field
' name_of_the_field refers to your column names
' Suppose you have a column named ID with type long, to get the current ID, do:
lngID = RST!ID
' Suppose you have a column named MyField with type string
strMyField = RST!MyField
' and do whatever you want
' And finally you go to the next record and continue your stuff
RST.MoveNext
i = i + 1
Wend
' When you arrive here, you have processed all your records
MsgBox "All done, I have processed " & i & " records"
'Close your recordset
RST.Close
'Clean your objects
Set RST = Nothing
Set DB = Nothing
End Sub
Something like this will let you connect vba to your database and get the data out:
Sub vbaRecords()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQLstr As String
Set db=CurrentDb
SQLstr = "SELECT * FROM results WHERE (condition)" ' You'll need to flesh this out to have the same condition as you've used previously.
Set rst = db.OpenRecordset(SQLstr)
' Then you can move around the recordset. Assuming you want to start at the beginning:
rst.MoveFirst
' Then you can access individual items
vbitem1 = rst!item1
' You can also loop through the different records, if there's more than 1 (your condition can narrow this down)
do until rst.EOF
' Grab items from each record in here and do something with them
rst.MoveNext
Loop
' Then close and end the connections
rst.Close
db.Close
Set rst = Nothing
Set db = Nothing
End sub
Just open a recordset using the same SQL:
SELECT * FROM results WHERE (condition)
and browse the records as needed.
Read up on the Recordset class. You can use it like this to get the results of the query into an object:
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("SELECT * FROM results WHERE (condition)", dbOpenDynaset, dbFailOnError + dbSeeChanges)
From there you can run through it, query and manipulate it as you like.

How to properly use Seek in DAO database

I'm trying to search for currently selected item in my listbox control on my table.
In my listbox control after update event, I have this code
Private Sub lst_MainList_AfterUpdate()
Dim theDB As DAO.Database
Dim theProposalsTable As DAO.Recordset
Set theDB = CurrentDb
Set theProposalsTable = theDB.OpenRecordset("tbl_PROPOSAL", dbOpenDynaset)
theSeeker theProposalsTable, Me.lst_PPpg_MainList.Value
End Sub
Then I have a sub on my Module1 with this code. I got this from an example code # https://msdn.microsoft.com/en-us/library/office/ff836416.aspx
Sub theSeeker(ByRef rstTemp As Recordset, intSeek As Integer)
Dim theBookmark As Variant
Dim theMessage As String
With rstTemp
' Store current record location.
theBookmark = .Bookmark
.Seek "=", intSeek
' If Seek method fails, notify user and return to the
' last current record.
If .NoMatch Then
theMessage = "Not found! Returning to current record." & vbCr & vbCr & "NoMatch = " & .NoMatch
MsgBox theMessage
.Bookmark = theBookmark
End If
End With
End Sub
I am getting Runtime Error 3251 Operation is not supported for this type of object.
When I hit Debug, it highlights .Seek "=", intSeek
In this point from the linked page ...
Locates the record in an indexed table-type Recordset object
... "table-type Recordset" means you must use dbOpenTable instead of dbOpenDynaset with OpenRecordset()
That point is critical. If you can't open the table with dbOpenTable, you can't use Seek. And dbOpenTable can only be used with native Access tables contained in the current database. It can not be used with any kind of linked table.
So if dbOpenTable is compatible with tbl_PROPOSAL, this change will eliminate the first error ...
'Set theProposalsTable = theDB.OpenRecordset("tbl_PROPOSAL", dbOpenDynaset)
Set theProposalsTable = theDB.OpenRecordset("tbl_PROPOSAL", dbOpenTable)
If that does work, the next error will be #3019, "Operation invalid without a current index." That happens because you must set the controlling index before calling Seek ...
With rstTemp
' Store current record location.
theBookmark = .Bookmark
' Set the index.
.Index = "PrimaryKey" '<- use your index name here
.Seek "=", intSeek
If you need to list the names of your table's indexes, you can examine its TableDef.Indexes collection. Here is an Immediate window example with a table in my database ...
set db = CurrentDb
for each idx in db.TableDefs("tblFoo").Indexes : ? idx.name : next
id
PrimaryKey
You can't use the Seek method on a linked table because you can't open linked tables as table-type Recordset objects...
However, you can use the Seek method if you use the OpenDatabase method to open the backend database.
So instead of:
Set theDB = CurrentDb()
Do this:
Set theDB = OpenDatabase("full path to backend database")
Set theProposalsTable = theDB.OpenRecordset("tbl_PROPOSAL", dbOpenTable)
Allow me to combine these two old answers. Yes, you get an error when opening a linked table as dbOpenTable because that is only supported on tables local to the DB object you are working on. Like David pointed out, you can open the linked backend as a DB object and use that.
I'm using a reliable table in my back-end called "Settings". If you don't have a reliable table you can use to pull the back end you can pass in the table name as an argument.
I'm storing the backend object once I have a handle on it so we can call against it rapidly throughout our code without recreating the object.
Private thisBEDB As Database
'#Description("This allows us to call directly against linked tables.")
Public Function thisBackend() As Database
' For MS-ACCESS table
If (thisBEDB Is Nothing) Then
With DBEngine
Set thisBEDB = .OpenDatabase(Mid(CurrentDB.TableDefs("Settings").Connect, 11), False, False, "")
End With
End If
Set thisBackend = thisBEDB
End Function
Now we can use the backend handle to make the code in your example work as expected.
Private Sub lst_MainList_AfterUpdate()
Dim theDB As DAO.Database
Dim theProposalsTable As DAO.Recordset
Set theDB = CurrentDb
Set theProposalsTable = thisBackend.OpenRecordset("tbl_PROPOSAL", dbOpenTable)
theSeeker theProposalsTable, Me.lst_PPpg_MainList.Value
End Sub
Sub theSeeker(ByRef rstTemp As Recordset, intSeek As Integer)
Dim theBookmark As Variant
Dim theMessage As String
With rstTemp
.Index = "PrimaryKey"
' Store current record location.
theBookmark = .Bookmark
.Seek "=", intSeek
' If Seek method fails, notify user and return to the
' last current record.
If .NoMatch Then
theMessage = "Not found! Returning to current record." & vbCr & vbCr & "NoMatch = " & .NoMatch
MsgBox theMessage
.Bookmark = theBookmark
End If
End With
End Sub

Running multiple queries that begin by the same word in Access 2007 through VBA

I am more or less a rookie in using VBA in Access and hope I'm not asking something stupid. Is it possible through VBA to run and save several queries that begin by the same word?
I have an Access file with multiple tables and queries, which are identified by an initial 3 digit code, eg 100QueryName. I am trying to only run the queries that begin with "901".
Hope someone can help me out.
Best regards
Jorge
The following code is a start (depending on what type of queries)...
Create a module and paste the following code. Then execute subroutine 'Test_it'
Option Compare Database
Option Explicit
Sub Test_it()
Dim strPrefix As String
' Ask user for query prefix
strPrefix = InputBox("Please enter query prefix", "Qry Prefix")
MsgBox "Executed " & Run_Queries(strPrefix) & " queries.", vbOKOnly, "COunt of Queries"
End Sub
Function Run_Queries(strPrefix As String) As Integer
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
Dim strQryName As String
Dim iQryCt As Integer
Dim iQryRan As Integer
Dim i As Integer
Set dbs = CurrentDb
iQryCt = dbs.QueryDefs.Count
i = Len(strPrefix)
iQryRan = 0
For Each qdf In dbs.QueryDefs
strQryName = qdf.Name
Debug.Print strQryName
If LCase(left(strQryName, i)) = LCase(strPrefix) Then
Debug.Print " ** Run: " & strQryName & vbTab & qdf.Type
If qdf.Type = 0 Then ' Select query
' Open this query to view results
DoCmd.OpenQuery strQryName
ElseIf qdf.Type = 48 Then ' Update query
dbs.Execute strQryName
End If
iQryRan = iQryRan + 1
Else
End If
Next qdf
Set qdf = Nothing
Set dbs = Nothing
Run_Queries = iQryRan
End Function