Как исправить ошибки в операторных скобках и логике проведения документа в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки на встроенном языке 1С программисты, особенно начинающие, часто сталкиваются с ошибками, которые система квалифицирует как «Ожидается оператор» или «Ошибка синтаксиса». Зачастую проблема кроется в нарушении структуры управляющих конструкций: условий Если и циклов Для Каждого или Пока. Разберем на конкретном примере, как правильно выстраивать иерархию кода, работать с датами и обеспечивать корректное прерывание проведения документа.

Анализ синтаксиса условного оператора Если

Рассмотрим распространенную ошибку, когда при написании условия пропускаются ключевые слова или ставятся лишние знаки препинания. В языке 1С конструкция Если имеет строго определенный формат. Разберем типичные ошибки из практики:

  1. Пропуск ключевого слова Если: Нельзя начинать проверку условия сразу с выражения. Любое ветвление должно начинаться с Если.
  2. Точка с запятой после Иначе: Это критическая ошибка. Конструкция Иначе — это часть единого блока, и точка с запятой после нее (Иначе;) фактически обрывает выполнение всей инструкции, оставляя последующий код «висеть в воздухе».
  3. Отсутствие Тогда: После выражения условия обязательно должно следовать слово Тогда.

Проанализируем правильную структуру кода:


Если <Условие> Тогда
    // Действия, если условие истинно
ИначеЕсли <ДругоеУсловие> Тогда
    // Действия, если второе условие истинно
Иначе
    // Действия в остальных случаях
КонецЕсли;

Правила вложенности операторных скобок

Выясним причину возникновения ошибок, связанных с ключевыми словами КонецЦикла и КонецЕсли. В программировании на 1С действует принцип стека: блоки кода, которые открылись последними, должны закрываться первыми. Это называется правильной вложенностью.

Если мы открываем цикл внутри условия, то сначала мы должны завершить цикл, а только потом — условие. Посмотрим на примере:


Если ПроверкаВыполнена Тогда
    Пока Выборка.Следующий() Цикл
        // Какая-то логика
    КонецЦикла; // Закрываем цикл
КонецЕсли; // Закрываем условие

В исходном коде автора темы наблюдалась путаница: блоки закрывались в произвольном порядке, что приводило к тому, что компилятор не понимал, к какому Если относится конкретный КонецЕсли. Помните: области Если...КонецЕсли и Цикл...КонецЦикла не могут пересекаться «крест-накрест».

Работа с датами и временем в условиях

В задачах часто встречается требование ограничить периодичность создания документов (например, не чаще одного раза в неделю). Для этого мы используем арифметику дат. В 1С тип данных Дата хранит значение в секундах. Чтобы прибавить к дате одну неделю, мы действительно умножаем 60 секунд на 60 минут, на 24 часа и на 7 дней.

Однако, при сравнении дат важно учитывать контекст выполнения. Если код исполняется в модуле объекта (например, в процедуре ОбработкаПроведения), обращаться к текущей дате документа следует просто по имени реквизита — Дата, а не через Объект.Дата. Использование префикса Объект характерно для модулей форм.

Логика проведения и параметр Отказ

Разберем важный нюанс работы процедуры ОбработкаПроведения. Установка значения Отказ = Истина сообщает системе, что документ не должен быть проведен. Но важно понимать: этот оператор не останавливает выполнение кода немедленно. Весь последующий код процедуры будет выполнен до самого конца, если не предпринять дополнительных действий.

Рассмотрим правильный подход к проверке условий при проведении:


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

Использование оператора Возврат после установки Отказ = Истина — это признак хорошего тона в программировании. Это избавляет сервер от лишней работы по формированию движений, которые все равно будут отменены в конце транзакции.

Оптимизация запроса в цикле

Проанализируем ситуацию с получением данных. В исходном коде выполнялось обращение через точку: Выборка.Регистратор.Дата. С точки зрения производительности это не самый лучший вариант, так как происходит неявное соединение таблиц («разыменование ссылки»).

Поскольку в виртуальной таблице СрезПоследних поле Период чаще всего соответствует дате документа-регистратора, эффективнее получать именно его напрямую в тексте запроса. Это ускорит работу системы, особенно если документов в базе много.

Итоговые рекомендации для исправления кода:

← На главную