如何将Access查询结果保存到VBA中的对象?

huangapple go评论70阅读模式
英文:

How to save Access query result into an object in VBA?

问题

抱歉,以下是您提供的代码的翻译部分:

我无法将Access查询的整个结果写入一个对象。
这是一个示例代码。

Sub test()

Dim cn As Object
Dim strConnection As String
Dim rs As Object

Set cn = CreateObject("ADODB.Connection")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Test.mdb;Jet OLEDB:Database Password=pass;"

cn.Open strConnection

'写入一些测试数据
cn.Execute ("CREATE TABLE TestTable (ID int, Column_1 varchar(255), Column_2 varchar(255));")
cn.Execute ("INSERT INTO TestTable (ID, Column_1, Column_2) VALUES (1, ""Foo"", ""Bar"")")
cn.Execute ("INSERT INTO TestTable (ID, Column_1, Column_2) VALUES (2, ""Bar"", ""Foo"")")
cn.Execute ("INSERT INTO TestTable (ID, Column_1, Column_2) VALUES (3, ""FooBar"", ""BarFoo"")")

'获取数据
Set rs = cn.Execute("SELECT * FROM TestTable")

cn.Close

End Sub

请注意,这只是代码的翻译部分,不包括问题的回答。

英文:

I'm not able to write the whole result of an Access query to an object.

Here is a sample code.

Sub test()

Dim cn As Object
Dim strConnection As String
Dim rs As Object

Set cn = CreateObject("ADODB.Connection")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Test.mdb;Jet OLEDB:Database Password=pass;"

cn.Open strConnection

'Write some test data
cn.Execute ("CREATE TABLE TestTable (ID int, Column_1 varchar(255), Column_2 varchar(255));")
cn.Execute ("INSERT INTO TestTable (ID, Column_1, Column_2) VALUES (1, ""Foo"", ""Bar"")")
cn.Execute ("INSERT INTO TestTable (ID, Column_1, Column_2) VALUES (2, ""Bar"", ""Foo"")")
cn.Execute ("INSERT INTO TestTable (ID, Column_1, Column_2) VALUES (3, ""FooBar"", ""BarFoo"")")

'Get the data
Set rs = cn.Execute("SELECT * FROM TestTable")

cn.Close

End Sub

It seems I'm getting only the first row when checking rs on the watchlist, having Item 1 = 1, Item 2 = Foo, Item 3 = Bar under the Fields.

如何将Access查询结果保存到VBA中的对象?

On Python with PyODBC I'm used to use the fetchall method, but I don't find similar for ADODB.

On Access the query returns all the 3 rows.

Is the object type wrong? I tried also "Set rs = New ADODB.Recordset" but it did help either. So how can I write all 3 rows to the object?

答案1

得分: 1

FetchAll的粗略等价是GetRows

Dim cn As Object
Dim strConnection As String
Dim rowdata As Variant

Set cn = CreateObject("ADODB.Connection")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Test.mdb;Jet OLEDB:Database Password=pass;"

cn.Open strConnection

'写入一些测试数据
cn.Execute ("CREATE TABLE TestTable (ID int, Column_1 varchar(255), Column_2 varchar(255));")
cn.Execute ("INSERT INTO TestTable (ID, Column_1, Column_2) VALUES (1, ""Foo"", ""Bar"")")
cn.Execute ("INSERT INTO TestTable (ID, Column_1, Column_2) VALUES (2, ""Bar"", ""Foo"")")
cn.Execute ("INSERT INTO TestTable (ID, Column_1, Column_2) VALUES (3, ""FooBar"", ""BarFoo"")")

'获取数据
rowdata = cn.Execute("SELECT * FROM TestTable").GetRows()

cn.Close

通常情况下首选使用记录集因为记录集只在需要时加载数据例如当使用`rs.MoveNext`下一个记录将被加载而不是立即加载),并且记录集与数据源相关联因此可以用来插入新行到您的表中在VBA中,`GetRows`的用途非常有限
英文:

The rough equivalent to FetchAll is GetRows:

Dim cn As Object
Dim strConnection As String
Dim rowdata As Variant

Set cn = CreateObject("ADODB.Connection")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Test.mdb;Jet OLEDB:Database Password=pass;"

cn.Open strConnection

'Write some test data
cn.Execute ("CREATE TABLE TestTable (ID int, Column_1 varchar(255), Column_2 varchar(255));")
cn.Execute ("INSERT INTO TestTable (ID, Column_1, Column_2) VALUES (1, ""Foo"", ""Bar"")")
cn.Execute ("INSERT INTO TestTable (ID, Column_1, Column_2) VALUES (2, ""Bar"", ""Foo"")")
cn.Execute ("INSERT INTO TestTable (ID, Column_1, Column_2) VALUES (3, ""FooBar"", ""BarFoo"")")

'Get the data
rowdata = cn.Execute("SELECT * FROM TestTable").GetRows()

cn.Close

Usually, working with the recordset is preferred, as recordsets only load data when needed (e.g. when you use rs.MoveNext, the next record gets loaded, instead of immediately loading it), and recordsets are linked to the data source, so can be used to insert new rows into your table. GetRows has very few use cases in VBA.

答案2

得分: 0

首先,我不建议使用GetRows,除非您想从一个具有良好字段和movenext等功能的非常好的记录集对象转换为难以处理的多维数组。

接下来:

当您使用rs.execute时,您会得到一个只能向前移动的记录集,并且只能通过.recordCount来检查现有记录(它始终为-1)。因此,您只能通过使用.recordCount来检查记录 - 不能获取实际记录数。

由于上述原因,您需要在打开命令中指定“游标”类型。

因此,使用:

Dim strSQL As String

strSQL = "select * from tblHotels where City like 'Edmon%' "

rstD.CursorLocation = adUseClient
rstD.Open strSQL, rstDCon
Debug.Print rstD.RecordCount

还有其他几种设置游标(记录集)类型的方法,您也可以像这样简单地使用:

rstD.CursorLocation = adUseClient

但在大多数情况下,Execute命令将覆盖设置。由于您需要额外的代码行,所以只需使用记录集的.Open方法来执行此操作。

因此:

'获取数据
Set rs = cn.Execute("SELECT * FROM TestTable")

变成:

'获取数据
rs.Open "SELECT * FROM TestTable", cn, adUseClient
Debug.Print rs.RecordCount

如果您没有使用早期绑定,因此必须将常量adUseClient替换为3,例如:

'获取数据
rs.Open "SELECT * FROM TestTable", cn, 3
Debug.Print rs.RecordCount
英文:

First, I don't recommend GetRows unless you want to go from a really nice fantastic recordset object with nice fields, and movenext etc to that of a multi-dimensional array which is hard to work with.

Next up:

When you use rs.execute, you get a forward only recordset, and you can ONLY check recordcount for existing records (it will always be -1). So, you can ONLY check for records by using .recordCount - not get an actual count of records.

Because of above, you want to specify the "cursor" type in the open command.

So, use:

Dim strSQL     As String

strSQL = "select * from tblHotels where City like 'Edmon%' "

rstD.CursorLocation = adUseClient
rstD.Open strSQL, rstDCon
Debug.Print rstD.RecordCount

There are several other ways to set the cursor (recordset) type, you could also just likey go:
rstD.CursorLocation = adUseClient, but the Execute command will override the setting in most cases. Since you need the extra line of code, then just use the .Open method of the recordset to do this.

So:

'Get the data
Set rs = cn.Execute("SELECT * FROM TestTable")

Becomes

'Get the data
rs.Open "SELECT * FROM TestTable", cn, adUseClient
debug.print rs.RecordCount

It not clear if you are using late binding, and thus you have to replace the constant adUseClient with 3

eg:

'Get the data
rs.Open "SELECT * FROM TestTable", cn, 3
debug.print rs.RecordCount

huangapple
  • 本文由 发表于 2020年1月3日 20:43:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/59578869.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定