Как исправить ошибку Ожидается ключевое слово Конец в запросе 1С

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

При работе с языком запросов «1С:Предприятие» программисты часто сталкиваются с ситуацией, когда система выдает ошибку «Ожидается ключевое слово "Конец"» (Expected keyword "End"), хотя само слово КОНЕЦ в коде присутствует. Это типичная ситуация «каскадной ошибки», когда синтаксический анализатор (парсер) сбивается из-за опечатки в середине сложной конструкции. В этой статье мы подробно разберем, почему это происходит на примере оператора ВЫБОР, и научимся писать чистый и отказоустойчивый код для работы с периодами.

Анализ исходной проблемы: почему «разваливается» запрос

Рассмотрим ситуацию, с которой столкнулся автор темы. В его запросе использовалась многоуровневая конструкция ВЫБОР для определения текстового представления декад месяца. Проанализируем фрагмент кода, который вызвал сбой:


Выбор 
Когда Дата42ДняПослеОтела >= ДатаВремя(2019, 01, 01) и Дата42ДняПослеОтела <= ДатаВремя(2019, 01, 10) 
Тогда "01 янв - 10 янв" 
...
Когда Дата42ДняПослеОтела >= ДатаВремя(2019, 02, 10) и Дата42ДняПослеОтела <= ДатаВремя(2019, 02, 19) 
Тогда "10 фев" - 19 фев" 
Когда Дата42ДняПослеОтела >= ДатаВремя(2019, 02, 20) и Дата42ДняПослеОтела <= ДатаВремя(2019, 03, 01) 
Тогда "20 фев" - 01 мар"
Конец

Если внимательно посмотреть на строки с результатами, мы увидим лишние кавычки. Разберем механизм ошибки по шагам. Когда парсер 1С встречает строку "10 фев" - 19 фев", он интерпретирует её следующим образом:

  1. Открывающая кавычка перед числом 10 начинает строковый литерал.
  2. Кавычка после слова фев закрывает этот литерал. Для системы строка закончилась на фразе "10 фев".
  3. Далее следует дефис (оператор вычитания) и текст 19 фев", который не является ни командой, ни параметром, ни строкой (так как нет открывающей кавычки).

В этот момент синтаксическая структура оператора ВЫБОР нарушается. Система ожидает продолжения логики (другое условие КОГДА или завершение КОНЕЦ), но натыкается на мусорный текст. В итоге анализатор «теряет» контекст и сообщает, что не нашел ожидаемое завершение блока. Это классический пример замыленности глаза, когда одна лишняя кавычка ломает весь запрос.

Правила работы со строками в запросах 1С

Чтобы избежать подобных проблем, важно помнить правила экранирования символов. Если вам необходимо включить символ кавычки в саму строку (внутри текстового результата), этот символ нужно удваивать. Рассмотрим пример исправления:

Неправильно: Тогда "20 фев" - 01 мар"

Правильно (если кавычки не нужны в результате): Тогда "20 фев - 01 мар"

Правильно (если кавычки должны отображаться): Тогда """20 фев"" - 01 мар"

В контексте данной задачи автору просто нужно было убрать лишние символы внутри текста, чтобы получить корректный интервал дат в виде строки.

Оптимизация кода: использование оператора МЕЖДУ

Посмотрим на условия в коде автора. Он использует связку >= и <=. Хотя это технически верно, такая запись перегружает визуальное восприятие запроса и повышает риск ошибки при копировании. В языке запросов 1С предусмотрен более элегантный оператор МЕЖДУ (BETWEEN).

Давайте перепишем один из блоков ВЫБОР, используя этот оператор:


Выбор 
    Когда Дата42ДняПослеОтела МЕЖДУ ДатаВремя(2019, 01, 01) И ДатаВремя(2019, 01, 10) 
        Тогда "01 янв - 10 янв" 
    Когда Дата42ДняПослеОтела МЕЖДУ ДатаВремя(2019, 01, 11) И ДатаВремя(2019, 01, 20) 
        Тогда "11 янв - 20 янв" 
Конец

Такой подход значительно упрощает чтение кода и делает логику интервалов прозрачной. Оператор МЕЖДУ включает обе границы периода (и начало, и конец), что идеально подходит для работы с датами.

Использование стандартных функций работы с периодами

В сообщении №8 форума прозвучало предложение использовать функцию НАЧАЛОПЕРИОДА с типом ДЕКАДА. Это очень правильное направление мысли, которое позволяет уйти от «хардкода» (жесткого прописывания дат в тексте запроса).

Проанализируем работу функции НАЧАЛОПЕРИОДА(Дата, ДЕКАДА):

  1. Для любой даты с 1 по 10 число месяца она вернет 1-е число этого месяца.
  2. Для дат с 11 по 20 число она вернет 11-е число.
  3. Для всех остальных дат до конца месяца она вернет 21-е число.

Однако стоит учитывать нюанс: эта функция возвращает значение типа Дата, а не красивую строку «01 янв - 10 янв». Чтобы получить текстовое представление, можно использовать ВЫБОР не по конкретным датам, а по номеру дня в месяце или просто выводить дату начала декады в отчет, а форматирование делать уже на уровне системы компоновки данных (СКД).

Проблема магических дат и масштабируемости

В исходном примере мы видим использование функции ДатаВремя(2019, 01, 01). Это называется «магическими значениями». Если отчет занадобится в 2020 или 2024 году, программисту придется вручную переписывать весь запрос. Выясним, как этого избежать.

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


ВЫБОР
    КОГДА ДЕНЬ(Дата42ДняПослеОтела) <= 10 ТОГДА "1-я декада " + ФОРМАТ(Дата42ДняПослеОтела, "ДФ='МММ гггг'")
    КОГДА ДЕНЬ(Дата42ДняПослеОтела) <= 20 ТОГДА "2-я декада " + ФОРМАТ(Дата42ДняПослеОтела, "ДФ='МММ гггг'")
    ИНАЧЕ "3-я декада " + ФОРМАТ(Дата42ДняПослеОтела, "ДФ='МММ гггг'")
КОНЕЦ

Важное примечание: Функцию ФОРМАТ нельзя использовать напрямую в языке запросов (она доступна только в СКД или в коде 1С). В самом запросе для формирования сложных строк часто приходится использовать конструкции ПРЕДСТАВЛЕНИЕ или оставлять обработку строк для вычисляемых полей СКД.

Рекомендации по поиску ошибок в сложных ВЫБОР

Если ваш запрос содержит десятки условий КОГДА...ТОГДА, найти опечатку становится крайне сложно. Разберем алгоритм эффективной отладки:

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

Подводя итог, можно сказать, что ошибка «Ожидается ключевое слово "Конец"» в 90% случаев является следствием невнимательности при написании строк или пропущенных скобок. Использование операторов типа МЕЖДУ и стандартных функций работы с датами позволяет сократить объем кода и минимизировать риск таких досадных ошибок.

← На главную