Проблема использования с Find ADODB.Recordset

Программирование на Visual Basic for Applications
anvg
Обычный пользователь
Обычный пользователь
 
Сообщения: 66
Зарегистрирован: 20.05.2007 (Вс) 18:04

Проблема использования с Find ADODB.Recordset

Сообщение anvg » 02.04.2012 (Пн) 4:21

Создаю ADODB.Recordset (Microsoft ActivX Data Objects 2.5 Library) в Excel 2010
Код: Выделить всё
    Dim pTable As New ADODB.Recordset
    pTable.Fields.Append "FLength", adDouble
    pTable.CursorLocation = adUseClient
    pTable.Open
   
    pTable.AddNew: pTable(0).Value = 715
    pTable.AddNew: pTable(0).Value = 916
    pTable.AddNew: pTable(0).Value = 830

Пытаюсь найти требуемое число по критерию методом Find
Код: Выделить всё
    pTable.Sort = "FLength DESC"
    pTable.MoveFirst
    pTable.Find "FLength<=" & CStr(730), SearchDirection:=adSearchForward
    Debug.Print pTable(0).Value
    pTable.Close

Получаю 916. Что делаю не так? И как правильно? Или остаётся только работать через Filter?

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Проблема использования с Find ADODB.Recordset

Сообщение alibek » 02.04.2012 (Пн) 8:17

Полный текст ошибки и строку, на которой происходит ошибка, укажи. И тип курсора укажи.
Lasciate ogni speranza, voi ch'entrate.

anvg
Обычный пользователь
Обычный пользователь
 
Сообщения: 66
Зарегистрирован: 20.05.2007 (Вс) 18:04

Re: Проблема использования с Find ADODB.Recordset

Сообщение anvg » 02.04.2012 (Пн) 8:57

А я разве писал, что получаю исключение (ошибку)? Ошибка в результате в Immediate выводиться 916 (легко проверить, заключив весь код в Sub Test() ... End Sub), а должно быть 715. Тип курсора adOpenStatic = 3.
На www.sql.ru подсказали, что это старый "глюк" присутствующий и в библиотеке 2.8. При сортировке по возрастанию и поиску с конца, вроде, работает нормально, но ведь может быть и более сложная сортировка.

Sam777e
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 157
Зарегистрирован: 16.09.2010 (Чт) 4:33

Re: Проблема использования с Find ADODB.Recordset

Сообщение Sam777e » 02.04.2012 (Пн) 16:58

anvg писал(а):pTable.Fields.Append "FLength", adDouble


Здесь система "знает", что тип Double
anvg писал(а):pTable.AddNew: pTable(0).Value = 715


anvg писал(а):pTable.Find "FLength<=" & CStr(730)

А здесь ей откуда знать - для нее строка поиска ПРОСТО ТЕКСТ.
Вероятно, в поиске будет "pTable.Find "FLength<=730", а надо, скорее, "FLength<=730.000Х" ( Х - это знак типа, я не помню какой для Double, # что-ли ). Короче, трудности со сравнением в нецелой ситуации. И я бы пробовал pTable.Find . . . Cstr(Cdbl(730))
Здоровья и удачи

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 02.04.2012 (Пн) 19:57

Sam777e писал(а):А здесь ей откуда знать - для нее строка поиска ПРОСТО ТЕКСТ.

Возможно, я чего-то не понимаю, но как в данной ситуации это может повлиять на результат? Есть несколько положительных чисел одного порядка. Для них лексикографическое сравнение даёт тот же результат, что и числовое.

Sam777e писал(а):Cstr(Cdbl(730))

Насколько я помню, VB в любом случае нули отрежет...

anvg
Обычный пользователь
Обычный пользователь
 
Сообщения: 66
Зарегистрирован: 20.05.2007 (Вс) 18:04

Re: Проблема использования с Find ADODB.Recordset

Сообщение anvg » 03.04.2012 (Вт) 2:36

Sam777e
Это просто "глюк". При сортировке по убыванию находит не правильно. Продемонстрирую на коде. По смыслу одинаково, а результат разный.
Код: Выделить всё
Public Sub testDESC()
    Dim pTable As New ADODB.Recordset
    pTable.Fields.Append "FLength", adDouble
    pTable.CursorLocation = adUseClient
    pTable.Open
   
    pTable.AddNew: pTable(0).Value = 715#
    pTable.AddNew: pTable(0).Value = 916#
    pTable.AddNew: pTable(0).Value = 830#
   
    pTable.Sort = "FLength DESC"
    pTable.Find "FLength<=730.0", SearchDirection:=adSearchForward, Start:=adBookmarkFirst
    Debug.Print pTable(0).Value
    pTable.Close
End Sub

Получим 916 вне зависимости от формы записи числа (лишь бы разделитель точка)
А при сортировке по возрастанию правильно.
Код: Выделить всё
Public Sub testASC()
    Dim pTable As New ADODB.Recordset
    pTable.Fields.Append "FLength", adDouble
    pTable.CursorLocation = adUseClient
    pTable.Open
   
    pTable.AddNew: pTable(0).Value = 715#
    pTable.AddNew: pTable(0).Value = 916#
    pTable.AddNew: pTable(0).Value = 830#
   
    pTable.Sort = "FLength"
    pTable.Find "FLength<=730.0", SearchDirection:=adSearchBackward, Start:=adBookmarkLast
    Debug.Print pTable(0).Value
    pTable.Close
End Sub

Как и должно быть 715.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Проблема использования с Find ADODB.Recordset

Сообщение alibek » 03.04.2012 (Вт) 9:56

anvg писал(а):А при сортировке по возрастанию правильно.

Видимо действительно баг.
Полная версия ADODB какая? Сервис-паки установлены?
Lasciate ogni speranza, voi ch'entrate.

anvg
Обычный пользователь
Обычный пользователь
 
Сообщения: 66
Зарегистрирован: 20.05.2007 (Вс) 18:04

Re: Проблема использования с Find ADODB.Recordset

Сообщение anvg » 04.04.2012 (Ср) 6:02

Создаю ADODB.Recordset (Microsoft ActivX Data Objects 2.5 Library)

Пробовал с версиями 2.0, 2.1, 2.8.
Excel 2010 32bit, Windows 7 64bit. Сервис-паки и обновления установлены. В конторе организовано автоматическое обновление. Софт лицензионный.

Sam777e
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 157
Зарегистрирован: 16.09.2010 (Чт) 4:33

Re: Проблема использования с Find ADODB.Recordset

Сообщение Sam777e » 04.04.2012 (Ср) 22:07

Я понимаю, что предлагаю не вариант - панацею, но . . .

.Find S, SearchDirection:=adSearchBackward, Start:=adBookmarkLast

Код: Выделить всё
Public Sub testDESC_2()
  Dim pTable As New ADODB.Recordset
  Dim j As Long, S As String
 
  pTable.Fields.Append "FLength", adDouble
  pTable.CursorLocation = adUseClient
  pTable.Open
 
  pTable.AddNew: pTable(0).Value = 715#
  pTable.AddNew: pTable(0).Value = 916#
  pTable.AddNew: pTable(0).Value = 728#
  pTable.AddNew: pTable(0).Value = 830#
 
  With pTable
    Debug.Print vbNewLine; " Sozdali"
    j = 1
    .MoveFirst
    Do
      If .EOF Then Exit Do
     
      Debug.Print j, pTable.Fields(0).Value
      .MoveNext: j = j + 1
    Loop
   
    .Sort = "FLength DESC"  ' <<===========
   
    Debug.Print vbNewLine; " Otsortirovali po UBYVANIJU"
    j = 1
    .MoveFirst
    Do
      If .EOF Then Exit Do
     
      Debug.Print j, pTable.Fields(0).Value
      .MoveNext: j = j + 1
    Loop
   
    Debug.Print vbNewLine; " Poisk"
   
    S = "FLength<=730.0"
    .Find S, SearchDirection:=adSearchBackward, Start:=adBookmarkLast
    Debug.Print S; pTable(0).Value
   
    S = "FLength>730.0"
    .Find S, SearchDirection:=adSearchBackward, Start:=adBookmarkLast
    Debug.Print S; pTable(0).Value
   
    S = "FLength>720.0"
    .Find S, SearchDirection:=adSearchBackward, Start:=adBookmarkLast
    Debug.Print S; pTable(0).Value
   
    S = "FLength>830.0"
    .Find S, SearchDirection:=adSearchBackward, Start:=adBookmarkLast
    Debug.Print S; pTable(0).Value
  End With
   
  pTable.Close
End Sub


Результат :
Sozdali
1 715
2 916
3 728
4 830

Otsortirovali po UBYVANIJU
1 916
2 830
3 728
4 715

Poisk
FLength<=730.0 715
FLength>730.0 830
FLength>720.0 728
FLength>830.0 916
Здоровья и удачи

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 04.04.2012 (Ср) 22:32

Sam777e писал(а):FLength<=730.0 715

Мне кажется, или правильно было бы 728?

Sam777e
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 157
Зарегистрирован: 16.09.2010 (Чт) 4:33

Re: Проблема использования с Find ADODB.Recordset

Сообщение Sam777e » 04.04.2012 (Ср) 23:01

Qwertiy писал(а):
Sam777e писал(а):FLength<=730.0 715

Мне кажется, или правильно было бы 728?


До некоторой степени согласен; особенно, если смотреть с формальной точки зрения. Но тогда надо и задачу ставить формально: есть записи, отсортированные по убыванию. Надо найти 1-ую СВЕРХУ... <=730.0 . Find НЕ работает корректно. Обязательно ли пользоваться фильтром или есть другие варианты?

Некий ответ:
1. ищем СНИЗУ > 730.0 [ как в моем предыдущем посте ]
2. нашли - [ по возможности, т.е., с проверками и.т.п. ] MoveNext
3. сумели сдвинуться - это и есть нужная запись
Здоровья и удачи

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 05.04.2012 (Чт) 11:00

Если можно получить доступ к записи в отсортированном списке по индексу, то это надо использовать в своём бинарном поиске.

anvg
Обычный пользователь
Обычный пользователь
 
Сообщения: 66
Зарегистрирован: 20.05.2007 (Вс) 18:04

Re: Проблема использования с Find ADODB.Recordset

Сообщение anvg » 06.04.2012 (Пт) 7:36

Спасибо всем за обсуждение

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Проблема использования с Find ADODB.Recordset

Сообщение alibek » 06.04.2012 (Пт) 11:23

anvg писал(а):Пробовал с версиями 2.0, 2.1, 2.8.

Я имел ввиду полный номер версии.
Последней версией для XP должна быть 2.81.1132.0.
Если установленная версия младше, возможно в последующих обновлениях MDAC этот баг устранен.
Lasciate ogni speranza, voi ch'entrate.


Вернуться в VBA

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10

    TopList