Ошибка при выполнении запроса в 1С редко называется так дословно: платформа пишет «Ошибка при вызове метода контекста (Выполнить)», а причину — ниже, после слов «по причине:». Вариантов три: 1С не разобрала текст запроса, СУБД не смогла его выполнить или пользователю не хватило прав. Ниже — как понять, какой вариант ваш, частые случаи и код для поиска места ошибки и записи в журнал регистрации.
Скопируйте текст из окна ошибки целиком, раскрыв подробности. Выглядит он примерно так:
{Обработка.ОстаткиТоваров.Форма.Форма.Форма(48)}: Ошибка при вызове метода контекста (Выполнить)
Выборка = Запрос.Выполнить().Выбрать();
по причине:
{(3, 2)}: Поле не найдено "Остатки.ВНаличииОстатокк"
<<?>>Остатки.ВНаличииОстатокк КАК Количество
{Обработка.ОстаткиТоваров.Форма.Форма.Форма(48)} — модуль и строка, где вызван Выполнить(). Это место вызова, а не ошибки.(Выполнить) — упавший метод, бывает ВыполнитьПакет.по причине: — настоящая причина. Уровней бывает несколько, смотрите последний.{(3, 2)} — строка и колонка в тексте запроса, а не в модуле. Счёт от первой строки Запрос.Текст, в пакете — от начала пакета.<<?>> — место, где разбор остановился.Главная развилка — координаты. Есть {(строка, колонка)} — 1С не разобрала текст, до СУБД запрос не дошёл, и ошибка повторится при каждом выполнении. Координат нет, зато есть «Ошибка СУБД» или «Конфликт блокировок» — текст верный, упало выполнение. Ошибка прав зависит от пользователя.
Если текст собран через СтрЗаменить() или сложение строк, строки запроса не совпадают со строками модуля. Место ошибки покажут две функции серверного общего модуля ЗапросыСервер:
// Общий модуль ЗапросыСервер (флажок «Сервер»). Часть 1: место ошибки в тексте запроса.
// Ищет в тексте ошибки координаты вида {(3, 2)} и возвращает структуру
// НомерСтроки, НомерКолонки. Координат нет — Неопределено: текст запроса
// разобран, а упало выполнение (СУБД, права, блокировки).
Функция КоординатыОшибкиЗапроса(Знач ТекстОшибки) Экспорт
Начало = СтрНайти(ТекстОшибки, "{(");
Если Начало = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Конец = СтрНайти(ТекстОшибки, ")}", НаправлениеПоиска.СНачала, Начало);
Если Конец = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Части = СтрРазделить(Сред(ТекстОшибки, Начало + 2, Конец - Начало - 2), ",", Ложь);
Если Части.Количество() <> 2 Тогда
Возврат Неопределено;
КонецЕсли;
ТипЧисло = Новый ОписаниеТипов("Число");
Возврат Новый Структура("НомерСтроки, НомерКолонки",
ТипЧисло.ПривестиЗначение(СокрЛП(Части[0])),
ТипЧисло.ПривестиЗначение(СокрЛП(Части[1])));
КонецФункции
// Строки текста запроса вокруг ошибки с номерами. Строка с ошибкой помечена ">>",
// на месте колонки вставлен маркер <<?>>, как в тексте ошибки платформы.
Функция ФрагментТекстаЗапроса(Знач ТекстЗапроса, НомерСтроки, НомерКолонки = 0, Окрестность = 3) Экспорт
Строки = СтрРазделить(ТекстЗапроса, Символы.ПС, Истина);
Первая = Макс(1, НомерСтроки - Окрестность);
Последняя = Мин(Строки.Количество(), НомерСтроки + Окрестность);
Результат = Новый Массив;
Для Номер = Первая По Последняя Цикл
ТекстСтроки = Строки[Номер - 1];
Метка = " ";
Если Номер = НомерСтроки Тогда
Метка = ">> ";
Если НомерКолонки > 0 Тогда
ТекстСтроки = Лев(ТекстСтроки, НомерКолонки - 1) + "<<?>>" + Сред(ТекстСтроки, НомерКолонки);
КонецЕсли;
КонецЕсли;
Результат.Добавить(Метка + Формат(Номер, "ЧГ=0") + ": " + ТекстСтроки);
КонецЦикла;
Возврат СтрСоединить(Результат, Символы.ПС);
КонецФункции
// Для запроса из примера выше ФрагментТекстаЗапроса(Запрос.Текст, 3, 2) вернёт:
// 1: ВЫБРАТЬ
// 2: Остатки.Номенклатура КАК Номенклатура,
// >> 3: <<?>>Остатки.ВНаличииОстатокк КАК Количество
// 4: ИЗ
// 5: РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад = &Склад) КАК Остатки
СтрНайти() ищет «{(», а заголовок модуля начинается с «{» и буквы, поэтому не мешает. СтрРазделить() с параметром Истина сохраняет пустые строки, иначе нумерация разъедется. Маркер вставляется по номеру символа, табуляция — тоже символ.
| Текст причины | Что случилось | Где подробнее |
|---|---|---|
| Синтаксическая ошибка | Опечатка, лишняя или пропущенная запятая, незакрытая скобка, склейка без пробела | Ниже, синтаксис запросов |
| Поле не найдено "…" | Нет такого поля: опечатка, другая конфигурация, переименование при обновлении | Ниже |
| Таблица не найдена "…" | Нет такого объекта метаданных или временной таблицы в менеджере | Ниже |
| Временная таблица уже существует | Повторный ПОМЕСТИТЬ в тот же менеджер | Ниже |
| Не задано значение параметра "…" | Нет УстановитьПараметр() или имя не совпадает | Параметры запроса |
| Неверные параметры | Функция запроса с неподходящими аргументами, например ЗНАЧЕНИЕ() с несуществующим предопределённым элементом | Функция ЗНАЧЕНИЕ() |
| Нельзя сравнивать поля неограниченной длины и поля несовместимых типов | Строка неограниченной длины в сравнении или группировке | ВЫРАЗИТЬ в запросе |
| Тип не может быть выбран в запросе | Колонка таблицы значений без типа | Таблица значений в запросе |
| У пользователя недостаточно прав на исполнение операции над базой данных | Ограничение на уровне записей, запрос без РАЗРЕШЕННЫЕ | Ниже |
| Конфликт блокировок при выполнении транзакции; Ошибка СУБД | Ожидание блокировки, взаимоблокировка, ресурсы СУБД | Ниже |
Если ошибки нет, а результат пустой, смотрите статью о пустом результате запроса.
Такая ошибка в запросе 1С не зависит от данных и пользователя. Маркер <<?>> стоит на слове, где разбор сломался, причина — в нём или прямо перед ним.
ИЗ, пропущенная ; между запросами пакета, латинская буква в ключевом слове.Если синтаксическая ошибка бывает только при некоторых отборах, текст собран кусками, и в одной из комбинаций остаётся ГДЕ без условия или условие с И в начале. Условия надёжнее копить в массиве (примеры — на регистре ТоварыНаСкладах из УТ 11 и КА 2):
// Было: к тексту всегда добавлялось «ГДЕ», а каждое условие начиналось с «И».
// При пустом первом отборе получалось «ГДЕ И ...», при пустых обоих — «ГДЕ»
// без условия: синтаксическая ошибка только у части пользователей.
// Стало: условия копятся в массиве и соединяются один раз.
// Отборы — Структура с ключами Склад и Номенклатура.
Функция ТекстЗапросаОстатков(Отборы) Экспорт
Условия = Новый Массив;
Если ЗначениеЗаполнено(Отборы.Склад) Тогда
Условия.Добавить("Склад = &Склад");
КонецЕсли;
Если ЗначениеЗаполнено(Отборы.Номенклатура) Тогда
Условия.Добавить("Номенклатура В ИЕРАРХИИ (&Номенклатура)");
КонецЕсли;
Текст =
"ВЫБРАТЬ
| Остатки.Номенклатура КАК Номенклатура,
| Остатки.Склад КАК Склад,
| Остатки.ВНаличииОстаток КАК Количество
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(, &УсловиеОтбора) КАК Остатки";
// Пустой массив даёт «Остатки(, )» — допустимая запись без условия
Возврат СтрЗаменить(Текст, "&УсловиеОтбора", СтрСоединить(Условия, " И "));
КонецФункции
Функция ОстаткиПоОтборам(Отборы) Экспорт
Запрос = Новый Запрос(ТекстЗапросаОстатков(Отборы));
// Параметр, которого нет в тексте, запросу не мешает
Запрос.УстановитьПараметр("Склад", Отборы.Склад);
Запрос.УстановитьПараметр("Номенклатура", Отборы.Номенклатура);
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Пустой массив даёт допустимую запись Остатки(, ), и висячих ГДЕ и И не будет ни при каком наборе отборов.
«Временная таблица уже существует» — ПОМЕСТИТЬ с тем же именем выполнили второй раз в том же менеджере, например в цикле, или доработка взяла занятое имя. В УТ 11.4 при проведении документа один менеджер из ДополнительныеСвойства.ДляПроведения.СтруктураВременныеТаблицы передаётся и в модули наборов записей, поэтому своим таблицам давайте имена с префиксом. «Таблица не найдена "ВТОстатки"» — читающий запрос создан без менеджера или с новым.
// Было: процедура добавляла ВТОстатки в общий менеджер, и второй вызов
// с тем же менеджером падал: «Временная таблица уже существует».
// Стало: перед созданием таблица уничтожается, если она уже есть.
Процедура ПоместитьОстаткиСклада(МенеджерВТ, Склад) Экспорт
УничтожитьВременнуюТаблицу(МенеджерВТ, "ВТОстатки");
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст =
"ВЫБРАТЬ
| Остатки.Номенклатура КАК Номенклатура,
| Остатки.ВНаличииОстаток КАК Количество
|ПОМЕСТИТЬ ВТОстатки
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад = &Склад) КАК Остатки";
Запрос.УстановитьПараметр("Склад", Склад);
Запрос.Выполнить();
КонецПроцедуры
Процедура УничтожитьВременнуюТаблицу(МенеджерВТ, ИмяТаблицы) Экспорт
Если МенеджерВТ.Таблицы.Найти(ИмяТаблицы) = Неопределено Тогда
Возврат;
КонецЕсли;
Запрос = Новый Запрос("УНИЧТОЖИТЬ " + ИмяТаблицы);
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Выполнить();
КонецПроцедуры
// Вызывайте перед запросом, который читает таблицы из менеджера, например
// ПроверитьВременныеТаблицы(Запрос.МенеджерВременныхТаблиц, "ВТОстатки, ВТЦены").
// Вместо «Таблица не найдена» будет видно, чего не хватает и что есть.
Процедура ПроверитьВременныеТаблицы(МенеджерВТ, Знач ИменаТаблиц) Экспорт
Если МенеджерВТ = Неопределено Тогда
ВызватьИсключение "Запросу не передан менеджер временных таблиц";
КонецЕсли;
Отсутствуют = Новый Массив;
Для Каждого Имя Из СтрРазделить(ИменаТаблиц, ",", Ложь) Цикл
Если МенеджерВТ.Таблицы.Найти(СокрЛП(Имя)) = Неопределено Тогда
Отсутствуют.Добавить(СокрЛП(Имя));
КонецЕсли;
КонецЦикла;
Если Отсутствуют.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ЕстьВМенеджере = Новый Массив;
Для Каждого Таблица Из МенеджерВТ.Таблицы Цикл
ЕстьВМенеджере.Добавить(Таблица.ПолноеИмя);
КонецЦикла;
ВызватьИсключение СтрШаблон("Нет временных таблиц: %1. В менеджере: %2",
СтрСоединить(Отсутствуют, ", "),
?(ЕстьВМенеджере.Количество() = 0, "пусто", СтрСоединить(ЕстьВМенеджере, ", ")));
КонецПроцедуры
В цикле по складам лучше один запрос с условием Склад В (&Склады), чем пересоздание таблицы. В УТ 11 и КА 2 похожие функции есть в модуле ОбщегоНазначенияУТ: СписокВременныхТаблиц() и УничтожитьВременныеТаблицы(). Содержимое временных таблиц в отладчике смотрят приёмом из статьи об отладке 1С.
«У пользователя недостаточно прав на исполнение операции над базой данных» при выполнении запроса — признак ограничения на уровне записей (RLS). Запрос без РАЗРЕШЕННЫЕ падает целиком, если закрыта хотя бы одна нужная ему запись; с РАЗРЕШЕННЫЕ закрытые записи просто не попадают в результат. На пользователя с полными правами ограничения не действуют.
// Пакет для отчёта: РАЗРЕШЕННЫЕ в каждом запросе, который читает таблицы базы
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Остатки.Номенклатура КАК Номенклатура,
Остатки.Склад КАК Склад,
Остатки.ВНаличииОстаток КАК Количество
ПОМЕСТИТЬ ВТОстатки
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад В (&Склады)) КАК Остатки
;
////////////////////////////////////////////////////////////////////////////////
// Второй запрос читает справочник неявно — через точку от ссылки
ВЫБРАТЬ РАЗРЕШЕННЫЕ
ВТОстатки.Номенклатура КАК Номенклатура,
ВТОстатки.Номенклатура.Артикул КАК Артикул,
ВТОстатки.Склад КАК Склад,
ВТОстатки.Количество КАК Количество
ИЗ
ВТОстатки КАК ВТОстатки
Слово нужно в каждом запросе пакета, который читает таблицы базы, в том числе через точку от ссылки. Там, где важна полнота — контроль остатков, сверки, — оно опасно: недоступные записи выпадут молча. Если у роли нет права чтения таблицы вообще, нужна настройка прав доступа, а не правка запроса.
Ошибка выполнения запроса в 1С 8.3 на клиент-серверной базе может прийти от СУБД: координат нет, после «по причине:» — «Конфликт блокировок при выполнении транзакции» или «Ошибка СУБД» с текстом MS SQL или PostgreSQL, иногда под заголовком «Ошибка при выполнении операции с информационной базой». Тайм-ауты и взаимоблокировки разобраны в статье о конфликте блокировок. Нехватка места под временные данные (tempdb, временные файлы PostgreSQL) — признак запроса с огромными промежуточными таблицами: нужны администратор и отборы в параметрах виртуальных таблиц.
В файловой базе:
1Cv8.1CD: проверьте копию утилитой chdbfl.exe из каталога bin платформы или «Тестированием и исправлением» в конфигураторе.Выполнить() в модуле из первой строки ошибки. Если ошибка внутри Попытка, включите «Отладка → Остановка по ошибке».ЗапросыСервер.СнимокЗапроса(Запрос) из листинга ниже — текст, параметры и временные таблицы придут одной строкой.Где отладчик не подключить — рабочая база, фоновое задание, HTTP-сервис, — помогает обёртка, которая при ошибке пишет снимок в журнал регистрации:
// Общий модуль ЗапросыСервер, часть 2: выполнение с записью в журнал регистрации.
// Использует функции КоординатыОшибкиЗапроса и ФрагментТекстаЗапроса из части 1.
// Выполняет запрос. При ошибке пишет снимок запроса в журнал регистрации
// и пробрасывает исходное исключение дальше.
Функция ВыполнитьЗапросСЖурналом(Запрос, Операция = "") Экспорт
Попытка
Возврат Запрос.Выполнить();
Исключение
ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации("Запросы.Ошибка выполнения", УровеньЖурналаРегистрации.Ошибка, , ,
"Операция: " + Операция + Символы.ПС + СнимокЗапроса(Запрос, ТекстОшибки));
ВызватьИсключение;
КонецПопытки;
КонецФункции
// Ошибка, место в тексте, полный текст, параметры и временные таблицы.
// В отладчике: «Вычислить выражение» → ЗапросыСервер.СнимокЗапроса(Запрос)
Функция СнимокЗапроса(Запрос, ТекстОшибки = "") Экспорт
Части = Новый Массив;
Если ЗначениеЗаполнено(ТекстОшибки) Тогда
Части.Добавить(ТекстОшибки);
Координаты = КоординатыОшибкиЗапроса(ТекстОшибки);
Если Координаты <> Неопределено Тогда
Части.Добавить(СтрШаблон("Место в тексте запроса: строка %1, колонка %2",
Координаты.НомерСтроки, Координаты.НомерКолонки));
Части.Добавить(ФрагментТекстаЗапроса(Запрос.Текст,
Координаты.НомерСтроки, Координаты.НомерКолонки));
КонецЕсли;
КонецЕсли;
Части.Добавить("Текст запроса:" + Символы.ПС + Запрос.Текст);
Части.Добавить("Параметры:");
Для Каждого Параметр Из Запрос.Параметры Цикл
Части.Добавить(" &" + Параметр.Ключ + " = " + ОписаниеЗначенияПараметра(Параметр.Значение));
КонецЦикла;
Если Запрос.МенеджерВременныхТаблиц <> Неопределено Тогда
Имена = Новый Массив;
Для Каждого Таблица Из Запрос.МенеджерВременныхТаблиц.Таблицы Цикл
Имена.Добавить(Таблица.ПолноеИмя);
КонецЦикла;
Части.Добавить("Временные таблицы в менеджере: " + СтрСоединить(Имена, ", "));
КонецЕсли;
Возврат СтрСоединить(Части, Символы.ПС);
КонецФункции
// Значение параметра с типом — без чтения базы: после ошибки СУБД внутри
// транзакции любое чтение данных упадёт с новой ошибкой и скроет исходную.
Функция ОписаниеЗначенияПараметра(Значение)
ТипЗначения = ТипЗнч(Значение);
Если ТипЗначения = Тип("ТаблицаЗначений") Тогда
Колонки = Новый Массив;
Для Каждого Колонка Из Значение.Колонки Цикл
// Колонка без типа — причина «Тип не может быть выбран в запросе»
БезТипа = (Колонка.ТипЗначения.Типы().Количество() = 0);
Колонки.Добавить(Колонка.Имя + ?(БезТипа, " (без типа!)", ""));
КонецЦикла;
Возврат СтрШаблон("ТаблицаЗначений, строк %1, колонки: %2",
Значение.Количество(), СтрСоединить(Колонки, ", "));
ИначеЕсли ТипЗначения = Тип("Массив") Или ТипЗначения = Тип("СписокЗначений") Тогда
Возврат СтрШаблон("%1, элементов %2", ТипЗначения, Значение.Количество());
ИначеЕсли ТипЗначения = Тип("МоментВремени") Тогда
Возврат СтрШаблон("МоментВремени: %1, %2", Значение.Дата, ОписаниеЗначенияПараметра(Значение.Ссылка));
ИначеЕсли ТипЗначения = Тип("Граница") Тогда
Возврат СтрШаблон("Граница (%1): %2", Значение.ВидГраницы, ОписаниеЗначенияПараметра(Значение.Значение));
КонецЕсли;
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗначения);
Если ОбъектМетаданных = Неопределено Тогда
// Строка, число, дата, булево, Неопределено — представление без обращения к базе
Представление = Строка(Значение);
Возврат СтрШаблон("%1 (%2)", ?(ПустаяСтрока(Представление), "<пусто>", Представление), ТипЗначения);
КонецЕсли;
Описание = ОбъектМетаданных.ПолноеИмя();
ЭтоСсылка = Справочники.ТипВсеСсылки().СодержитТип(ТипЗначения)
Или Документы.ТипВсеСсылки().СодержитТип(ТипЗначения)
Или Перечисления.ТипВсеСсылки().СодержитТип(ТипЗначения)
Или ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(ТипЗначения);
Если Не ЭтоСсылка Тогда
Возврат Описание;
ИначеЕсли Не ЗначениеЗаполнено(Значение) Тогда
Возврат Описание + ", пустая ссылка";
КонецЕсли;
// Строка(Ссылка) прочитала бы базу, поэтому пишем идентификатор (у перечисления — имя значения).
// В консоли ссылку восстановит XMLЗначение(Тип("СправочникСсылка.Склады"), Идентификатор)
Возврат Описание + ", " + XMLСтрока(Значение);
КонецФункции
// Вызов из серверной процедуры:
// Результат = ЗапросыСервер.ВыполнитьЗапросСЖурналом(Запрос, "Отчёт по остаткам");
ВызватьИсключение; без параметров пробрасывает исходную ошибку — вызывающий код видит прежний текст.Записи ищите в журнале регистрации по событию «Запросы.Ошибка выполнения»: в УТ 11.4 — «НСИ и администрирование → Обслуживание», в любой конфигурации — «Все функции → Стандартные → Журнал регистрации».
Первая строка подсказывает, чей код упал. ВнешняяОбработка или ВнешнийОтчет в имени модуля — подключённый файл не подходит к релизу. Модуль типового объекта — повторите на копии с отключёнными расширениями: пропала — виновато расширение. Повторяется на конфигурации без изменений — это ошибка релиза: ищут исправление от 1С, а до него программист закрывает её расширением. Программисту передайте:
Выполнить(), а координаты отсчитываются от начала текста запроса.Исключение. Вместо ошибки — пустой отчёт, а в транзакции следующая запись падает с «В данной транзакции уже происходили ошибки!» — см. статью о транзакциях в 1С.РАЗРЕШЕННЫЕ «чтобы не падало». Контрольный запрос начнёт молча терять записи.ВТТовары может совпасть с таблицей типового кода в общем менеджере.Упал метод Выполнить объекта Запрос, а причина — после «по причине:». Та же обёртка бывает у других методов, например (Записать).
Это 12-я строка текста запроса и 5-й символ в ней. Для одной строковой константы отсчитайте 12 строк от открывающей кавычки, для собранного текста смотрите итоговый текст в отладчике или через ФрагментТекстаЗапроса().
Чаще всего это права: ограничение на уровне записей и запрос без РАЗРЕШЕННЫЕ. Реже — его настройки отчёта или отборы, с которыми код собирает другой текст. Проверяйте под его учётной записью.
Нет. Здесь запрос — HTTP-обращение клиента к серверу 1С через веб-сервер, и нормального ответа не было. Частые причины: рабочий процесс упал или перезапустился, нередко из-за нехватки памяти; у учётной записи веб-сервера нет прав на каталог файловой базы; база повреждена. Если перезапуск клиента не помог и ошибка повторяется на одной операции, передайте администратору время и действие.
Если ошибка появилась после обновления в доработанном отчёте, связана с правами или тяжёлым запросом на рабочей базе, быстрее отдать её программисту с полным текстом. Опишите задачу на странице разместить задачу — оценка бесплатная, ответ в течение рабочего дня. Доработка отчётов и обработок — в разделе отчёты и обработки 1С.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.