Excel VBA, соединение ADO, вернуть дату, если она существует, или предыдущую доступную дату

Я открыл новое соединение ADODB и установил новый набор записей с датами в первом поле и значениями во втором поле.

  • 01/01/2016
  • 02/01/2016
  • 04/01/2016
  • 05/01/2016

Итак, я создаю функцию myfunction(mydate), которая должна возвращать максимально доступную дату, которая равна или меньше (ранее), чем mydate:

myfunction(mydate as date)
Dim CurrentDate as Date

Set rst = cn.Execute("SELECT * FROM tbl1 ORDER BY dates;")
CurrentDate = worksheetfunction.INDEX(rst.Fields(0),worksheetfunction.MATCH(CDate(CurrentDate),rst.Fields(0), 1))

myfunction = CurrentDate
end function

Результаты должны быть

  • моя функция ("01.02.2016") = 01.02.2016
  • моя функция ("01.03.2016") = 01.02.2016

Это работает в электронной таблице Excel, но выдает ошибку «Невозможно получить свойство Match функции WorksheetFunction». Есть ли другой способ получить результат, используя этот массив?


person Gedeon    schedule 06.04.2016    source источник
comment
Вы могли бы использовать предложение WHERE в своем SQL? А может ТОП?   -  person Vincent G    schedule 06.04.2016
comment
Проблема в том, что набор записей должен использоваться для нескольких функций, поэтому я не могу использовать WHERE.. Это короткая версия моего кода.   -  person Gedeon    schedule 06.04.2016
comment
Прямо сейчас вы передаете только одно значение (Fields (0) в качестве второго параметра Match, где ожидается массив значений, возможно, поэтому жалуются.   -  person Vincent G    schedule 06.04.2016
comment
Хорошо, но «0» означает первый столбец, а rst.Fields(0) не является массивом?   -  person Gedeon    schedule 06.04.2016
comment
Нет, это означает первое поле текущей строки набора записей.   -  person Vincent G    schedule 06.04.2016
comment
Да, ты прав ! Итак, я думаю, единственный способ — выполнить другой набор записей для этой операции.   -  person Gedeon    schedule 06.04.2016


Ответы (2)


Вы можете попробовать это, если вы делаете несколько наборов записей:

Function myfunction(mydate as date) as date
    Dim CurrentDate as Date
    Set rst = cn.Execute("SELECT TOP 1 * FROM tbl1 WHERE (dates<=" & Format(mydate, "#mm/dd/yyyy#") & ") ORDER BY tbl1.dates DESC;")
    if not rst.EOF then
        CurrentDate = rst.Fields(0)
    else
        'No record found
    endif
    myfunction = CurrentDate
end function
person Vincent G    schedule 06.04.2016
comment
Но у меня есть вопрос. Если я открою соединение, а затем выполню весь набор записей и использую фильтр в функции, будет ли это быстрее, чем если бы я выполнял данные каждый раз? - person Gedeon; 07.04.2016

Вы можете попробовать метод поиска набора записей:

rst.movefirst
rst.find "datecolumnname >= " & mydate
If rst.BOF = false then
  myfunction = rst.fields(0)
Else
  Set myfunction = nothing
Endif
person INOPIAE    schedule 06.04.2016
comment
но метод Find требует возможности двигаться назад. Это дает ошибку, когда набор строк не поддерживает прокрутку назад, несмотря на то, что я установил для набора записей динамический режим: rst.CursorType = adOpenDynamic. - person Gedeon; 06.04.2016