Разработка и Конфигурация · 11 мин
Как добавить строку в запросе 1С
Как добавить строку в запросе 1С: ОБЪЕДИНИТЬ ВСЕ, добавление строк в таблицу значений и табличную часть документа. Примеры кода, ошибки и проверка результата.
Фраза «добавить строку в запросе 1С» на практике означает три разные задачи. Первая — дополнить результат запроса дополнительными строками через конструкцию ОБЪЕДИНИТЬ ВСЕ. Вторая — программно добавить строку в таблицу значений, полученную из запроса. Третья — добавить строку в табличную часть документа или справочника кодом. Каждая задача решается своим инструментом, и путать их нельзя: синтаксис запроса работает на уровне СУБД, а методы Добавить() — на уровне встроенного языка платформы.
Ниже разобраны все три сценария с примерами кода, условиями выбора и типичными ошибками. Материал ориентирован на платформу 1С:Предприятие 8.3, но подходы актуальны и для более ранних версий управляемых форм.
Определите, где именно нужно добавить строку
Прежде чем писать код, ответьте на вопрос: строка должна появиться в результате запроса, в таблице значений в памяти или в табличной части объекта базы данных? От этого зависит инструмент. Запрос в 1С — это только чтение данных: он не может вставить строку в таблицу базы, как INSERT в классическом SQL. Поэтому «добавить строку запросом» в буквальном смысле невозможно — можно лишь скомпоновать строки в выборке.
Если цель — изменить данные в базе (например, добавить товар в документ), работа ведётся не через запрос, а через объектную модель: получение объекта, добавление строки в табличную часть, запись. Если цель — вывести в отчёт дополнительную строку, которой нет в базе (итог, пустая строка, строка-заглушка), используется ОБЪЕДИНИТЬ ВСЕ или добавление строки в таблицу значений после выполнения запроса.
Как выбрать действие
Добавление строки в тексте запроса через ОБЪЕДИНИТЬ ВСЕ
Конструкция ОБЪЕДИНИТЬ ВСЕ склеивает строки нескольких выборок в одну. Это основной способ «добавить строку» непосредственно в запросе. Вторая часть объединения может выбирать данные не из таблицы, а из литералов — тогда в результате появится строка с заданными значениями.
ВЫБРАТЬ
Товары.Номенклатура КАК Номенклатура,
Товары.Количество КАК Количество
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
Товары.Ссылка = &Ссылка
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка),
0
Важное правило: количество, порядок и типы полей во всех частях объединения должны совпадать. Если в первой выборке поле имеет тип «СправочникСсылка.Номенклатура», то и во второй части нужно передать значение того же типа — например, через ЗНАЧЕНИЕ() с пустой ссылкой. Несовпадение типов — самая частая причина ошибки «Несовместимые типы в объединении».
Используйте именно ОБЪЕДИНИТЬ ВСЕ, а не ОБЪЕДИНИТЬ, если строки могут совпадать: вариант без ВСЕ убирает дубликаты и выполняется медленнее. ОБЪЕДИНИТЬ без ВСЕ оправдан только когда нужно гарантированно исключить повторяющиеся строки.
Добавление строки в таблицу значений после выполнения запроса
Когда запрос уже выполнен, результат выгружается в таблицу значений методом Выгрузить(). Дальше строки добавляются штатным методом Добавить(), который возвращает ссылку на новую строку — её поля заполняются через точку.
РезультатЗапроса = Запрос.Выполнить();
ТаблицаРезультата = РезультатЗапроса.Выгрузить();
НоваяСтрока = ТаблицаРезультата.Добавить();
НоваяСтрока.Номенклатура = Справочники.Номенклатура.ПустаяСсылка();
НоваяСтрока.Количество = 0;
Обращайте внимание на типы колонок. Таблица значений, полученная из запроса, наследует типы полей выборки. Если колонка «Количество» имеет тип Число с длиной 15 и точностью 3, попытка записать туда строку вызовет ошибку преобразования. Перед добавлением проверьте состав колонок через ТаблицаРезультата.Колонки, особенно если таблица формируется в разных ветках алгоритма.
Этот способ удобен для промежуточных вычислений: добавления итоговых строк, строк-разделителей, служебных записей перед выводом в табличный документ или передачей в СКД. Таблица значений живёт только в памяти сеанса — при завершении процедуры данные теряются.
НоваяСтрока = ТаблицаРезультата.Добавить();
НоваяСтрока.Номенклатура = ТекущаяНоменклатура;
НоваяСтрока.Количество = 1;Добавление строки в табличную часть документа программно
Если под «добавить строку» понимается добавление позиции в документ, запрос здесь не нужен вовсе. Работа идёт через объектную модель: получить объект документа, добавить строку в табличную часть, заполнить поля, записать.
ДокументОбъект = ДокументСсылка.ПолучитьОбъект();
НоваяСтрока = ДокументОбъект.Товары.Добавить();
НоваяСтрока.Номенклатура = ВыбраннаяНоменклатура;
НоваяСтрока.Количество = 5;
НоваяСтрока.Цена = 1200;
НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Ключевые моменты: ПолучитьОбъект() загружает документ целиком, поэтому для массовой обработки такой код выполняется медленно — на больших объёмах групповое изменение лучше делать в транзакции с контролем ошибок. Метод Записать() с проведением пересчитает движения документа; если проведение не нужно, используйте РежимЗаписиДокумента.Запись.
В управляемых формах добавление строки «вручную кодом формы» делается иначе: через Элементы.Товары.ДобавитьСтроку() для интерактивного добавления или через Объект.Товары.Добавить() в серверной процедуре. Смешивать клиентский и серверный контекст нельзя — ПолучитьОбъект() недоступен на клиенте в управляемом приложении.
Добавление строки в консоли запросов и конструкторе
Частый бытовой сценарий: разработчик работает в консоли запросов и хочет добавить строку в параметр-список или во временную таблицу. Для параметра типа «Список значений» в консоли запросов строка добавляется кнопкой добавления в редакторе параметра — это интерфейсное действие, а не код. В самом тексте запроса список значений формируется через конструкцию В (&Список), а наполняется список уже в коде методом Добавить().
Если нужно собрать временную таблицу из фиксированных строк прямо в запросе, используется приём с ОБЪЕДИНИТЬ ВСЕ и помещением результата во временную таблицу:
ВЫБРАТЬ
1 КАК НомерСтроки,
"Первая строка" КАК Описание
ПОМЕСТИТЬ ВТ_Данные
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
2,
"Вторая строка"
Такой приём удобен для тестирования запросов без реальных данных и для передачи в запрос небольших фиксированных наборов. При большом количестве строк эффективнее передать таблицу значений через параметр и поместить её во временную таблицу конструкцией ВЫБРАТЬ ... ИЗ &Таблица.
- 1Определите, где должна появиться строка: в выборке, таблице значений или табличной части объекта
- 2Для выборки добавьте ОБЪЕДИНИТЬ ВСЕ с совпадающими по типам полями
- 3Для таблицы значений вызовите Добавить() и заполните поля новой строки
- 4Для документа получите объект, добавьте строку в табличную часть и запишите
- 5Проверьте результат: количество строк, типы полей, движения документа
Проверка результата и типичные ошибки
После добавления строки убедитесь, что она действительно появилась там, где ожидалось. Для запроса — проверьте количество строк в результате (РезультатЗапроса.Пустой() и Выгрузить().Количество()). Для документа — откройте его в пользовательском режиме и проверьте табличную часть и движения по регистрам.
Как проверить результат
Увеличилось ровно на число добавленных через ОБЪЕДИНИТЬ ВСЕ строк
Строка отсутствует — проверьте условия ГДЕ и типы полей объединения
Значения соответствуют типам колонок, ошибок преобразования нет
Ошибка присваивания — тип значения не совпадает с типом колонки
Строка видна в табличной части, движения пересчитаны
Документ не записался — смотрите сообщения об ошибках проведения
Ограничения и альтернативные подходы
Запрос в 1С принципиально не поддерживает операции вставки, обновления и удаления данных — это отличие от классического SQL, которое часто сбивает новичков. Все изменения базы выполняются только через объектную модель или наборы записей регистров. Если нужно массово добавить строки в регистр сведений, используйте НаборЗаписей с методом Добавить() и последующим Записать().
Для пакетного добавления большого числа строк в таблицу значений перед выводом в отчёт рассмотрите альтернативу: сформировать все данные одним запросом с объединениями, а не добавлять строки по одной в цикле. Один запрос с ОБЪЕДИНИТЬ ВСЕ обычно работает быстрее, чем многократные обращения к базе внутри цикла.
Что важно запомнить
Строка добавляется тремя способами: ОБЪЕДИНИТЬ ВСЕ в тексте запроса — для выборки, Добавить() — для таблицы значений и табличной части объекта. Запрос не изменяет данные базы. Контролируйте типы полей и не забывайте записывать объект после изменения.
Частые вопросы
Можно ли добавить строку в таблицу базы данных запросом, как INSERT в SQL?
Нет. Язык запросов 1С поддерживает только чтение данных. Для добавления записей используется объектная модель: документы и справочники — через ПолучитьОбъект() и Записать(), регистры — через наборы записей или менеджеры записей.
Чем ОБЪЕДИНИТЬ отличается от ОБЪЕДИНИТЬ ВСЕ?
ОБЪЕДИНИТЬ убирает дублирующиеся строки и требует дополнительной обработки на сервере. ОБЪЕДИНИТЬ ВСЕ просто склеивает выборки, работает быстрее и сохраняет все строки, включая одинаковые. В большинстве случаев правильный выбор — ОБЪЕДИНИТЬ ВСЕ.
Почему возникает ошибка «Несовместимые типы в объединении»?
Поля в частях объединения должны совпадать по количеству, порядку и типам. Если в одной части поле — ссылка на справочник, а в другой — строка, запрос не выполнится. Приведите литералы к нужному типу через ЗНАЧЕНИЕ() или ВЫРАЗИТЬ.
Как добавить строку в табличную часть на управляемой форме?
В клиентской процедуре — через Элементы.ИмяТаблицы.ДобавитьСтроку() для интерактивного ввода. В серверной процедуре — через Объект.ИмяТабличнойЧасти.Добавить() с заполнением полей. Метод ПолучитьОбъект() на клиенте управляемой формы недоступен.
Добавленная в документ строка пропала после закрытия — в чём причина?
Объект не был записан. Метод Добавить() изменяет данные только в памяти; чтобы изменения сохранились в базе, нужно вызвать Записать() с подходящим режимом записи. Также проверьте, не откатывается ли транзакция из-за ошибки проведения.
Как передать в запрос таблицу с заранее заданными строками?
Сформируйте таблицу значений в коде, передайте её как параметр запроса и поместите во временную таблицу: ВЫБРАТЬ ... ПОМЕСТИТЬ ВТ ИЗ &Таблица. Дальше временная таблица используется в соединениях как обычный источник данных.