Какую систему дат VBA распознает / по умолчанию? - PullRequest
0 голосов
/ 31 января 2019

Я пишу подпрограмму vba в Excel, чтобы сохранить все значения дат между двумя датами в одном массиве измерений, а затем проверить каждое значение в диапазоне на другом листе.

Моя проблема заключается в том, когда кодзахватывая значения даты (как целое число (или двойное число - в зависимости от того, какое из них фактически используется)), он сохраняет значение на 1462 больше значения даты на листе.

Я использую систему дат 1904 года, поэтому я могу использовать отрицательные значения времени, и я нахожусь в Австралии, поэтому даты отформатированы дд / мм / гггг.

Как пример;

На листе: 01.01.2009 = 42004

В коде: 01/01/2019 = 43466

Я понимаю, что разница такая же, какразница между значениями даты при использовании систем дат 1900 г. и 1904 г., которая заставляет меня поверить, что, возможно, VBA по умолчанию использует значение листа в 1900 г. и снова преобразовывает значение в 1904 г. при выполнении кода?

Эта рабочая книгаустанавливается следующим образом:

Sheet1 содержит даты с 01.01.2009 по 25.01.2009 в Range("A1:A25").

Sheet2 содержит 01/01/ 2019 в ячейке A1 и 10/01/2019 в ячейке A2 и activeX commandbutton.

и код:

Private Sub CommandButton1_Click()
Dim myStart As Long
Dim myEnd As Long

myStart = Me.Range("A1").Value
myEnd = Me.Range("A2").Value

Dim v As Variant
Dim x As Long
Dim myArr As Variant
ReDim myArr(0 To 100)
x = 0

For v = myStart To myEnd
    If v = Empty Then Exit For
    myArr(x) = v
    Debug.Print ("v = " & v)
    Debug.Print ("myArr = " & myArr(x))
    x = x + 1
Next

Dim lastrow As Long
lastrow = Me.Cells(Rows.Count, 4).End(xlUp).Row
x = 0
For Each cell In Sheet1.Range("A1:A100")
Debug.Print (CDbl(cell))
    If cell = myArr(x) Then
        Me.Cells(lastrow, 3).Value = cell
        Me.Cells(lastrow, 4).Value = Format(cell, "dd/mm/yyyy")
        lastrow = lastrow + 1
    End If
    x = x + 1
Next
End Sub

Выход дляcell значения в столбцах 3 и 4 следующие (первые 5 строк для демонстрации):

       C         D             Sheet1.Range("A1:A5")[when displayed as number format] 
1    43466    01/01/2019                42004
2    43467    02/01/2019                42005
3    43468    03/01/2019                42006
4    43469    04/01/2019                42007
5    43470    05/01/2019                42008

Даты записываются в ячейку как краткая дата дляциновка не числовое значение.

Используя окно запугивания, я заметил ?cdbl(DateValue(now)) = 43496 (31/01/2019), что заставляет меня задуматься, какие значения являются правильными для дат, использующих систему дат 1904 года?В соответствии со значениями в Sheet1 это должно быть 42034.

Является ли проблема вызванной типом данных или функцией, которую я использовал, как это было задано ранее - лист преобразует их в 1904, когда значенияназначен Sheet2 с VBA, это ошибка в Excel или что-то еще?

Я нашел вопрос с той же проблемой здесь, на mrexcel , однако разрешение там было изменить Excel, чтобы использовать систему дат 1900 или вычесть 1462 из значений в коде, который я надеюсьчтобы избежать обоих.

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Чтобы предоставить решение для моего примера, коллега упомянул, что если вы уменьшите значения даты как тип данных date, проблемы с таблицей значений -> vba -> sheet исчезнут.

0 голосов
/ 31 января 2019

В общем, система даты в VBA отличается от системы даты в Excel.Вы можете использовать эти 3 опции системы дат:

  • Дата Excel
  • Дата Excel с 1904 свойством
  • Дата VBA

В этом разница:

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

  • В Excel 1 преобразуется в 01. января 1900 г.;
  • В VBA 1 преобразуется в 31.Декабрь. 1899 ;
  • В Excel с 1904 г. 1 преобразуется в 02. января.1904 ;

Система 1904 (или ее отсутствие) устанавливается для каждой рабочей книги.Таким образом, если у вас есть две книги в Excel, одна с 1904, а другая без нее, она распознает их соответственно.Система установлена ​​в:

Файл> Параметры> Дополнительно> Использовать систему дат 1904

enter image description here

InВ общем, если есть вероятность, что кто-то каким-то образом изменяет вашу рабочую книгу с неверной системой, рассмотрите возможность добавления этой проверки при открытии рабочей книги:

Private Sub Workbook_Open()    
    If ThisWorkbook.Date1904 Then
        MsgBox "System is 1904, consider some action!"
    End If        
End Sub

Если вам интересно, какую систему выбрать - я могурекомендую никогда , используя 1904.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...