2015-04-11 2 views
2
Private Sub cboMonth1_Change() 
    Dim rng As Range 
    Dim rngStart As Range 
    Dim rngEnd As Range 
    Dim dt As Worksheet 
    Dim strStart As String 
    Dim strEnd As String 
    Dim ICell As Range 

    Set dt = Worksheets("Sheet1") 

    If Me.cboMonth1.Value = "January" Then 
     Set rng = Range("J2") 
    ElseIf Me.cboMonth1.Value = "February" Then 
     Set rng = Range("AO2") 
    End If 

    If rng.MergeCells Then 
     Set rng = rng.MergeArea 
     Set rngStart = rng.Cells(1, 1) 
     Set rngEnd = rng.Cells(rng.Rows.Count, rng.Columns.Count) 

     strStart = Mid(rngStart.Address, 1, Len(rngStart.Address) - 1) 
     strEnd = Mid(rngEnd.Address, 1, Len(rngEnd.Address) - 1) 

     Me.cboStartDate.Clear 

     For Each ICell In dt.Range(strStart & "3 : " & strEnd & "3") 
      Me.cboStartDate.AddItem (ICell.Value) 
     Next ICell 

    Else 
     MsgBox ("Not merge cells") 
    End If 
End Sub 

Cell Format: Custom dd/mmдата Excel VBA в настоящее время вычитается один день

Пример: В ячейку J3 содержит 1/1/1900, но J3 значение отображается 12/31/1899 в выпадающем списке последний пункт будет дисплей 30/1/1900. Я ожидаю, что combobox будет содержать даты с 1/1/1900 - 31/1/1900, если выбран январь и так далее.

Я пробовал распечатать отдельные значения MsgBox (dt.Range("J3").Value), но он дает мне 12/31/1899, но содержимое этой ячейки равно 1/1/1900.

* Примечание. У меня нет кода, который изменяет содержимое ячеек.

ответ

5

Проблема заключается в том, как VBA хранит даты и время - они на самом деле являются парными с целым числом как число дней с 12/31/1899. Проблема в том, что он просто не работает правильно для дней «0» и «1». Я не уверен, если проблема с плавающей запятой точности или что-то теряется при переходе на Excel VBA, но вы можете увидеть эффект с помощью кода ниже:

Debug.Print Format(CDate(0), "dd/mm/yyyy") 'Outputs 12/30/1899 
Debug.Print Format(CDate(1), "dd/mm/yyyy") 'Outputs 12/30/1899 
Debug.Print Format(CDate(2), "dd/mm/yyyy") 'Outputs 01/01/1900 
Debug.Print Format(CDate(3), "dd/mm/yyyy") 'Outputs 01/02/1900 

решения (хотя и неприятны) заключается в использовании Текст клетки и брось на дату (если только не нужна строка, в этом случае не бросайте его на всех):

For Each ICell In dt.Range(strStart & "3 : " & strEnd & "3") 
    Me.cboStartDate.AddItem CDate(ICell.Text) 
Next ICell 

более wierdness демонстрационный код с необратимостью даты до 3/1900:

Debug.Print CDate(ActiveSheet.Range("J3").Text) 'Outputs 01/01/1900 
Debug.Print CDate(ActiveSheet.Range("J3").Value) 'Outputs 12/30/1899 
Debug.Print CDbl(CDate(ActiveSheet.Range("J3").Text)) 'Outputs 2 
Debug.Print CDbl(CDate(ActiveSheet.Range("J3").Value)) 'Outputs 1 
+2

У меня была аналогичная проблема с датами в приложении базы данных Access. Округление значения с плавающей запятой (double) вызывало две даты с той же «датой», которые оценивались как не равные. Моим единственным решением было преобразовать исходное поле 'Date' во внутреннюю' String', а затем обратно в 'Date' для принудительной эквивалентности. Иногда я просто сравнивал даты как строки. – PeterT

Смежные вопросы