Я пытаюсь понять, как Excel работает с форматами даты и значениями даты.
контекст проблемы:
Мое приложение имеет следующую архитектуру
- Клиент Excel VBA: французский на 2016 г. с windows 7 Французский
- База данных сервера SQL
В книге Excel на листе имеется обработчик событий Change
используется для сбора данных (для простоты объяснения, давайте предположим, что есть все даты) и сохранения входного значения в базе данных.Значения записываются и сохраняются в виде строк, загружаются в виде текста и форматируются в виде даты один раз на листе.
На листе обработчик событий Change
обрабатывает ввод, который отслеживается с помощью следующего кода (обработчик событий отключенпри загрузке данных из базы данных).
With Target
Dim mydate As Date
mydate = CDate(.Value)
Debug.Print " day = " & Day(mydate) & ", month = " & Month(mydate)
End with
Когда формат устанавливается вручную (щелкните правой кнопкой мыши ячейку> ячейка формата> дата> выберите или определите желаемый формат), месяцы и дни интерпретируются какожидается.
Установив проверку ввода, если я попытаюсь ввести дату, такую как 23.10.2008, Excel выдает ошибку (у меня французская операционная система и французская версия Excel).В этом примере первым элементом в дате является день (10), за которым следуют месяц (23, недопустимый для этого примера) и, наконец, год (2018).
Sub SetValidation(ByVal dataRange as Range)
With dataRange
With .Validation
On Error GoTo ErrorHandler
.Delete
.Add Type:=xlValidateDate, AlertStyle:=xlValidAlertStop, _
Operator:=xlGreater, Formula1:="1/1/1900"
.InCellDropdown = True
.IgnoreBlank = True
.ErrorTitle = ""
.ErrorMessage = ""
.ShowInput = False
.ShowError = True
End With '.Validation
End With 'dataRange
ErrorExit:
Exit Sub
' process error
GoTo ErrorExit
End Sub
Когда я набираю 23/10/2018, ввод принимается и сохраняется как напечатанный (в виде строки).
Теперь, когда ввод, например, 04/05/2018дата может быть неоднозначной в зависимости от того, является ли среда чтения пользователем французской или англосаксонской.
Итак, я хочу пояснить, что было набрано, используя явный формат с месяцем, отображаемым в виде строки.
Если я установлю формат как «дд ммм гггг», значение будет отображаться как 04 май 2018 (день = 04, месяц = май), а трассировка в обработчике событий Change
выдаст следующее
день = 4, месяц = 5 , что соответствует отображаемому значению.
Теперь, когда используется точно такой же формат с использованием кода VBA, он не обеспечивает тот же результат - деньи месяц поменялись местами.
With dataRange
.NumberFormat = "dd mmm yyyy"
.Value = .Value 'force format to update
end With
Чтобы было понятно:
- VBA загружает строку даты как «04/05/2018»
- VBA применяет формат «дд ммм гггг»»и дата отформатирована как« 5 апреля 2018 года »
- Пользователь вводит« 04/05/2018 »в пустую ячейку того же формата, а дата форматируется как« 4 мая 2018 года »
Проблема не в том, как установить проверку для даты, которая во французской системе не использует англосаксонское соглашение: при вводе даты, такой как 23.03.2008, неожиданно проверка выдает ошибку noнезависимо от того, как значение отображается.
Проблема заключается в несогласованности внутреннего представления даты и способа ее отображения пользователю при применении формата с использованием VBA.Я ожидаю, что применение формата вручную даст тот же результат, что и применение его через VBA.
при вводе даты 04/05/2018 проверяется , но при применении формата в VBA значение становится 05/04/2018 .
В обоих случаях инструкция форматирования абсолютно одинакова.
Я бы хотел понять, почему код VBA и пользовательский интерфейс Excel имеют разное поведение и если исправление будет доступно.