refer to recordset field using variable (1 Viewer)

Happy YN

Registered User.
Local time
Today, 13:08
Joined
Jan 27, 2002
Messages
425
In a DAO recordset, I want to refer to a field without using its name directly (for various reasons!), rather using a (string) variable which has previously been set. How can I get this to work?


(where rst is recordset etc)

rst!Amount 'works fine because that is the fieldname but

dim DonationValue

DonationValue="Amount"

rst!DonationValue 'returns Item not found in this collection

So how can I refer to the field?
Thanks
 

Jon K

Registered User.
Local time
Today, 13:08
Joined
May 22, 2002
Messages
2,209
Dim DonationValue

DonationValue = "Amount"

MsgBox rst(DonationValue) 'returns the amount.
.
 

ChrisO

Registered User.
Local time
Today, 22:08
Joined
Apr 30, 2003
Messages
3,202
How about: -

rst.Fields(DonationValue)

It should work.

Regards,
Chris.
 

Happy YN

Registered User.
Local time
Today, 13:08
Joined
Jan 27, 2002
Messages
425
Jon!
so why when I reference it does it reurn type-declaration character does not match declared data type?
I am using:-
rst(DonationValue)

Chris!
Nope sorry just get the same -item not found in this collection
 

ChrisO

Registered User.
Local time
Today, 22:08
Joined
Apr 30, 2003
Messages
3,202
There appears to be a small syntax error somewhere.
Please post a cut down demo of the problem.

Including Fields also allow its use within a With-End With structure.
 

modest

Registered User.
Local time
Today, 08:08
Joined
Jan 4, 2005
Messages
1,220
Happy YN said:
I am using:-
rst(DonationValue)

The answer has already been posted:

rst.Fields(DonationValue)

or if you want to set it:
rst.Edit
rst.Fields("Field Name").value = (whatever you want to set it to)
rst.Update
 

Happy YN

Registered User.
Local time
Today, 13:08
Joined
Jan 27, 2002
Messages
425
Thanks Chris & Modest but both of your solutions are not working! I enclose a cut down demo. All is OK except for that line I mentioned. If I use the alternative line, its fine!

Code:
Dim rst2 As DAO.Recordset
Dim txtView As String
txtView = ProfileGetItem("vars", "View_name", "none", "c:\temp\dg\tempv.tmp")

   Set rst2 = dbs.OpenRecordset(txtView)
   rst2.AddNew
Dim Datestamp

Datestamp = ProfileGetItem("FieldNames", "datestamp", "", appPath & "config\stanord.ini")

'This doesn't work although in the immediate window ?datestamp returns datew
   rst2!Fields(Datestamp).Value = CDbl(Now)

'This one does work- the fieldname is datew
rst2!datew = CDbl(Now)
     rst2.Update
 
Last edited by a moderator:

modest

Registered User.
Local time
Today, 08:08
Joined
Jan 4, 2005
Messages
1,220
You're still referencing it "rst!Fields()" --- I believe it's looking for the field name to be "Fields()" ... don't use the bang operator when calling a function

It should be rst.Fields() using the Dot Operator
 

EMP

Registered User.
Local time
Today, 13:08
Joined
May 10, 2003
Messages
574
Both rst(DonationValue) as posted by Jon K and rst.Fields(DonationValue) as subsequently posed by ChrisO and modest should work.


I suggest that you check the Datestamp value in the ini file. Could there be some leading or trailing spaces?


Note: Since the default collection of a recordset is Fields, the two expressions are functionally the same.

^
 

Happy YN

Registered User.
Local time
Today, 13:08
Joined
Jan 27, 2002
Messages
425
Thanks Modest
Firstly for presenting my code correctly!
Secondly for pointing out my error
I know there are countless threads on the forum re difference between bang and dot but I always thought you're always OK with bang , and dot sometimes works but I see I am wrong! I thought bang emphasizes things more. So what in a nutshell is the main criteria between them?
Thanks again
 

ChrisO

Registered User.
Local time
Today, 22:08
Joined
Apr 30, 2003
Messages
3,202
rst(DonationValue) and rst.Fields(DonationValue) are functionally the same.

However, we can’t use (DonationValue) inside a With/End With structure whereas we can use .Fields(DonationValue) because it has a leading dot.

More on Bang vs. Dot here http://www.advisor.com/Articles.nsf/aid/BAROA06

I currently take the view ‘Dot when you can and Bang when you can’t’ but a lot of the time either will do.

Regards,
Chris.
 

EMP

Registered User.
Local time
Today, 13:08
Joined
May 10, 2003
Messages
574
... we can’t use (DonationValue) inside a With/End With structure whereas we can use .Fields(DonationValue) because it has a leading dot.
Quite correct.

However we can just use the full rst(DonationValue) inside the With/End With.

^
 

ChrisO

Registered User.
Local time
Today, 22:08
Joined
Apr 30, 2003
Messages
3,202
G’day EMP.

Yes it can but under some circumstances defeats the purpose of the With structure.

In the following examples both cases do the same job: -

Case 1
Code:
Public Sub InitLanguageCase1(ByRef actobj As Object)
    Dim strLanguage As String
    Dim rs          As DAO.Recordset
    Dim db          As DAO.Recordset
    
    strLanguage = DLookup("Language", "tblConfig")

    Set db = CurrentDb()

    Set rs = db.OpenRecordset(" SELECT *" & _
                              " FROM tblLanguage" & _
                              " WHERE [Object] = '" & actobj.Name & "'")
    Do Until rs.EOF
        If rs!Control = "Object" Then
            actobj.Caption = rs(strLanguage)
        Else
            actobj(rs!Control).Caption = rs(strLanguage)
            If actobj(rs!Control).Tag = "Resize" Then
                actobj(rs!Control).Width = Len(rs(strLanguage)) * conPixelsPerChar
            End If
        End If
        rs.Movenext
    Loop
    
    rs.Close
    Set rs = Nothing
    db.Close
    Set db = Nothing
    
End Sub

And Case 2
Code:
Public Sub InitLanguageCase2(ByRef actobj As Object)
    Dim strLanguage As String
    
    strLanguage = DLookup("Language", "tblConfig")

    With CurrentDb.OpenRecordset(" SELECT *" & _
                                 " FROM tblLanguage" & _
                                 " WHERE [Object] = '" & actobj.Name & "'")
        Do Until .EOF
            If !Control = "Object" Then
                actobj.Caption = .Fields(strLanguage)
            Else
                actobj(!Control).Caption = .Fields(strLanguage)
                If actobj(!Control).Tag = "Resize" Then
                    actobj(!Control).Width = Len(.Fields(strLanguage)) * conPixelsPerChar
                End If
            End If
            .Movenext
        Loop
        .Close
    End With
    
End Sub
Note: I just grabbed this out of something that was already written so please don’t expect it to compile.

The major difference between Case1 and Case2 is that Case2 does not require a reference to ADO or DAO and is therefore more portable across Access versions. ADO and/or DAO may be referenced but it still doesn’t matter because no references are made to them…the code in Case2 simply doesn’t care what’s referenced.

The second difference is that Case2 does not set anything to something and therefore does not require setting anything to Nothing, but the recordset is still closed.

The third difference is that Case2, by legitimately dropping some of the code, preserves valuable vertical screen workspace which, in turn, helps to prevent ‘page flipping’ and screen scrolling.

And everything else that I forgot to mention.

I know it will not work under all circumstances and I also know that very few people, if any, have tried it but it works sometimes and that’s enough for me to experiment.

Hope that helps.

ETA
Changed the word legitimacy to legitimately and bolded the change.

Regards,
Chris.
 
Last edited:

EMP

Registered User.
Local time
Today, 13:08
Joined
May 10, 2003
Messages
574
Chris,

You've shown a very good example of getting rid of the need to reference DAO/ADO in Case 2.

EMP
 

modest

Registered User.
Local time
Today, 08:08
Joined
Jan 4, 2005
Messages
1,220
Chris, I don't think your cases are correct. You're not declaring the type, but I think Access goes to the default ADO/DAO that your Access version is set to.

For instance:
Dim rs As Recordset
Even though you don't declare the DAO or ADO, rs would still be one of them. Which one depends on if you have Access 97, 2000, XP, or 2003. The reason we don't do this is because sometimes people use ADO and DAO objects/types in the same sub/function, because they both use the same keywords Access would get confused -- there would be errors.
 

ChrisO

Registered User.
Local time
Today, 22:08
Joined
Apr 30, 2003
Messages
3,202
G’day Modest.

Case 2 works because no variables are declared As Database or As Recordset.

Ever since the introduction of A2K we have been aware that both Database and Recordset need to be disambiguated because the default shifted from DAO to ADO.

But if we don’t declare variables as Database or Recordset then the references to DAO or ADO are ignored. They may be present or they may be removed entirely but the line of code: -

With CurrentDb.OpenRecordset(Blah, Blah)

still works as a recordset, with or without references. So by dropping the creation of database and recordset variables and cutting straight to the chase of With CurrentDb, we make the code independent of declared references in Tools/References.

I have attached a small demo which is in A97 and without references. It readily converts to A2K and even in A2K you can go to Tools/References and remove all the references. Please also note after conversion to A2K that neither DAO or ADO appear as references. And the same sort of thing happens all the way to A2K3…it still works.

So imagine that we have a code library that needed to support all 32bit versions of Access. Which reference would we prefer to use ADO, DAO or none?

Now I know it doesn’t work with all the ways that we can use CurrentDb, but it does with recordsets.

It may seem a bit strange at first, largely because I doubt if With CurrentDb has been used that way before, but once we get the hang of it conversion between different versions of Access becomes much easier.

Regards,
Chris.
 

Attachments

  • AutoCompact97.zip
    111.5 KB · Views: 129

modest

Registered User.
Local time
Today, 08:08
Joined
Jan 4, 2005
Messages
1,220
ChrisO said:
Case 2 works because no variables are declared As Database or As Recordset

Chris, I'm still awaiting what someone else has to say on this... but I think you may be correct.

The reason I said what I did is because OpenRecordset() is a function. In this case, it returns a value. I was thinking the value it returned was a Recordset. Because I thought this, that would mean that Access would have to choose which type of recordset it was.

However, after looking further into what you had to say, now I don't think it returns a recordset. When not declaring the variable type, OpenRecordset() seems to return a "Variant/Object/Fields" type value... in this case "Object" and "Fields" is the keyword. And the important thing to note is that "Recordset" was not included.
 
Last edited:

ChrisO

Registered User.
Local time
Today, 22:08
Joined
Apr 30, 2003
Messages
3,202
Have a look at this…open MdlCompactFunctions and Function AutoCompact.
Go inside the With statement and type a dot. Have a look down the Intellisense drop-down list. That looks very much like a DAO recordset to me, even when no references are declared.

So it seems to me that CurrentDb.OpenRecordset returns a pointer to a DAO recordset in all versions of Access with or without references in Tools.

I don’t know what other people may think about this because I’m the only one I know that uses it. But it has been well tested in all versions and it works.


Regards,
Chris
 

modest

Registered User.
Local time
Today, 08:08
Joined
Jan 4, 2005
Messages
1,220
This is how Access libraries are selected by default:
-Prior to 2000: DAO object library was selected by default when a new db was created
-Access 2000: ADO object library was selected by default
-Access 2002: ADO object library still selected by default
-Access 2003: Both libraries are preselected

I'm not sure how the application handles the process when none are selected (an error should come up), or maybe it goes back to the default even though there is no selection.

I wish I could look at your zip file, but can't at work because I don't have a decompressor because of security restrictions.
 

Users who are viewing this thread

Top Bottom