Страницы: 1
RSS
Не строится сводная таблица на основе ADODB.Recordset при обращении к свойствам EOF и BOF
 
Добрый день!

Столкнулся с интересной проблемой - пытаюсь построить сводную таблицу из кэша, который в свою очередь создан на основе ADODB.Recordset:
Код
    Dim rsReport As New ADODB.Recordset
   
    rsReport.Open strSql, cnnMSSQL
    
    Dim PT As PivotTable, PTCash As PivotCache

    Set PTCash = ActiveSheet.Parent.PivotCaches.Create(SourceType:=xlExternal)
    Set PTCash.Recordset = rsReport

    Set PT = PTCash.CreatePivotTable(TableDestination:=ActiveSheet.Cells(1, "A"), TableName:="PT")
И всё прекрасно работает до тех пор, пока я не добавляю проверку на наличие в этом RecordSet записей при помощи конструкции
Код
If rsReport.EOF And rsReport.BOF Then Stop
После этого сводная таблица не строится с формулировкой "Недопустимые флаги метода доступа". Опытным путем выяснил, что любое обращение к этим свойствам приводит к такой же ошибке.

Никто не подскажет, в какую сторону копать?
 
В процессе многочисленных эксперементов выяснилось, что данную проблему можно решить, если перед открытием RecordSet установить свойство:
Код
rsReport.CursorLocation = adUseClient
Однако, тогда при открытии RecordSet меняется CursorType на adOpenStatic - не уверен, что это не скажется на быстродействии...
 
Если и скажется, то в лучшую сторону, поскольку Вам необходимы все записи, возвращаемые SQL-запросом.
Изменено: sokol92 - 19.01.2022 20:16:12
Владимир
 
sokol92, вот тут пожалуй не соглашусь. У меня сейчас через RecordSet из базы тянутся списки для заполнения ComboBox. Когда CursorType=adOpenStatic, то время загрузки всех списков составляет примерно 3 секунды, а если adOpenForwardOnly, то уже менее 1 секунды. Хотя, возможно, такая аналогия и не совсем корректна
Изменено: webley - 19.01.2022 21:50:28
 
Цитата
webley написал:
а если adOpenForwardOnly, то уже менее 1 секунды
а менее это сколько? Это замер общего времени или запроса? Как заполняете CB?
По вопросам из тем форума, личку не читаю.
 
БМВ, это время загрузки формы, при инициализации которой заполняются CB. А "менее" - так точно не скажу, но визуально форма загружается без задержки. Что касается заполнения - в цикле данные тянутся во временный RecordSet (как раз без явного указания CursorType, т.е. насколько я понимаю adOpenForwardOnly), а уже из него считываются данные в целевые RecordSet(ы), ассоциированные с ComboBox(ами), ну и потом непосредственно заполнение через ComboBox.column = rsSource.GetRows. И, кстати, такая двухступенчатая схема мне потребовалась как раз из-за CursorType - на CB организован список с фильтрацией, в логике работы которой используется rsSource.RecordCount (значение которого при adOpenForwardOnly всегда равно -1)
 
Ну часто проще RS забрать в массив и его уже обработать для загрузки в CB.
RecordCount (значение которого при adOpenForwardOnly всегда равно -1) - Не думаю что это хорошая идея, ибо часто это в два раза замедляет общее выполнение , но MoveLast MoveFirst посчитает записи. Хотя могу ошибатсья, ооочен давно делал.
По вопросам из тем форума, личку не читаю.
 
БМВ, использование именно RS в качестве источника для CB в данном случае для меня принципиально, т.к. у меня на нем основана фильтрация списка в процессе ввода. Идею с движением по записям попробовал реализовать, но к сожалению при adOpenForwardOnly не работает MoveLast ("Набор строк не поддерживает обратную выборку"). В любом случае спасибо!
Страницы: 1
Наверх