Разработка простых, на первый взгляд, алгоритмов часто ставит начинающих программистов 1С в тупик из-за особенностей типизации и работы со встроенными функциями. В этой статье мы подробно разберем, почему код для вывода приветствия ("Доброе утро", "Добрый день") может не работать, и рассмотрим наиболее эффективные способы решения этой задачи.
Рассмотрим ситуацию, с которой столкнулся автор темы. Его алгоритм строился на получении текущей даты, преобразовании её в строку и последующем сравнении. Давайте проанализируем фрагмент кода, чтобы понять, где затаились ошибки:
Время = ТекущаяДата();
Время = Прав(Время, 8); // Попытка получить "ЧЧ:ММ:СС"
Если Время >= "060000" И Время <= "175959" Тогда
Сообщить("Доброе утро!");
ИначеЕсли Время >= "120000" И Время <= "175959" Тогда
Сообщить("Добрый день!");
// ... и так далее
Ошибка №1: Несоответствие форматов строк. Проанализируем результат работы функции Прав(Время, 8). Функция ТекущаяДата() возвращает объект типа Дата. При неявном преобразовании в строку (которое происходит внутри функции Прав) дата принимает стандартный вид, например, "15.05.2023 12:30:05". Взяв 8 символов справа, мы получим "12:30:05" (с двоеточиями). Однако в условии автор сравнивает эту строку со значением "120000" (без двоеточий). Символ ":" имеет код в таблице символов, отличный от цифр, поэтому сравнение "12:30:05" >= "120000" будет работать не так, как ожидает разработчик.
Ошибка №2: Логическое перекрытие условий. Обратите внимание на интервалы. Первое условие проверяет время от 06:00 до 17:59. Второе условие (для дня) проверяет время от 12:00 до 17:59. Поскольку в конструкции Если ... ИначеЕсли выполняется только первый блок, условие которого истинно, программа всегда будет выводить "Доброе утро!", если время находится в промежутке между 6 утра и 6 вечера. До проверки "Добрый день" код просто не дойдет.
Ошибка №3: Синтаксис оператора Иначе. В языке 1С оператор Иначе не подразумевает написания условия. Если нужно проверить дополнительное условие, следует использовать ИначеЕсли. Попытка написать Иначе Время >= ... Тогда приведет к ошибке компиляции "Неопознанный оператор".
Самый простой и надежный способ — работать не со строками, а с числами. В 1С есть встроенная функция Час(), которая извлекает составляющую часа из даты (число от 0 до 23). Давайте разберем этот метод по шагам.
Во-первых, выясним, какую функцию получения даты использовать. В клиент-серверном варианте ТекущаяДата() возвращает время сервера. Если сервер находится в другом часовом поясе, пользователь увидит неактуальное приветствие. Поэтому рекомендуется использовать ТекущаяДатаСеанса().
Рассмотрим правильный код:
ТекущийЧас = Час(ТекущаяДатаСеанса());
Если ТекущийЧас >= 6 И ТекущийЧас < 12 Тогда
Сообщить("Доброе утро!");
ИначеЕсли ТекущийЧас >= 12 И ТекущийЧас < 18 Тогда
Сообщить("Добрый день!");
ИначеЕсли ТекущийЧас >= 18 И ТекущийЧас <= 23 Тогда
Сообщить("Добрый вечер!");
Иначе // Остается интервал от 0 до 5 утра
Сообщить("Доброй ночи!");
КонецЕсли;
Почему этот код лучше:
Если вам необходима точность до секунды (хотя для приветствия это избыточно), проанализируем ситуацию с точки зрения секунд, прошедших с начала дня. В 1С разность двух дат дает количество секунд между ними.
ТекущееВремя = ТекущаяДатаСеанса();
СекундПрошло = ТекущееВремя - НачалоДня(ТекущееВремя);
Если СекундПрошло >= 21600 И СекундПрошло < 43200 Тогда // 06:00:00 - 11:59:59
Сообщить("Доброе утро!");
// ... и другие интервалы
КонецЕсли;
Этот метод часто используется в сложных расчетах времени, где важна каждая секунда, например, при расчете периодов действия скидок или времени работы оборудования.
Если вы всё же хотите использовать строковое сравнение (например, для специфических логов), выясним, как избежать проблемы с двоеточиями. Для этого используем функцию Формат() с конструктором форматной строки ДФ=ЧЧммсс (ДатаФрагмент = ЧасМинутаСекунда без разделителей).
ВремяСтрокой = Формат(ТекущаяДатаСеанса(), "ДФ=ЧЧммсс");
Если ВремяСтрокой >= "060000" И ВремяСтрокой < "120000" Тогда
Сообщить("Доброе утро!");
ИначеЕсли ВремяСтрокой >= "120000" И ВремяСтрокой < "180000" Тогда
Сообщить("Добрый день!");
// ... и так далее
КонецЕсли;
Этот подход гарантирует, что переменная ВремяСтрокой будет содержать ровно 6 цифр, и сравнение строк отработает корректно посимвольно слева направо.
В завершение проанализируем, как выводить сообщения согласно стандартам фирмы "1С". Использование метода Сообщить() в современном управляемом приложении считается устаревшим. Вместо него следует использовать объект СообщениеПользователю. Это позволяет избежать проблем при работе кода на сервере и делает интерфейс более профессиональным.
Рассмотрим пример правильного вывода приветствия:
ТекстПриветствия = "Здравствуйте!";
ЧасСуток = Час(ТекущаяДатаСеанса());
Если ЧасСуток >= 6 И ЧасСуток < 12 Тогда
ТекстПриветствия = "Доброе утро!";
ИначеЕсли ЧасСуток >= 12 И ЧасСуток < 18 Тогда
ТекстПриветствия = "Добрый день!";
КонецЕсли;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = ТекстПриветствия;
Сообщение.Сообщить();
Подведем итог: для решения задачи "Приветствие по времени" лучше всего использовать функцию Час() от ТекущаяДатаСеанса() и числовое сравнение. Это избавит вас от синтаксических ошибок, логических наложений и проблем с часовыми поясами сервера.