powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Манипуляции с датами.
25 сообщений из 29, страница 1 из 2
Манипуляции с датами.
    #36165626
Castro men
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Была задача: написать функцию которая бы вычитала из нужной даты 1 месяц.
Ну вроде всё просто и можно использовать DateAdd("m", -1, myDate).
Но есть грабли, связаные с тем, что она функция запускается на разных машинах и формат превставления меняется.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Sub A()
Dim qDate As Date
Dim LValue, RValue As String
Select Case DatePart("q", Now)
Case  2 
qDate = Format(# 1 / 3 / 2009 #, "mm/dd/yyyy")
Case  3 
qDate = Format(# 1 / 6 / 2009 #, "mm/dd/yyyy")
Case  4 
qDate = Format(# 1 / 9 / 2009 #, "mm/dd/yyyy")
Case  1 
qDate = Format(# 1 / 1 / 2010 #, "mm/dd/yyyy")
End Select

Debug.Print "LValue: " & qDate

RValue = (DateAdd("m", - 1 , qDate))

Debug.Print "RValue: " & RValue
End Sub

Копнул в сторону функции Format , которая вроде для того и предназначена

Должно вернуть
авторLValue: 01.06.2009
RValue: 01.05.2009
и на одной машине так и возвращает.

На другой же возвращает
авторLValue: 1/6/2009
RValue: 12/6/2008
Что конечно не правильно и вычитание не выполнятся как нужно.
(если изменить маску на "dd/mm/yyyy", и применить функцию Format к результату то в этом случае жизнь налаживается, но это уже перестаёт работать на других машинах).
Что я делаю не так?
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36165738
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не очень ясно, зачем вы преобразовывате дату в строку ДО того, как делаете операции над ней? Дайте DateAdd работать с типом ДАТА. А потом форматируйте как нравится.
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36165756
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
типа так?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Sub A()
Dim qDate As Date
Dim RValue As Date
Select Case DatePart("q", Now)
Case  2 
qDate = # 1 / 3 / 2009 #
Case  3 
qDate = # 1 / 6 / 2009 #
Case  4 
qDate = # 1 / 9 / 2009 #
Case  1 
qDate = # 1 / 1 / 2010 #
End Select

Debug.Print "LValue: " & Format$(qDate)

RValue = DateAdd("m", - 1 , qDate)

Debug.Print "RValue: " & Format$(RValue)
End Sub
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36165763
Фотография qwrqwr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Castro men
Что я делаю не так?Вы неправильно запихиваете стринг, возвращаемый функцией Format в переменную qDate As Date - т.е. 2 раза конвертируете Now() -> string -> опять в Date.
При этом в 1ый параметр функции формат Вы подставляете значение (как-бы) даты с использованием неких определенных разделителей, которые не определены как разделители на ином компе.
Ваш пример следует переписать хотя бы так - исключив преобразование в стринг и возвращая заведомо дату функцией DateSerial:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Sub A()
Dim qDate As Date
Dim LValue As String, RValue As String
    Select Case DatePart("q", Now)
        Case  2 
            qDate = DateSerial( 2009 ,  3 ,  1 )
        Case  3 
            qDate = DateSerial( 2009 ,  6 ,  1 )
        Case  4 
            qDate = DateSerial( 2009 ,  9 ,  1 )
        Case  1 
            qDate = DateSerial( 2010 ,  1 ,  1 )
    End Select

Debug.Print "LValue: " & qDate
RValue = (DateAdd("m", - 1 , qDate))
Debug.Print "RValue: " & RValue
End Sub
PS но логику этих действий я все равно не уловил:
если следовать далее прогрессии, то надо каждый раз добавлять по 3 месяца - и в Case 1 должно быть DateSerial(2009, 12, 1) - а там вдруг добавляется четыре?
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36165769
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а еще ошибка тут:
#1/9/2009# - это 9 января 2009 независимо от компа, так что если вы имели ввиду 1-е сентября, то надо писать так: #9/1/2009#
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36165794
sergeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Думаю, что собака зарыта здесь
Код: plaintext
qDate = Format(# 1 / 6 / 2009 #, "mm/dd/yyyy")
Пишите день.месяц.год, а формат как месяц.день.год. Считаю, лучше написать так, авось поможет
Код: plaintext
qDate = Format("01/06/2009", "dd/mm/yyyy")
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36165802
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sergeyvgДумаю, что собака зарыта здесь
Код: plaintext
qDate = Format(# 1 / 6 / 2009 #, "mm/dd/yyyy")
Пишите день.месяц.год, а формат как месяц.день.год. Считаю, лучше написать так, авось поможет
Код: plaintext
qDate = Format("01/06/2009", "dd/mm/yyyy")



у автора qDate определена как Date. Функция Format возвращает строку. Так что этот кусок кода в принципе ошибочен.
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36165993
Castro men
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qDate As Date я запихнул в самом конце, там был стринг, но всё равно не работало правильно.
Вариант qwrqwr подошёл, DateSerial - как раз то что надо. Спасибо
Смысл функции в том, чтобы вернуть даты начала и окончания за только что прошедший квартал. Тоесть если сейчас 3й квартал, то нужно вернуть даты за 2й.
Возможно я тут колесо изобретаю и есть что-то уже готовое, к тому же мой вариант загнётся к конце года. Может есть какое-то более элегантное и универсальное решение по вычислению границ годовых кварталов?
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166064
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Castro men
Возможно я тут колесо изобретаю и есть что-то уже готовое, к тому же мой вариант загнётся к конце года.


Да, в общем-то все просто. Начало квартала:
Код: plaintext
1.
? DateSerial(Year(Date),DatePart("q", Date)* 3 , 1 )

вместо вашего кейса. Можете потом обрабатывать эту дату как угодно (DateAdd и т.п.), только Format не используйте.

непонятно две вещи
1) почему у вас для 1-го квартала возвращается дата на год позже указанной даты?
2) почему функция DatePart("q".... считает, что сейчас уже третий квартал.... это я щас поразбираюсь
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166068
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ой. второй пункт отпадает, это я не те тестовые данные дал :)
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166132
Castro men
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ваш первый пункт - это моя попытка разрулить с годами.
Если я запущу код 01,01,2010, то Date вернёт 2010 год и конечно же ничего работать не будет
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166139
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блин, тороплюсь :(
виноват, посыпаю пеплом

Код: plaintext
? DateSerial(Year(Date),(DatePart("q", Date)- 1 )* 3 + 1 , 1 )
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166144
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Castro menВаш первый пункт - это моя попытка разрулить с годами.
Если я запущу код 01,01,2010, то Date вернёт 2010 год и конечно же ничего работать не будет

А что не будет работать? Почему во втором квартале вас это устраивает, а в первом - нет?
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166196
Фотография qwrqwr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Castro men
Смысл функции в том, чтобы вернуть даты начала и окончания за только что прошедший квартал. Тоесть если сейчас 3й квартал, то нужно вернуть даты за 2й.
Возможно я тут колесо изобретаю и есть что-то уже готовое, к тому же мой вариант загнётся к конце года. Может есть какое-то более элегантное и универсальное решение по вычислению границ годовых кварталов?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Sub q(mydate As Date)
Dim firstday As Date, lastday As Date, quartback As Date

    quartback = DateAdd("q", - 1 , mydate)
    firstday = DateSerial(Year(quartback), (Month(quartback) \  3 ) *  3  -  2 ,  1 )
    lastday = DateAdd("q",  1 , firstday) -  1 

    Debug.Print firstday, lastday
End Sub
?
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166332
Фотография qwrqwr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я тут ступил, но никто не жалуется :(
так надо:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Sub q(mydate As Date)
Dim firstday As Date, lastday As Date, quartback As Date

    quartback = DateAdd("q", - 1 , mydate)
    firstday = DateSerial(Year(quartback), DatePart("q", quartback) *  3  -  2 ,  1 )
    lastday = DateAdd("q",  1 , firstday) -  1 

    Debug.Print mydate, firstday, lastday
End Sub
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166341
Castro men
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwrqwr,

Похоже, по возвращает странное, есть передать например Date.
Сейчас это 1/1/2009 3/31/2009, хотя по идее должно вернуть 4/1/2009 6/30/2009
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166350
Castro men
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДА-да, именно так. Я чуточку недопилил эту функцию.
Спасибо огромное!
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166406
Castro men
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хотелось бы у Вас более подробно спросить об этом алгоритме, очень любопытен для меня.

Код: plaintext
1.
2.
3.
mydate = Date
quartback = DateAdd("q", - 1 , mydate)
firstday = DateSerial(Year(quartback), DatePart("q", quartback) *  3  -  2 ,  1 )
lastday = DateAdd("q",  1 , firstday) -  1 

Итак.
Код: plaintext
quartback = DateAdd("q", - 1 , mydate)
получили -3 месяца назад

Код: plaintext
firstday = DateSerial(Year(quartback), DatePart("q", quartback) *  3  -  2 ,  1 ) 
Код: plaintext
Year(quartback) 
- получили год. Очень хорошо, это как раз то место, с которым я больше всего парился.


Код: plaintext
DatePart("q", quartback) *  3  -  2 
- первое выражение выражение вернет 2. А почему умножаем на 3 и вычитаем? Какая тут логика действует в определении месяца?
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166477
Фотография qwrqwr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторХотелось бы у Вас более подробно спросить об этом алгоритме, очень любопытен для меня.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Sub q(mydate As Date)
Dim firstday As Date, lastday As Date, quartback As Date

    quartback = DateAdd("q", - 1 , mydate)
' получили дату ровно на 1 квартал назад от заданной
    firstday = DateSerial(Year(quartback), DatePart("q", quartback) *  3  -  2 ,  1 )
' от полученной даты берем год, и номер её квартала
' номер квартала преобразуем в номер месяца так: 1 ->1 ; 2 ->4 ; 3 ->7 ; 4 ->10 (с помощью арифметики)
    lastday = DateAdd("q",  1 , firstday) -  1 
' добавляем ровно 1 квартал без 1 дня - получаем последний день квартала

    Debug.Print mydate, firstday, lastday
End Sub
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166698
Castro men
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо!
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36166895
Valihan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А не проше будет просто сделать проверку перед запуском приложения

If Len(Date) > 8 Then
MsgBox "Не правильная настройка формата даты !", vbOKOnly + vbCritical
Exit Sub
End If
Потом в настроиках поменять на краткий формат
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36633231
valdemar_ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите
в Excel UserForm добавил календарик и по нажатию выбранной дате в поле TextBox пояляется выбранная дата в формате "05/18/2010" т.е. 18 мая 2010 я указал для TextBox формат
tbDate_O.Text = Format(tbDate_O.Text, "dd.mm.yyyy")
что бы дата выводилась в формате "dd.mm.yyyy", но выводятся не все даты правильно если выбрать
17 мая 2010 выведет 17.05.2010, а если выбрать 3 мая 2010 выведет 05.03.2010
в чем может быть ошибка ? надо чтобы после выбора даты в календарике отоброжалась дата в формате "dd.mm.yyyy"
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36633401
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
valdemar_ruвыбранной дате в поле TextBox пояляется выбранная дата в формате "05/18/2010"

У вас вот в этом месте ошибка. Вы дважы пытаете преобразовать дату, зачем?
Вам нужно брать дату из календарика (а не из текстбокса) и форматировать так, как вам нравится.

Либо, на крайняк для первого текстбокса сделать формат YYYY-MM-DD, тогда уж точно не ошибется.
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36633583
valdemar_ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro,
Спасибо.
Я не правильно обращался поэтому календарик возвращал не правильное значение типа 05/05/2010
Private Sub Calendar1_Click()
UserForm.tbDate_O = Calendar1.Value
UserForm1.Hide
End Sub
Должно быть так
Private Sub Calendar1_Click()
UserForm.tbDate_O.Text = Calendar1.Value
UserForm1.Hide
End Sub
...
Рейтинг: 0 / 0
Манипуляции с датами.
    #36633599
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
valdemar_ru Должно быть так
UserForm.tbDate_O.Text = Calendar1.Value

Не должно!!!!!!!!!!
НИКОГДА не используйте неявные преобразования типов, не придется искать такие дурацкие ошибки (а если бы вы не заметили?)

P.S. и всегда Используйте Option Explicit
...
Рейтинг: 0 / 0
25 сообщений из 29, страница 1 из 2
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Манипуляции с датами.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]