При работе с Системой компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда необходимо преобразовать строковые данные, хранящиеся в комментариях или текстовых полях, в полноценный тип Дата для выполнения арифметических операций. Одной из самых коварных ошибок при этом является сообщение «ожидается ключевое слово "Конец"», которое появляется даже тогда, когда синтаксис оператора ВЫБОР кажется абсолютно верным. Разберем подробно причины этой проблемы и рассмотрим три эффективных способа ее решения.
Проанализируем ситуацию: когда мы пишем выражение в вычисляемом поле СКД, система пытается заранее определить тип возвращаемого значения. Ошибка парсера часто возникает не из-за отсутствия самого слова КОНЕЦ, а из-за несовместимости типов в ветках оператора ВЫБОР.
Рассмотрим пример кода, который часто приводит к ошибке:
ВЫБОР
КОГДА СчетНаОплатуПокупателюКомментарий <> NULL
ТОГДА Дата(СчетНаОплатуПокупателюКомментарий + " 00:00:00")
ИНАЧЕ "Не было"
КОНЕЦ
В данном случае в ветке ТОГДА система получает тип Дата, а в ветке ИНАЧЕ — тип Строка. СКД не может создать поле, которое одновременно является и датой, и строкой. В результате механизм разбора выражения «сбивается» и выдает неинформативное сообщение об ожидании ключевого слова. Чтобы этого избежать, всегда приводите все ветки условия к единому типу. Например, вместо строки "Не было" следует использовать пустую дату — ДАТАВРЕМЯ(1, 1, 1).
Если в вашей конфигурации (например, в «Бухгалтерии предприятия 2.0») дата реализации или оплаты записана в комментарии в формате «12.10.2018», ее нельзя просто передать в функцию Дата(). Система 1С ожидает формат «ГГГГММДД» или «ГГГГ-ММ-ДД».
Посмотрим, как можно «пересобрать» строку прямо в вычисляемом поле СКД, не прибегая к изменению кода конфигурации. Мы воспользуемся функцией ПОДСТРОКА, чтобы извлечь год, месяц и день, а затем объединим их в правильном порядке:
Дата(
Подстрока(СчетНаОплатуПокупателюКомментарий, 7, 4) + // Год
Подстрока(СчетНаОплатуПокупателюКомментарий, 4, 2) + // Месяц
Подстрока(СчетНаОплатуПокупателюКомментарий, 1, 2) // День
)
Важный нюанс: Перед преобразованием обязательно проверьте поле на наличие данных. Если в комментарии будет пустая строка или текст другого формата, отчет завершится с ошибкой. Проанализируем безопасный вариант выражения:
ВЫБОР
КОГДА ДлинаСтроки(СчетНаОплатуПокупателюКомментарий) >= 10
ТОГДА Дата(Подстрока(СчетНаОплатуПокупателюКомментарий, 7, 4) + Подстрока(СчетНаОплатуПокупателюКомментарий, 4, 2) + Подстрока(СчетНаОплатуПокупателюКомментарий, 1, 2))
ИНАЧЕ ДАТАВРЕМЯ(1, 1, 1)
КОНЕЦ
Хранение важных дат в строковом поле комментария — это плохая практика, которая ведет к ошибкам ввода. Более правильным решением будет использование механизма дополнительных свойств (в БП 2.0) или дополнительных реквизитов (в БП 3.0). Это позволит хранить данные сразу в типе Дата.
Разберем, как подключить эти данные в СКД через вкладку «Характеристики»:
ЗначенияСвойствОбъектов.Этот метод позволяет обращаться к дате напрямую: СчетНаОплату.ДополнительноеСвойство_ДатаОплаты. Поле уже будет иметь нужный тип, и вам не придется заниматься строковыми преобразованиями.
Когда мы успешно получили дату из комментария (или доп. реквизита), нам нужно вычислить разницу между ней и датой реализации. В вычисляемых полях СКД для этого существует встроенная функция РАЗНОСТЬДАТ.
Рассмотрим пример вычисления разности в днях:
РАЗНОСТЬДАТ(ДатаРеализации, ВычисленноеПолеДатаИзКомментария, "ДЕНЬ")
Обратите внимание: Если вы попытаетесь просто вычесть одну дату из другой (Дата1 - Дата2), в языке запросов вы получите разницу в секундах, а в вычисляемом поле результат может зависеть от настроек платформы. Использование функции РАЗНОСТЬДАТ с указанием типа "ДЕНЬ" является наиболее надежным и кроссплатформенным решением.
При работе в СКД важно различать NULL (отсутствие записи в базе при левом соединении) и пустую строку (запись есть, но она не заполнена).
Проанализируем типичную ошибку: проверка Поле <> NULL часто не срабатывает для пустых строк. Поэтому в условиях ВЫБОР в СКД лучше использовать проверку на длину строки или сравнение с пустой строкой:
ВЫБОР
КОГДА СчетНаОплатуПокупателюКомментарий ЕСТЬ NULL ИЛИ СчетНаОплатуПокупателюКомментарий = ""
ТОГДА ДАТАВРЕМЯ(1, 1, 1)
...
Подводя итог, можно сказать, что решение проблемы «ожидается ключевое слово Конец» заключается в строгом контроле типов возвращаемых значений. Если вы используете СКД для сложных отчетов, старайтесь либо преобразовывать строки в даты по формату «ГГГГММДД», либо использовать штатные механизмы характеристик 1С, что значительно упростит поддержку кода в будущем.