При разработке и адаптации типовых конфигураций 1С специалисты часто сталкиваются со сложными архитектурными решениями, заложенными разработчиками фирмы "1С". Одной из таких "загадок", способной поставить в тупик даже опытного программиста, является интерфейс документа "Заказ покупателя" в конфигурации "1С:Управление нашей фирмой" (УНФ). Пользователь в режиме предприятия видит красивую и понятную таблицу "Товары, услуги", но при попытке найти её в конфигураторе на управляемой форме разработчик обнаруживает совершенно другие элементы или не находит нужную таблицу вовсе.
В этой статье мы подробно разберем, как устроена внутренняя структура документа ЗаказПокупателя в 1С:УНФ, почему одна физическая табличная часть может превращаться в несколько разных экранных таблиц и как правильно добавить новый реквизит в этот документ и вывести его на форму.
Прежде чем переходить к редактированию конфигурации, давайте проанализируем архитектурную концепцию, заложенную в УНФ. Разработчики системы объединили два абсолютно разных с точки зрения бизнес-процессов документа в один объект метаданных:
Физически в конфигураторе существует только один объект — Документ.ЗаказПокупателя. Однако для реализации столь разного поведения системы разработчики создали две независимые управляемые формы:
ФормаДокумента — стандартная форма для обычного "Заказа покупателя".ФормаЗаказНаряда — специализированная форма для оформления "Заказ-наряда".Именно здесь и крылась главная причина затруднения автора темы на форуме. Открыв в конфигураторе форму заказ-наряда (ФормаЗаказНаряда), он пытался найти на ней привычную единую таблицу "Товары, услуги", но видел раздельные таблицы для материалов, работ и товаров. Для решения задачи необходимо было работать со стандартной формой — ФормаДокумента.
Давайте выясним, как хранятся данные этих документов на уровне базы данных. Если мы откроем ветку метаданных Документ.ЗаказПокупателя и развернем список его табличных частей, мы не найдем там ТЧ с именем "Товары", "Услуги" или "Работы". Вся информация о продаваемых позициях, оказываемых услугах и списываемых материалах хранится в одной физической табличной части — Запасы.
При этом визуальное представление этой табличной части на формах кардинально отличается:
ФормаДокумента): Табличная часть выводится классическим единым блоком. Элемент формы (таблица) связан с путем к данным Объект.Запасы. На уровне интерфейса (в свойствах элемента формы) заголовок этой таблицы изменен для пользователя на более понятный — "Товары, услуги".ФормаЗаказНаряда): Разработчики применили механизм динамического разделения одной физической таблицы на несколько экранных элементов. На форме созданы отдельные визуальные таблицы (например, "Работы", "Товары", "Материалы"), каждая из которых отображает строки из одной и той же ТЧ Запасы, но фильтрует их программно по типу номенклатуры или по значению специальных служебных реквизитов строки.Рассмотрим подробнее и разберем по шагам процесс добавления нового справочного реквизита (например, текстового поля "Данные для справки" или дополнительного комментария к строке) в табличную часть "Товары, услуги" документа "Заказ покупателя".
Первым делом нам необходимо внести изменения в физическую структуру базы данных. Выполним следующие действия:
Документы.ЗаказПокупателя и развернем его структуру.Табличные части -> Запасы -> Реквизиты.ДанныеДляСправки с типом значения Строка (длина 150 символов, допустимая длина — переменная).Теперь добавим созданное поле на форму стандартного заказа покупателя, чтобы пользователи могли его заполнять:
ЗаказПокупателя перейдем в раздел Формы и откроем ФормаДокумента.Объект -> Запасы. Внутри этой ветки найдем наш новый реквизит ДанныеДляСправки.Запасы (или Товары, в зависимости от версии УНФ). Проверить, что это именно та таблица, можно по свойству ПутьКДанным — оно должно иметь значение Объект.Запасы.ДанныеДляСправки из списка реквизитов в нужную позицию внутри таблицы элементов формы. На форме автоматически создастся новое поле ввода.Если бизнес-процессы вашей компании предполагают, что справочная информация должна отображаться и при оформлении заказ-нарядов, необходимо проделать аналогичную операцию для второй формы:
ФормаЗаказНаряда в конфигураторе.Запасы распределены по нескольким таблицам интерфейса, нам нужно решить, в каких именно разделах должен отображаться новый реквизит. Например, если он нужен только для продаваемых сопутствующих товаров, найдем таблицу элементов с именем ЗапасыТовары.ДанныеДляСправки из ветки Объект.Запасы в выбранную таблицу на форме.ЗапасыРаботы (вкладка "Работы") или ЗапасыМатериалы (вкладка "Материалы").Важный нюанс: Если вы добавите реквизит в структуру ТЧ Запасы в метаданных, но выведете его на форму только в ФормаДокумента, то при открытии документа через интерфейс заказ-наряда данные в базе данных по-прежнему будут сохраняться, но пользователь их просто не увидит на экране.
Посмотрим на пример того, как мы можем программно взаимодействовать с новым реквизитом в кодовой базе конфигурации. Например, нам может потребоваться автоматически заполнять данное поле при изменении номенклатуры или при проведении документа.
Рассмотрим пример обработчика события ПриИзменении для номенклатуры в строке табличной части, где мы будем автоматически заполнять наше новое поле дефолтным значением:
&НаКлиенте
Процедура ЗапасыНоменклатураПриИзменении(Элемент)
// Получаем текущую строку табличной части
СтрокаТаблицы = Элементы.Запасы.ТекущиеДанные;
Если СтрокаТаблицы <> Неопределено Тогда
// Заполняем дефолтное значение для справки на основании выбранной номенклатуры
СтрокаТаблицы.ДанныеДляСправки = "Базовое описание: " + СтрокаТаблицы.Номенклатура;
КонецЕсли;
КонецПроцедуры
Если же нам требуется обойти все строки документа на стороне сервера перед записью или проведением и заполнить служебные данные, мы можем написать следующий код в модуле объекта документа:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверим, что документ не копируется, а записывается осознанно
Для Каждого СтрокаЗапасов Из Запасы Цикл
// Если поле "ДанныеДляСправки" пустое, заполним его автоматически
Если ПустаяСтрока(СтрокаЗапасов.ДанныеДляСправки) Тогда
ТипНоменклатуры = СтрокаЗапасов.Номенклатура.ТипНоменклатуры;
Если ТипНоменклатуры = Справочники.НаправленияДеятельности.ПустаяСсылка() Тогда
// Обработка исключения или заполнение по умолчанию
СтрокаЗапасов.ДанныеДляСправки = "Без категории";
Иначе
СтрокаЗапасов.ДанныеДляСправки = "Тип позиции: " + СокрЛП(ТипНоменклатуры);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Выясним еще одну важную деталь, которая часто вводит в заблуждение начинающих специалистов. В пользовательском режиме 1С:УНФ видимость документов "Заказ-наряд" напрямую зависит от настроек программы. За это отвечает функциональная опция "Выполнение работ и оказание услуг" (её можно включить или выключить по пути: Настройки -> Еще больше возможностей -> Работы).
Если эта опция выключена в базе данных клиента:
Поэтому всегда проверяйте, какую именно форму использует система в данный момент для конкретного вида операции документа.
Мы проанализировали внутреннее устройство документа ЗаказПокупателя в 1С:УНФ и выяснили, почему визуальное отображение табличных частей на управляемых формах может существенно отличаться от структуры метаданных в конфигураторе. При работе со сложными типовыми формами всегда придерживайтесь правила: проверяйте свойство "Путь к данным" элемента формы. Это гарантирует, что вы быстро найдете истинный источник данных (в данном случае — ТЧ Запасы) и не потратите несколько часов драгоценного времени на поиск несуществующих таблиц.