Где хранить текст запроса 1С, чтобы он не потерялся и работал

· 10 мин

Содержание

Сохранить запрос в 1С можно пятью способами: скопировать текст в буфер обмена, записать его в файл, положить в макет обработки или расширения, завести справочник с запросами или держать тексты во внешнем хранилище — Git, хранилище конфигурации, хранилище общих настроек. Для разового отчёта хватает файла. Для запроса, которым пользуется отдел, — макет или справочник.

Сохранять нужно не только текст. Запрос без значений параметров через месяц не воспроизвести: непонятно, за какой период и по какой организации он считался. Все примеры кода — для платформы 8.3, их можно вставить в свою обработку или расширение.

Что именно сохранять вместе с текстом запроса

Текст запроса — только половина дела. Чтобы запрос можно было открыть и выполнить снова, рядом с ним держат:

  • 📝 текст запроса — ровно в том виде, в котором его принимает объект Запрос;
  • 🔢 параметры — имена и значения: &НачалоПериода, &Организация, &Склад;
  • 🏷️ имя и назначение — «Остатки по складам на дату для сверки с бухгалтерией», а не «Запрос1»;
  • 📅 дату и автора — кто и когда менял, чтобы понимать, какой версии верить;
  • ⚙️ конфигурацию и релиз, под которые он написан: после обновления имена реквизитов и регистров могут поменяться.

Способы различаются тем, сколько из этого списка они сохраняют автоматически.

СпособЧто сохраняетКогда подходитРиски
Буфер обменаТолько текст, до следующего копированияПеренести текст из консоли в кодПотеря при закрытии окна или новом Ctrl+C
ФайлТекст, по желанию параметрыЛичная библиотека, передача коллегеФайлы расползаются по папкам, версий нет
Макет обработки или расширенияТекст, вместе с кодомОтчёт или обработка для пользователейПравка текста — через Конфигуратор
СправочникТекст, параметры, автор, датаНабор запросов для отделаНужны права и контроль, кто что выполняет
Git, хранилище конфигурации, общие настройкиТекст и история измененийКомандная разработкаТребует дисциплины и настройки

Способ 1. Сохранение запроса через буфер обмена

Самый быстрый путь: выделить текст в консоли запросов или в модуле и нажать Ctrl+C. Так делают, когда запрос собран в конструкторе и его нужно перенести в код.

Как получить текст из разных мест:

  1. Конструктор запроса в Конфигураторе. В модуле щёлкните правой кнопкой по тексту запроса и выберите Конструктор запроса.... После нажатия «ОК» текст вернётся в модуль уже оформленным строкой с символами | в начале строк.
  2. Консоль запросов. Выделите текст в поле запроса, Ctrl+A, Ctrl+C.
  3. Отладчик. Если запрос собирается в коде из кусков и вы не видите итоговый текст, поставьте точку останова перед Запрос.Выполнить(). Откройте вычисление выражения (Shift+F9), введите Запрос.Текст и скопируйте значение. Здесь же видно содержимое Запрос.Параметры.

Третий приём выручает чаще всего. Текст, который собирается из условий и подстановок, иначе приходится восстанавливать руками.

Буфер обмена — не хранилище. Закрыли консоль без сохранения, скопировали что-то ещё — текст пропал. Сразу после копирования вставьте его в файл, макет или модуль.

При вставке текста из консоли в модуль кавычки внутри запроса нужно удвоить: строковый литерал "Поставщик" внутри текста превращается в ""Поставщик"". Конструктор запроса делает это сам, ручная вставка — нет.

Способ 2. Экспорт запроса в файл: текст и параметры

Файл — хороший вариант для личной библиотеки запросов и для передачи коллеге. Большинство консолей запросов умеют сохранять список запросов в файл и открывать его обратно. Если консоль своя или такой команды нет, сохранение пишется в несколько строк.

Только текст — в обычный .txt

&НаСервере
Процедура СохранитьТекстЗапроса(ТекстЗапроса, ИмяФайла)
    Документ = Новый ТекстовыйДокумент;
    Документ.УстановитьТекст(ТекстЗапроса);
    Документ.Записать(ИмяФайла, КодировкаТекста.UTF8);
КонецПроцедуры

&НаСервере
Функция ПрочитатьТекстЗапроса(ИмяФайла)
    Документ = Новый ТекстовыйДокумент;
    Документ.Прочитать(ИмяФайла, КодировкаТекста.UTF8);
    Возврат Документ.ПолучитьТекст();
КонецФункции

Кодировку указывайте явно. Файл в UTF-8 корректно откроется в любом редакторе и в системе контроля версий.

Текст вместе с параметрами

Чтобы не вспоминать, с какими значениями запрос выполнялся, сохраните текст и параметры одной структурой:

&НаСервере
Процедура СохранитьЗапросСПараметрами(Запрос, ИмяФайла)
    Данные = Новый Структура("Текст, Параметры", Запрос.Текст, Запрос.Параметры);
    Документ = Новый ТекстовыйДокумент;
    Документ.УстановитьТекст(ЗначениеВСтрокуВнутр(Данные));
    Документ.Записать(ИмяФайла, КодировкаТекста.UTF8);
КонецПроцедуры

&НаСервере
Функция ЗагрузитьЗапросСПараметрами(ИмяФайла)
    Документ = Новый ТекстовыйДокумент;
    Документ.Прочитать(ИмяФайла, КодировкаТекста.UTF8);
    Данные = ЗначениеИзСтрокиВнутр(Документ.ПолучитьТекст());

    Запрос = Новый Запрос(Данные.Текст);
    Для Каждого КлючИЗначение Из Данные.Параметры Цикл
        Запрос.УстановитьПараметр(КлючИЗначение.Ключ, КлючИЗначение.Значение);
    КонецЦикла;
    Возврат Запрос;
КонецФункции

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

Код с &НаСервере пишет файл на диск той машины, где работает сервер 1С. В файловой базе это компьютер пользователя, в клиент-серверной — сервер. Ищите файл там, а для записи на диск пользователя используйте диалог выбора файла на клиенте.

Минус файлового способа — дисциплина. Через полгода у каждого в «Документах» лежат «остатки_новый.txt», «остатки_новый2.txt», и какой из них правильный, не помнит никто. Договоритесь об одной общей папке и шаблоне имени: Конфигурация_Назначение_ГГГГММДД.txt.

Способ 3. Запрос в макете обработки, конфигурации или расширения

Если запрос нужен в отчёте или обработке, его текст удобно держать не строкой в модуле, а в макете типа «Текстовый документ». Код становится короче, текст запроса читается без символов | и удвоенных кавычек.

Как это сделать

  1. Откройте обработку, общий макет конфигурации или расширение в Конфигураторе.
  2. В ветке «Макеты» добавьте новый макет, тип — «Текстовый документ». Назовите по смыслу, например ОстаткиПоСкладам.
  3. Вставьте в макет текст запроса как есть, без кавычек и |.
  4. Получите текст в коде.

Для макета внешней или встроенной обработки:

&НаСервере
Функция ТекстЗапросаОстатки()
    Обработка = РеквизитФормыВЗначение("Объект");
    Возврат Обработка.ПолучитьМакет("ОстаткиПоСкладам").ПолучитьТекст();
КонецФункции

Для общего макета конфигурации или расширения:

ТекстЗапроса = ПолучитьОбщийМакет("ОстаткиПоСкладам").ПолучитьТекст();
Запрос = Новый Запрос(ТекстЗапроса);

Почему для команды выбирают расширение

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

Порядок для расширения:

  1. Конфигурация → Расширения конфигурации, создайте расширение или откройте существующее.
  2. Добавьте общий макет «Текстовый документ» с текстом запроса и общий модуль, который его выполняет.
  3. Обновите конфигурацию базы данных расширения (F7 в окне расширения).
  4. Если запрос обращается к регистрам и справочникам, заимствуйте нужные объекты в расширение — иначе при проверке он не найдёт таблицы.

Внешнюю обработку с макетами в типовой БП 3.0 подключают пользователям через Администрирование → Печатные формы, отчеты и обработки → Дополнительные отчеты и обработки.

После обновления типовой конфигурации прогоните сохранённые запросы. Если в новом релизе переименовали реквизит или регистр, запрос упадёт с ошибкой вида Поле не найдено, и узнаете вы об этом от пользователя.

Способ 4. Хранение запросов в справочнике базы

Когда запросов десятки и ими пользуются несколько человек, удобно хранить их прямо в базе. Такой подход встречается реже, но даёт главное: поиск, автора, дату и параметры в одном месте.

Структура справочника

В расширении или в своей конфигурации создайте справочник, например СохраненныеЗапросы:

РеквизитТипЗачем
НаименованиеСтрокаПонятное название запроса
ТекстЗапросаСтрока, длина 0Текст запроса, длина 0 означает неограниченную строку
ОписаниеСтрока, длина 0Что считает, для какой задачи
АвторСправочникСсылка.ПользователиКто создал или менял
ДатаИзмененияДатаКогда меняли последний раз
ПараметрыЗапроса (табличная часть)Имя — Строка, Значение — составной типЗначения параметров по умолчанию

Группы справочника позволяют разложить запросы по темам: склад, расчёты, зарплата.

Выполнение запроса из справочника

&НаСервере
Функция ВыполнитьСохраненныйЗапрос(СсылкаНаЗапрос)
    Запрос = Новый Запрос(СсылкаНаЗапрос.ТекстЗапроса);
    Для Каждого СтрокаПараметра Из СсылкаНаЗапрос.ПараметрыЗапроса Цикл
        Запрос.УстановитьПараметр(СтрокаПараметра.Имя, СтрокаПараметра.Значение);
    КонецЦикла;
    Возврат Запрос.Выполнить().Выгрузить();
КонецФункции

Результат — таблица значений. Её можно вывести в табличный документ на форме и оттуда сохранить в Excel.

Справочник с произвольными запросами — это возможность для пользователя прочитать любые данные, к которым у него есть доступ. Не выполняйте такие запросы в привилегированном режиме: так пользователь обойдёт ограничения прав на уровне записей. Право на изменение элементов справочника давайте только тем, кто пишет запросы, остальным — только на чтение и выполнение.

Способ 5. Внешние хранилища для запросов: Git, хранилище конфигурации, общие настройки

Для команды разработчиков главное — история изменений. Кто поменял условие отбора и почему отчёт стал показывать другую сумму, видно только в системе с версиями.

Хранилище конфигурации

Если запросы лежат в макетах конфигурации или расширения, их версии хранит хранилище конфигурации. Каждое помещение объекта — это версия с автором, датой и комментарием. Старый текст макета можно сравнить с новым через отчёт по истории объекта.

Git

Конфигурацию можно выгрузить в XML-файлы: Конфигурация → Выгрузить конфигурацию в файлы. Макеты типа «Текстовый документ» попадают в выгрузку обычными текстовыми файлами, и Git показывает построчную разницу в тексте запроса. В 1С:EDT проект изначально хранится в файлах, и запросы в макетах версионируются вместе с кодом.

Личную библиотеку .txt-файлов из способа 2 тоже стоит положить в репозиторий. Это решает проблему «остатки_новый2.txt»: файл один, история — в коммитах.

Хранилище общих настроек

Для запросов, которые нужны одному пользователю и не должны попадать в код, подходит хранилище общих настроек. Значение сохраняется в базе и привязано к пользователю:

ХранилищеОбщихНастроек.Сохранить("МоиЗапросы", "ОстаткиПоСкладам", ТекстЗапроса);

ТекстЗапроса = ХранилищеОбщихНастроек.Загрузить("МоиЗапросы", "ОстаткиПоСкладам");
Если ТекстЗапроса = Неопределено Тогда
    // Настройка ещё не сохранялась
    ТекстЗапроса = "";
КонецЕсли;

Для сохранения у пользователя должно быть право «Сохранение данных пользователя». Если его нет, вызов закончится ошибкой.

Какой способ сохранения запроса подходит вам?

Ошибки при сохранении запросов и как их избежать

  • 🔤 Неудвоенные кавычки. Текст вставили в модуль строкой, а внутри был литерал "Основной". Модуль не компилируется. Либо удвойте кавычки, либо перенесите текст в макет, где их удваивать не нужно.
  • 🧩 Сохранён текст без временных таблиц. Запрос из пакета ссылается на ВТ_Остатки, а сама таблица создавалась предыдущим запросом пакета или жила в менеджере временных таблиц. Отдельно такой текст не выполнится. Сохраняйте пакет целиком.
  • 🔗 Ссылки в параметрах переносят в другую базу. Сохранённая во внутреннем формате ссылка на организацию в копии базы может указывать на другой объект или ни на что. Для переноса между базами храните в параметрах код или ИНН и ищите ссылку при загрузке.
  • 🗂️ Неверная кодировка файла. Файл записали в одной кодировке, открыли в другой — вместо кириллицы символы-заменители. Пишите и читайте с явным КодировкаТекста.UTF8.
  • 🔄 Запрос не проверили после обновления. Регистр переименовали в новом релизе, сохранённый запрос молчит до первого запуска. Держите короткий список критичных запросов и прогоняйте его после каждого обновления на копии базы.
Можно ли сохранить результат запроса, а не только текст?
Да. Выгрузите результат в таблицу значений, выведите в табличный документ и сохраните его в формате Excel или PDF. Текст запроса при этом лучше сохранить отдельно: таблица устареет, а запрос можно выполнить заново.
Сохраняются ли временные таблицы запроса?
Нет. Временные таблицы живут в менеджере временных таблиц, пока он существует, обычно в рамках одного вызова сервера. Сохранить можно только текст пакета, который их создаёт.
Какой длины текст запроса можно хранить в реквизите справочника?
Строковый реквизит с длиной 0 не ограничен по длине и подходит для любого запроса. У реквизита с заданной длиной, например 1024, длинный запрос обрежется при записи.
Как передать запрос коллеге, у которого другая база той же конфигурации?
Отправьте текст запроса файлом .txt, а параметры опишите словами или кодами элементов. Файл во внутреннем формате со ссылками в чужой базе может открыться с битыми ссылками.
Почему запрос, сохранённый из отладчика, выполняется иначе, чем в коде?
Скорее всего, не перенесли параметры или временные таблицы. В отладчике проверьте не только Запрос.Текст, но и Запрос.Параметры и менеджер временных таблиц, если он задан.