Доступ к VBA Subscript вне диапазона загрузки DAO.Recordset - PullRequest
1 голос
/ 25 мая 2020

Я вижу противоречивые результаты и получаю ошибку индекса вне допустимого диапазона, когда пытаюсь загрузить и использовать набор записей из запроса Access. Я загружаюсь из этого запроса: источник записи

Вот соответствующая часть моего кода:

Option Compare Database
Option Explicit

Function StoreStockoutEmail()
Dim objOutlook As Outlook.Application
   Dim objOutlookMsg As Outlook.MailItem
   Dim objOutlookRecip As Outlook.Recipient
   Dim dtStr As String
   Dim rstData    As DAO.Recordset
   Dim v  As Variant
   Dim i, j, k, x, y As Integer
   Dim mymsg As String

   mymsg = ""

    Set rstData = CurrentDb.OpenRecordset("Select * From Store_Stockouts")
    v = rstData.GetRows(rstData.RecordCount)
    If Not rstData.EOF And Not rstData.BOF Then
    rstData.MoveLast
    i = rstData.RecordCount
    rstData.MoveFirst


    MsgBox (v(0, 2))
   ...

MsgBox - это то место, где я получаю Runtime error 9 "Subscript вне допустимого диапазона », но в моем источнике данных есть точка данных 0,2 (и 2,0). (Я добавил движение EOF и BOF на основе другого ответа, но это не помогло.) Я считаю, что это могло быть ошибкой, потому что это сработало для некоторых наборов записей, а не для других. MS Access для Micosoft 365 32-разрядная версия. Добавлены ссылки на библиотеку объектов MS DAO 3.6. Спасибо!

1 Ответ

0 голосов
/ 25 мая 2020

Как намекнул Тим Уильямс, rstData.RecordCount может быть неверным, пока вы не станете танцевать .MoveLast / .MoveFirst. (См. Примечание 2)

Проверка для rstData.EOF должна следовать непосредственно за .OpenRecordset. Проверять на .BOF здесь нет необходимости (автомобиль go культ).

Таким образом, код должен быть:

Set rstData = CurrentDb.OpenRecordset("Select * From Store_Stockouts")
If Not rstData.EOF Then
    rstData.MoveLast
    i = rstData.RecordCount
    rstData.MoveFirst

    v = rstData.GetRows(i)

Примечание:

   Dim i, j, k, x, y As Integer

Это объявляет все как вариант, только y будет целым.


Примечание 2:

Я считаю, что это может быть ошибкой, потому что это сработало для некоторых наборов записей, а не для других.

Это сделано специально. Аллен Браун объясняет это в 4. здесь: http://allenbrowne.com/ser-29.html

Для наборов записей, основанных на запросах, SQL операторах и прикрепленных таблицах, свойство RecordCount возвращает количество записей. доступ до сих пор. Когда вы впервые откроете OpenRecordset (), Access захватит первую запись и продолжит обработку вашего кода, пока загружаются остальные.
Итак, если вы протестируете RecordCount сразу после OpenRecordset, вы обычно получите 0 (если записей нет) или 1 (если есть, независимо от того, сколько будет загружено.)
Это не относится к наборам записей типа dbOpenTable (по умолчанию для локальных таблиц).

Решение:

Если вам нужно знать RecordCount, сначала используйте метод MoveLast. Это заставляет Access ждать, пока загрузятся все записи, поэтому RecordCount отражает весь набор записей.

...