Question

I needed to copy some values from MS Access table into Excel using VBA code. I had done this many times and considered myself experienced. In my code I export the data using the following statements:

sh.range("A" & row).Value = rs("MyField")

where sh is Excel sheet, row is integer (long) and rs is recordset (either DAO or ADO, without any effect on the problem under consideration).

My code worked well on my computer with installed MS Office 2007. But when my client ran the code on his machine with MS Office 2010, it failed and kept failing very randomly. E.g. when debugging VBA in MS Access module step by step by pressing F8 it always worked. But when I pressed 'run' F5, it failed very soon.

After many trials and errors (I tried to open the recordset using different options and recordset types and caching the records etc.), I finally found that if I write

sh.range("A" & row).Value = rs("MyField").Value

everything works just fine. But according to the docs (e.g. http://msdn.microsoft.com/en-us/library/office/ff197799(v=office.15).aspx ) the Value property is the default property of the field object, which in turn is the default collection of the recordset object.

But it seems that I cannot rely on the defaultness, which I have been doing in most of my code. Actually I found a solution to my problem, but I still have no idea about the cause. Does anyone know why is the code doing this? What is the problem?

PS: I also found that if I expand the one-line statement into two lines (three with declaration):

dim v as Variant
v = rs("MyField")
sh.range("A" & row).Value = v

it also works...

Was it helpful?

Solution

Since rs("MyField") is a Field object, if you do ...

MsgBox TypeName(rs("MyField"))

... Access will tell you its type is Field.

So TypeName() is one example where the object itself is referenced directly instead of its default .Value property.

But something like Debug.Print always references .Value, so Debug.Print rs("MyField") is the same as Debug.Print rs("MyField").Value

If you know exactly when .Value will be referenced implicitly and when it will not, you can add it only when absolutely required and omit it the rest of the time.

However, some Access developers recommend always including .Value to avoid such confusion. If that seems like too much effort to you, at least consider including .Value when you do any assignment ...

something = rs("MyField").Value

... and be watchful for any other contexts where you don't get what you want without .Value

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top