При работе с доработанными конфигурациями 1С (например, УТ 10.3 на обычных формах) часто возникает задача массового изменения данных в нетиповых (добавленных программистом) табличных частях. Стандартная обработка «Групповая обработка справочников и документов» часто «не видит» такие ТЧ, либо не позволяет гибко отобрать документы, где эта табличная часть еще не заполнена. Рассмотрим подробно, как решить эту задачу с помощью программного кода и правильных запросов.
Разберем ситуацию: нам необходимо найти документы РеализацияТоваровУслуг, у которых нетиповая табличная часть ИнформацияЭДО пуста, и заполнить её одной строкой. Основная ошибка начинающих разработчиков заключается в попытке выбрать данные напрямую из таблицы табличной части.
Проанализируем типичный неправильный запрос:
ВЫБРАТЬ
РеализацияТоваровУслугИнформацияЭДО.Ссылка КАК Ссылка
ИЗ
Документ.РеализацияТоваровУслуг.ИнформацияЭДО КАК РеализацияТоваровУслугИнформацияЭДО
ГДЕ
РеализацияТоваровУслугИнформацияЭДО.Ссылка.Проведен
Если мы обращаемся к таблице Документ.РеализацияТоваровУслуг.ИнформацияЭДО, система вернет только те документы, в которых есть хотя бы одна строка в этой ТЧ. Документы с пустой табличной частью в результат такого запроса просто не попадут. Чтобы найти именно пустые ТЧ, нам нужно использовать ЛЕВОЕ СОЕДИНЕНИЕ основной таблицы документов с таблицей их ТЧ.
Рассмотрим правильный алгоритм построения запроса. Мы берем все документы, подходящие под наши критерии (дата, склад, проведение), и «приклеиваем» к ним строки их табличной части. Если строк в ТЧ нет, в соответствующих полях запроса мы получим NULL.
Пример запроса для поиска документов с пустой ТЧ:
ВЫБРАТЬ
Реализация.Ссылка КАК Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.ИнформацияЭДО КАК ТЧ_ЭДО
ПО Реализация.Ссылка = ТЧ_ЭДО.Ссылка
ГДЕ
Реализация.Дата МЕЖДУ &ДатаНачала И &ДатаКонца
И Реализация.Проведен = ИСТИНА
И ТЧ_ЭДО.НомерСтроки ЕСТЬ NULL
В данном примере условие ТЧ_ЭДО.НомерСтроки ЕСТЬ NULL позволяет нам отобрать именно те документы, в которых табличная часть ИнформацияЭДО абсолютно пуста.
После того как мы получили список нужных ссылок на документы, нам необходимо перебрать их в цикле, получить объект каждого документа, добавить строку в табличную часть и записать изменения. Выясним, как это реализовать максимально эффективно.
Разберем по шагам код обработки результата запроса:
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Получаем объект документа для редактирования
ОбъектДок = Выборка.Ссылка.ПолучитьОбъект();
// Добавляем новую строку в нетиповую ТЧ
НоваяСтрока = ОбъектДок.ИнформацияЭДО.Добавить();
НоваяСтрока.Реквизит1 = "Значение 1";
НоваяСтрока.Реквизит2 = "Значение 2";
// Записываем объект.
// Если нужно просто сохранить данные без перепроведения,
// используем РежимЗаписиДокумента.Запись
Попытка
ОбъектДок.Записать(РежимЗаписиДокумента.Запись);
Исключение
Сообщить("Не удалось записать документ: " + Выборка.Ссылка + " Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Важный момент: если вы меняете данные, которые не должны влиять на бухгалтерские или управленческие итоги (движения по регистрам), всегда используйте РежимЗаписиДокумента.Запись. Это сэкономит время и ресурсы сервера, так как документ не будет перепроводиться.
Программисты часто сталкиваются с тем, что конфигуратор 1С не выдает подсказки после точки при работе с переменными типа ДокументОбъект, полученными через Выборка.Ссылка.ПолучитьОбъект(). Это происходит потому, что платформа не может заранее определить точный тип объекта в динамическом коде.
Чтобы заставить систему «понимать» тип переменной и выводить список реквизитов (включая вашу нетиповую ТЧ), можно использовать прием «Ложного условия»:
Если Ложь Тогда
// Эта строка никогда не выполнится, но конфигуратор поймет тип переменной
ОбъектДок = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
КонецЕсли;
// Теперь при наборе "ОбъектДок." будут выпадать подсказки
ОбъектДок = Выборка.Ссылка.ПолучитьОбъект();
Этот метод значительно ускоряет разработку и помогает избежать опечаток в названиях реквизитов нетиповых табличных частей.
Если вы не хотите писать код «с нуля», можно воспользоваться инструментом «Универсальный подбор и обработка объектов» (часто доступна на дисках ИТС или в составе подсистемы инструментов разработчика). В отличие от стандартной групповой обработки, она имеет режим «Произвольный алгоритм».
Объект.Строка = Объект.ИнформацияЭДО.Добавить(); Строка.Реквизит1 = "Данные";Использование этого метода безопасно, так как позволяет протестировать алгоритм на одном документе перед массовым запуском.
При массовом изменении 200 и более документов рекомендуется учитывать следующие правила:
ОбъектДок.ОбменДанными.Загрузка = Истина;. Это отключит проверки в процедурах ПередЗаписью и ПриЗаписи, что ускорит процесс и поможет избежать ошибок прав доступа или бизнес-логики.Мы проанализировали основные сложности при работе с нетиповыми табличными частями. Сочетание правильного LEFT JOIN в запросе для поиска пустых строк и корректного обращения к Объекту документа позволяет быстро и надежно решать задачи группового заполнения данных в любой конфигурации на платформе 1С:Предприятие 8.