Использование CountIF с датами до 01.03.1900 в Excel / VBA - PullRequest
1 голос
/ 18 января 2020

У меня странная проблема с Execl. Значение указанной c ячейки ist 01.01.1900, формат ячейки date -Формат. Когда я пытаюсь подсчитать, сколько экземпляров 01.01.1900 существует с помощью CountIf, получается 0, поисковый термин создается с помощью CDate() -конверсии. Вот полный код:

Dim searchterm as Date
Dim someRange as Range
searchTerm = CDate("01.01.1900")
Application.WorksheetFunction.CountIf(someRange, searchTerm)

Все работает как положено, когда дата начинается до 01.03.1900. С указанной датой 01.01.1900 я получаю следующие результаты:

VarType(singleCellRange) возвращает 7 (то есть формат даты )

singleCellRange.Value возвращает 31.12.1899 (см. Также здесь )

Итак, вопрос: как мне получить правильный формат для проблемных c дат, чтобы CountIf снова заработал?

Ответы [ 2 ]

3 голосов
/ 18 января 2020

Тип данных VBA Date и даты Excel не совпадают.

Они оба сохраняются как серийные номера, но в Excel (с использованием системы 1900):

  • Excel, (с использованием системы 1900): 1 -> 1 Jan 1900
  • VBA: 1 -> 31 Dec 1899

Поскольку Excel распознает (неправильно) 29 Feb 1900 как действительная дата, базовые значения становятся конгруэнтными по 1 Mar 1900 и после этого.

В зависимости от важности подсчета дат в этом диапазоне существуют различные обходные пути.

Вероятно, самое простое - просто вычесть 1 из компаратора даты vba, если дата предшествует 1-Mar-1900.

РЕДАКТИРОВАТЬ: По некоторым данным, объяснение этой ошибки считается, что для совместимости с основным рабочим листом в то время Excel был представлен: Lotus123, в котором была та же ошибка. Таким образом, он существует примерно столько же, сколько и в Excel, и вряд ли он изменится, опасаясь взлома программ, которые принимают это во внимание.

0 голосов
/ 18 января 2020
Sub CountDate()
  Dim searchterm As Date, sh As Worksheet, someRange As Range
  Set sh = ActiveSheet ' use here your worksheet
  Set someRange = sh.Range("A2:A13")
  searchterm = CDate("01.01.1900")
  If CLng(searchterm) < 61 Then
      Debug.Print Application.WorksheetFunction.CountIf(someRange, CLng(searchterm) - 1)
  Else
      Debug.Print Application.WorksheetFunction.CountIf(someRange, CLng(searchterm))
  End If
End Sub

Весь кредит должен go @Ron Rosenfeld, который объяснил, почему это ...

Поскольку Excel и VBA начинают совпадать с одной и той же датой только после first of March 1900 и серийного номера для эта дата равна 61, тогда при условии поиска таким образом вы всегда получите правильное совпадение.

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