Преобразование данных с помощью DatePart в запросе выбора доступа MS

Я пытаюсь использовать DatePart() в запросе выбора MS Access, чтобы извлечь месяц и год - как число - из даты, которая изначально находится в строковой форме


"ГГГГ-ММ-ДД ЧЧ:НН:СС.0000000"


Исходный код, написанный кем-то другим, говорит:

DatePart("m", date)
DatePart("yyyy", date)

Но это вызывало ошибку «Тип данных, несоответствие критериев» при выполнении запроса, поэтому я попытался использовать Cdate() для преобразования строки в тип даты.

DatePart("m", Cdate(date))
DatePart("yyyy", Cdate(date))

Однако это не решило проблему. Мне интересно, не находится ли моя исходная строка даты в форме, которую Cdate() может преобразовать, или есть ли более простой способ извлечь частичную числовую дату из строки даты, такой как моя.

Я готов более подробно остановиться на ситуации, если этот вопрос будет неполным, но я не хотел забегать вперед.


person cmgurba    schedule 13.02.2013    source источник


Ответы (2)


Эти лишние нули были бы проблемой, если бы их можно было убрать, можно сказать

CDate(Mid(sdate, 1, InStr(sdate, ".") - 1))

затем

DatePart("m", CDate(Mid(sdate, 1, InStr(sdate, ".") - 1)))

Однако вам может показаться более удобным просто обратиться к соответствующей части строки:

aYr = Left(sdate,4)
aMnth = Mid(sdate,6,2)
person Fionnuala    schedule 13.02.2013
comment
Извините, что забыл ответить... Это избавило меня от ошибки несоответствия типов, с которой я столкнулся. Спасибо большое. - person cmgurba; 16.02.2013

Вы были правы в том, что доли секунды не позволяют CDate принять вашу строку. И вы можете убрать доли секунды. Но поскольку вам в конечном итоге нужны год и месяц, вы можете игнорировать все компоненты времени и просто использовать часть даты.

Посмотрите, предлагает ли этот сеанс Immediate window что-нибудь полезное.

MyString = Format(Now(), "yyyy-mm-dd hh:nn:ss") & ".0000000"
? MyString
2013-02-14 23:38:09.0000000
' if date format is always yyyy-mm-dd,
' give CDate the first 10 characters
? CDate(Left(MyString, 10))
2/14/2013 
' year
? DatePart("yyyy", CDate(Left(MyString, 10)))
 2013 
' or
? Year(Left(MyString, 10))
 2013 
' month
? DatePart("m", CDate(Left(MyString, 10)))
 2 
' or
? Month(CDate(Left(MyString, 10)))
 2 

' if date format can vary slightly, eg yyyy-m-d,
' give CDate everything before the first space
? CDate(Left(MyString, InStr(MyString, Chr(32)) -1))
2/14/2013 
? Year(CDate(Left(MyString, InStr(MyString, Chr(32)) -1)))
 2013 
? Month(CDate(Left(MyString, InStr(MyString, Chr(32)) -1)))
 2 

Вы не упомянули, что вы будете делать с числами года и даты после того, как получите их. Если вы собираетесь соединить их вместе в виде строки, вы можете использовать Format().

? Format(Left(MyString, 10), "yyyymm")
201302
person HansUp    schedule 15.02.2013
comment
Спасибо за ответ, это тоже полезная информация. По сути, проблема решена: DatePart() требуется аргумент типа date, а CDate() требуется строковый аргумент без дробной доли секунды. - person cmgurba; 16.02.2013
comment
Итак, вы говорите, что при извлечении значения даты из вашей строки вы предпочитаете CDate(Mid(YourString, 1, InStr(YourString, ".") - 1)) вместо CDate(Left(YourString, 10))? 3 функции вместо 2? - person HansUp; 16.02.2013
comment
Нет, вызов Left() в этой ситуации более эффективен, я согласен. Но в целом концепция пропуска переменного количества долей секунды может быть более полезной. Также мне очень помогла его оперативность в ответах :) - person cmgurba; 18.02.2013