При работе с конфигурацией «1С:Медицина. Федеральные регистры» (особенно в релизе 3.0.33.2) пользователи часто сталкиваются с неприятным багом: в форме выбора эксплуатационных данных медицинского оборудования вместо текущих дат отображается 0001 год. Это делает невозможным корректный выбор периода и последующую выгрузку данных в федеральные фрагменты ЕГИСЗ (ФРМО). В данной статье мы подробно разберем причины возникновения этой ситуации и рассмотрим способы её программного исправления.
Давайте выясним, почему система начинает отсчет от начала нашей эры. В платформе 1С тип данных Дата имеет свои особенности. Пустая дата в 1С соответствует значению 01.01.0001 00:00:00. Важно понимать, что пустая дата не является значением Неопределено.
Разберем фрагмент проблемного кода, который присутствует в модуле формы:
Если НачальноеЗначение = Неопределено Тогда
НачальноеЗначение = ТекущаяДата();
КонецЕсли;
СписокВыбора = Элементы.ЭксплуатационныеДанные.ПодчиненныеЭлементы.ЭксплуатационныеДанныеМесяцСтрока.СписокВыбора;
СписокВыбора.Очистить();
НачалоТекущегоГода = НачалоГода(НачальноеЗначение);
// ... дальнейшее формирование списка выбора
Проанализируем ситуацию: если в переменную НачальноеЗначение передается пустая дата (например, при инициализации формы или из реквизита, который еще не заполнен), условие Если НачальноеЗначение = Неопределено возвращает Ложь. Система считает, что значение задано, и пропускает блок присвоения текущей даты. В итоге функция НачалоГода(НачальноеЗначение) вычисляет начало 1-го года, и весь последующий цикл заполнения списка выбора работает с датами двухтысячелетней давности.
Рассмотрим самый быстрый вариант исправления. Нам необходимо расширить условие проверки так, чтобы оно учитывало и пустое значение типа Дата. Мы можем явно сравнить переменную с пустой датой, используя конструктор Дата(1, 1, 1).
Исправленный код будет выглядеть следующим образом:
Если НачальноеЗначение = Неопределено Или НачальноеЗначение = Дата(1, 1, 1) Тогда
НачальноеЗначение = ТекущаяДата();
КонецЕсли;
В этом случае, если переменная не инициализирована или содержит "пустышку", система корректно подставит значение ТекущаяДата(), и список выбора периодов заполнится актуальными годами.
Разберем более профессиональный и надежный метод. В платформе 1С существует универсальная функция ЗначениеЗаполнено(), которая проверяет значение на соответствие "пустому" типу (для даты это 0001 год, для ссылок — пустая ссылка, для строк — пустая строка и т.д.).
Посмотрим на пример реализации:
Если Не ЗначениеЗаполнено(НачальноеЗначение) Тогда
НачальноеЗначение = ТекущаяДата();
КонецЕсли;
Преимущества этого метода:
ЗначениеЗаполнено() одинаково эффективно обрабатывает и Неопределено, и пустую дату.Поскольку программный продукт «1С:Медицина. Федеральные регистры» ред. 3.0 постепенно снимается с поддержки (функционал переносится в ЗКГУ), крайне не рекомендуется вносить изменения напрямую в конфигурацию поставщика. Это затруднит получение возможных будущих обновлений.
Выясним, как правильно применить исправление:
ПриОткрытии или специализированный метод в модуле формы ЭксплуатационныеДанныеМедоборудования).&Вместо или &Перед.ЗначениеЗаполнено().Иногда системные администраторы предполагают, что проблема кроется в настройках сервера 1С и смещении дат (0 или 2000 лет) в базе данных SQL Server. Проанализируем, почему в данном случае это не так. Если бы "слетело" смещение дат на уровне СУБД, вы бы видели в интерфейсе даты вида 2001 год (вместо 0001) или получали критическую ошибку Datetime overflow при записи документов. Поскольку в консоли запросов даты отображаются корректно, а проблема локализована только в конкретной форме выбора — мы имеем дело именно с ошибкой в программном коде формирования списка выбора.
Мы рассмотрели техническую природу ошибки в релизе 3.0.33.2 конфигурации «1С:Медицина. Федеральные регистры». Основная причина кроется в некорректной типизации и проверке входящих данных в процедурах формирования интерфейса. Использование функции ЗначениеЗаполнено() в расширении конфигурации позволяет полностью устранить проблему отображения 0001 года и восстановить работоспособность механизмов передачи данных в ФРМО.