Формат даты в Excel и несоответствие значений - PullRequest
0 голосов
/ 21 ноября 2018

Я пытаюсь понять, как 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 имеют разное поведение и если исправление будет доступно.

1 Ответ

0 голосов
/ 22 ноября 2018

VBA использует (всегда) форматирование даты в США, помогает ли вам помощь DateValue (см. Ниже)?

Sub SetValidation(ByVal dataRange as Range)

With dataRange
    With .Validation
    On Error GoTo ErrorHandler
        .Delete
        .Add Type:=xlValidateDate, AlertStyle:=xlValidAlertStop, _
            Operator:=xlGreater, Formula1:=DateValue("04/05/2018")
        .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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...