В процессе разработки на встроенном языке 1С программисты, особенно начинающие, часто сталкиваются с ошибками, которые система квалифицирует как «Ожидается оператор» или «Ошибка синтаксиса». Зачастую проблема кроется в нарушении структуры управляющих конструкций: условий Если и циклов Для Каждого или Пока. Разберем на конкретном примере, как правильно выстраивать иерархию кода, работать с датами и обеспечивать корректное прерывание проведения документа.
Рассмотрим распространенную ошибку, когда при написании условия пропускаются ключевые слова или ставятся лишние знаки препинания. В языке 1С конструкция Если имеет строго определенный формат. Разберем типичные ошибки из практики:
Если.Иначе — это часть единого блока, и точка с запятой после нее (Иначе;) фактически обрывает выполнение всей инструкции, оставляя последующий код «висеть в воздухе».Тогда.Проанализируем правильную структуру кода:
Если <Условие> Тогда
// Действия, если условие истинно
ИначеЕсли <ДругоеУсловие> Тогда
// Действия, если второе условие истинно
Иначе
// Действия в остальных случаях
КонецЕсли;
Выясним причину возникновения ошибок, связанных с ключевыми словами КонецЦикла и КонецЕсли. В программировании на 1С действует принцип стека: блоки кода, которые открылись последними, должны закрываться первыми. Это называется правильной вложенностью.
Если мы открываем цикл внутри условия, то сначала мы должны завершить цикл, а только потом — условие. Посмотрим на примере:
Если ПроверкаВыполнена Тогда
Пока Выборка.Следующий() Цикл
// Какая-то логика
КонецЦикла; // Закрываем цикл
КонецЕсли; // Закрываем условие
В исходном коде автора темы наблюдалась путаница: блоки закрывались в произвольном порядке, что приводило к тому, что компилятор не понимал, к какому Если относится конкретный КонецЕсли. Помните: области Если...КонецЕсли и Цикл...КонецЦикла не могут пересекаться «крест-накрест».
В задачах часто встречается требование ограничить периодичность создания документов (например, не чаще одного раза в неделю). Для этого мы используем арифметику дат. В 1С тип данных Дата хранит значение в секундах. Чтобы прибавить к дате одну неделю, мы действительно умножаем 60 секунд на 60 минут, на 24 часа и на 7 дней.
Однако, при сравнении дат важно учитывать контекст выполнения. Если код исполняется в модуле объекта (например, в процедуре ОбработкаПроведения), обращаться к текущей дате документа следует просто по имени реквизита — Дата, а не через Объект.Дата. Использование префикса Объект характерно для модулей форм.
Разберем важный нюанс работы процедуры ОбработкаПроведения. Установка значения Отказ = Истина сообщает системе, что документ не должен быть проведен. Но важно понимать: этот оператор не останавливает выполнение кода немедленно. Весь последующий код процедуры будет выполнен до самого конца, если не предпринять дополнительных действий.
Рассмотрим правильный подход к проверке условий при проведении:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
// 1. Сначала делаем все проверки
Если Дата < ДатаПоследнейСпецификации + (60 * 60 * 24 * 7) Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не прошло 7 дней с момента создания последней спецификации!";
Сообщение.Сообщить();
Возврат; // Прерываем выполнение процедуры, чтобы не делать лишних расчетов
КонецЕсли;
// 2. Если проверки пройдены, формируем движения
Движения.Спецификация.Записывать = Истина;
Для Каждого Строка Из Детали Цикл
Движение = Движения.Спецификация.Добавить();
Движение.Период = Дата;
// Заполнение остальных полей...
КонецЦикла;
КонецПроцедуры
Использование оператора Возврат после установки Отказ = Истина — это признак хорошего тона в программировании. Это избавляет сервер от лишней работы по формированию движений, которые все равно будут отменены в конце транзакции.
Проанализируем ситуацию с получением данных. В исходном коде выполнялось обращение через точку: Выборка.Регистратор.Дата. С точки зрения производительности это не самый лучший вариант, так как происходит неявное соединение таблиц («разыменование ссылки»).
Поскольку в виртуальной таблице СрезПоследних поле Период чаще всего соответствует дате документа-регистратора, эффективнее получать именно его напрямую в тексте запроса. Это ускорит работу системы, особенно если документов в базе много.
Итоговые рекомендации для исправления кода:
Если ... Тогда.Иначе не стояла точка с запятой.Возврат при обнаружении ошибок проведения, чтобы сэкономить ресурсы системы.СообщениеПользователю, так как он позволяет привязать сообщение к конкретному реквизиту формы.