При работе в 1С:Предприятие 8 часто возникает необходимость массово скорректировать реквизиты документов. Одной из специфических задач является изменение времени создания документов (часов и минут) при сохранении исходной даты. Стандартная обработка «Групповое изменение реквизитов» позволяет сделать это эффективно, если использовать механизм «Произвольного алгоритма». В этой статье мы подробно разберем, как правильно составить программный код для этой задачи, как избежать распространенных ошибок и какие настройки платформы необходимо проверить.
Рассмотрим ситуацию: нам нужно во всем списке документов «Сборка товаров» (или любом другом виде документов) установить единое время — например, 16:30. В системе 1С:Предприятие тип данных Дата всегда содержит в себе и календарную дату, и время (часы, минуты, секунды). Чтобы изменить только время, нам необходимо сначала «обнулить» время в исходной дате, приведя её к началу дня (00:00:00), а затем прибавить нужное количество секунд, соответствующих желаемому времени.
Проанализируем математическую составляющую:
(16 * 3600) + (30 * 60) секунд.Для реализации задачи в стандартной обработке «Групповое изменение реквизитов» выберем нужные документы и перейдем к написанию кода. Рассмотрим наиболее надежный вариант алгоритма:
Объект.Дата = НачалоДня(Объект.Дата) + (16 * 3600) + (30 * 60);
Разберем подробнее, почему код написан именно так:
Объект — это специальная переменная, через которую обработка обращается к текущему редактируемому документу в цикле. Обращение напрямую через Дата = ... часто приводит к ошибке, так как система может не понять, к какому именно объекту относится это поле.НачалоДня(Объект.Дата) — встроенная функция 1С, которая отсекает время, оставляя только дату. Например, из "25.05.2023 11:45:12" получится "25.05.2023 00:00:00".+ (16 * 3600) + (30 * 60) — к полученной дате прибавляется числовое значение в секундах. Платформа 1С корректно интерпретирует сложение типа Дата и Число, сдвигая время вперед.Выясним причину возникновения этой ошибки, которая часто встречается у пользователей. Проанализируем ситуацию: если вы вводите код Дата = НачалоДня(Дата) + ... и получаете сообщение о невозможности преобразования, это может происходить по нескольким причинам:
1. Конфликт имен переменных. Если в коде не указан префикс Объект., система может пытаться работать с локальной переменной Дата, которая на момент вычисления является пустой или неопределенной. Использование Объект.Дата гарантирует обращение к реквизиту документа.
2. Типизация данных. Важно следить за тем, чтобы к дате прибавлялось именно Число. Если вы случайно заключите выражение в кавычки или передадите его как строку, система выдаст ошибку. Рассмотрим пример правильной типизации:
// Правильно: прибавляем результат математического выражения (число)
Объект.Дата = НачалоДня(Объект.Дата) + Число(16 * 3600 + 30 * 60);
3. Пустые значения. Если в выборку попал документ с незаполненной датой (хотя для документов это аномалия), функция НачалоДня() может вернуть ошибку. Для надежности можно добавить проверку:
Если ЗначениеЗаполнено(Объект.Дата) Тогда
Объект.Дата = НачалоДня(Объект.Дата) + 59400; // 59400 — это 16:30 в секундах
КонецЕсли;
Даже если код написан верно, изменения могут не сохраниться в базе данных. Проанализируем настройки самой обработки «Групповое изменение реквизитов»:
Дополнительные параметры: Нажмите на кнопку «Дополнительные параметры» (обычно находится в нижней части формы или под кнопкой «Еще»). Убедитесь, что установлены следующие флаги:
Если по каким-то причинам стандартная групповая обработка не справляется, рассмотрим вариант написания собственной небольшой процедуры. Это полезно, когда требуется сложная логика отбора или дополнительная обработка документов. Посмотрим на пример кода:
&НаСервере
Процедура ОбработатьДокументыНаСервере()
// Выбираем документы за определенный период
Выборка = Документы.СборкаТоваров.Выбрать(ДатаНачала, ДатаОкончания);
Пока Выборка.Следующий() Цикл
ДокОбъект = Выборка.Ссылка.ПолучитьОбъект();
// Устанавливаем новое время 16:30
ДокОбъект.Дата = НачалоДня(ДокОбъект.Дата) + 16 * 3600 + 30 * 60;
// Попытка записи объекта
Попытка
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
Исключение
Сообщить("Не удалось записать документ: " + ДокОбъект.Ссылка + " Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
КонецПроцедуры
В данном примере мы используем метод ПолучитьОбъект(), так как менять данные можно только у объекта, а не у ссылки. Метод Записать(РежимЗаписиДокумента.Запись) просто сохраняет изменения без перепроведения документа. Если вам важно, чтобы документ пересчитал движения в регистрах по новому времени, следует использовать РежимЗаписиДокумента.Проведение, однако это потребует больше времени и может вызвать ошибки из-за контроля остатков.
Прежде чем запускать групповое изменение на всей базе, выполним следующие шаги:
Подводя итог, можно сказать, что формула Объект.Дата = НачалоДня(Объект.Дата) + Секунды является эталонным способом работы со временем в 1С. Главное — помнить о необходимости использования префикса Объект. и проверять настройки автоматической записи в параметрах обработки.