Преобразование из V_STRING в V_DATE - корректна ли дата в тексте?

Автор:Волошин Дмитрий
Дата:04.04.2005
Просмотров:3794
Скачиваний:970
Оценка: - , Оценок - 0
Скачать (rar-файл; Размер - 2578)

Обсудить в форуме

Описание

При экспорте значения из "V_STRING" в "V_DATE", необходимо знать,
действительно ли в тексте стоит дата и корректна ли она.
Если в тексте стоит дата, функция возвращает "True", иначе - "False".

История:
Мне нужно было проверить около тысячи полей с текстом,
куда операционисты понабивали даты и перенести их в поля
с типом "V_DATE". Выяснилось, что у операционистов, не только
кривые ручки, но ещё и 31 день в апреле: Вот так родился этот макрос.

Параметры:
1. "Строка" - Исходный текст даты;
2. "РазделительДаты" - символ-разделитель даты, участвующий в задаче (по умолчанию точка);
3. "УчитыватьНулевые" - учитывать или нет те значения, что не забиты или нулевые в исходном тексте даты.

Примеры:

1. Переменная "Quest" примет значение "False" в случае, когда:
Ошибка написания даты:
Quest = ЗначениеИмеетТип_Дата ("31.04.2005"); // В апреле не бывает 31 день
Quest = ЗначениеИмеетТип_Дата ("O1.04.2005");
Quest = ЗначениеИмеетТип_Дата ("01-04.2005");
Quest = ЗначениеИмеетТип_Дата ("01.04.00"); // Так уж работает функция Date, что нулевой год - ошибка:
// Обрабатывать нулевые. Иногда нужно для контроля:
Quest = ЗначениеИмеетТип_Дата ("00.00.00", Null, True);
Quest = ЗначениеИмеетТип_Дата (Null, Null, True);

2. Переменная "Quest" примет значение "True" в случае:
Quest = ЗначениеИмеетТип_Дата ("01.01.2001");
Quest = ЗначениеИмеетТип_Дата ("11.11.99");
Quest = ЗначениеИмеетТип_Дата ("11.11.1");
Quest = ЗначениеИмеетТип_Дата (); // Даты нет, не обрабатывать нулевые

Текст примера

 /////////////////////////////////////////////////////////////////
// Проверка, является ли значение переменной "Строка" корректной датой.
// Если значение "Дата" - возвращаем True, иначе - False
// Волошин Д.В. Братский АНКБ
Macro ЗначениеИмеетТип_Дата (Строка:Variant, РазделительДаты:Variant, УчитыватьНулевые:Variant)
 Private Var Quest = True, Дата = Date (0, 0, 0), День = "", Месяц = "", Год = "", i = 1;
 Private Const Цифры = "0123456789";
  Строка = String (Trim (Строка));
  If (ValType (УчитыватьНулевые) == V_UnDef) УчитыватьНулевые = False; // По умолчанию
  Elif (ValType (УчитыватьНулевые) != V_Bool) УчитыватьНулевые = False; // Если не логический параметр, то по умолчанию
  End;
  If (Строка != "") // Пропускаем строку через фильтр
     If (ValType (РазделительДаты) == V_UnDef) РазделительДаты = StrFor (46); // По умолчанию
     Else РазделительДаты = String (Trim (РазделительДаты)); // Разделитель только текст
        If (StrLen (String (РазделительДаты)) > 1) РазделительДаты = SubStr (РазделительДаты, 1, 1); // Первый символ разделителя
        Elif (StrLen (РазделительДаты) < 1) РазделительДаты = StrFor (46); // По умолчанию
        End;
     End;
     While (Quest And (i <= StrLen (Строка))) // Шагаем по всей строке
        If (Index (Цифры + РазделительДаты, SubStr (Строка, i, 1)) <= 0) Quest = False; End; i = i + 1;
     End;
  Else // Дата нулевая/не указана
     If (УчитыватьНулевые) Return False; // Обрабатывать как ошибку
     Else Return True; // Пропускать
     End;
  End;
  If (Quest) // Фильтр успешен
     День = SubStr (Строка, 1, StrBrk (Строка, РазделительДаты) - 1);
     Месяц = StrSubst ((SubStr (Строка, 2 + StrLen (День), StrBrk (Строка, РазделительДаты) - StrLen (День) + 1)), РазделительДаты, "");
     Год = StrSubst (SubStr (Строка, 3 + StrLen (День) + StrLen (Месяц)), РазделительДаты, "");
     Дата = Date (Int (День), Int (Месяц), Int (Год)); Return True; // Если преобразование имело место - значение дата
  Else Return False;
  End;
 OnError (er) Return False; // Если преобразования не было - значение НЕ дата
End;