Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
28 мар 2024, 20:15

Табличный часть документа

Автор wellknown, 21 янв 2016, 13:13

0 Пользователей и 1 гость просматривают эту тему.

wellknown

Как делат так чтоби при откритие документа в табличной части былы подобраны выбранные объекты?

cska-fanat-kz

Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

wellknown

Цитата: cska-fanat-kz от 21 янв 2016, 13:19
"выбранные" где и кем?
Скажем надо чтоби в документе были добавлены Номенклатура шоколад со всеми характеристиками (черный, белый, ...) при открытие. Или  чтоби в табличной часте было номенклатуры с категорий Продукт и все их характеристики.

cast

http://infostart.ru/public/201643/

Программисту на заметку: автозаполнение реквизитов документов и справочников

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

Часто бывает необходимым, чтобы при создании документа, элемента справочника автоматически заполнялись заданным значением определенные его реквизиты. Можно, конечно, прописать заполнение реквизитов в коде программы, но заменяемое значение со временем может понадобиться изменить либо вообще задать его в зависимости от каких то условий, и при этом постоянно дорабатывать программу считаю не очень правильным.

Ниже предлагается вариант реализации механизма автозаполнения реквизитов документов по заданным условиям.

1. Создаем подписку на событие "ПередЗаписьюДокумента_АвтозаполнениеРеквизитов". Источник - "ДокументОбъект", событие - "Перед записью", обработчик "ОбщегоНазначения.ПередЗаписьюДокумента_АвтозаполнениеРеквизитов"

2. Текст процедуры общего модуля "ПередЗаписьюДокумента_АвтозаполнениеРеквизитов" и вспомогательных процедур:


Процедура ПередЗаписьюДокумента_АвтозаполнениеРеквизитов(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт

ИмяДокумента = Источник.Метаданные().Имя;
ТипДокумента = Источник.Метаданные().Синоним;
Если Источник.Метаданные().Реквизиты.Найти("ВидОперации") <> Неопределено Тогда
ВидОперации = Строка(Источник.ВидОперации);
Иначе
ВидОперации = "";
КонецЕсли;

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

Запрос.Текст = "ВЫБРАТЬ
| ПараметрыАвтозаполненияДокументов.Ссылка
|ИЗ
| Справочник.ПараметрыАвтозаполненияДокументов КАК ПараметрыАвтозаполненияДокументов
|ГДЕ
| ПараметрыАвтозаполненияДокументов.ТипДокумента = &ТипДокумента
| И ПараметрыАвтозаполненияДокументов.ВидОперации = &ВидОперации
| И НЕ ПараметрыАвтозаполненияДокументов.Отключено
| И НЕ ПараметрыАвтозаполненияДокументов.ПометкаУдаления";
Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Количество() = 0 Тогда
Возврат;
КонецЕсли;

// окончательная проверка наличия настроек автозамены для данного типа документа и вида операции
ПараметрыАвтозаполнения = Неопределено;

Пока Выборка.Следующий() Цикл
УсловияВыполнены = Истина;
УсловияАвтозаполнения = Выборка.Ссылка.Условия;

Для каждого стр из УсловияАвтозаполнения Цикл
Если Источник[ПолучитьИмяРеквизитаПоСинониму(,стр.Реквизит,ИмяДокумента)] <> стр.Значение Тогда
УсловияВыполнены = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;

Если УсловияВыполнены Тогда
ПараметрыАвтозаполнения = Выборка.Ссылка.Настройки;
Прервать;
КонецЕсли;
КонецЦикла;

Если Не ЗначениеЗаполнено(ПараметрыАвтозаполнения) Тогда
Возврат;
КонецЕсли;

ПредставлениеДокумента = ТипДокумента+" № "+Источник.Номер+" от "+Формат(Источник.Дата,"ДФ=dd.MM.yyyy");

Для каждого стр из ПараметрыАвтозаполнения Цикл
Если Не ЗначениеЗаполнено(стр.ТабличнаяЧасть) Тогда
// заполняем значения реквизита в шапке документа
ИмяРеквизита = ПолучитьИмяРеквизитаПоСинониму(,стр.Реквизит,ИмяДокумента);
Если стр.Принудительно или Не ЗначениеЗаполнено(Источник[ИмяРеквизита]) Тогда
Сообщить(" "+ПредставлениеДокумента+": выполнено "+?(ЗначениеЗаполнено(Источник[ИмяРеквизита]),"изменение","автозаполнение")+" реквизита """+стр.Реквизит+"""");
Источник[ИмяРеквизита] = стр.Значение;
КонецЕсли;
Иначе
// заполняем значения реквизита в табличной части
ИмяТабличнойЧасти = ПолучитьИмяОбъектаПоСинониму("ТабличнаяЧасть",стр.ТабличнаяЧасть,ИмяДокумента);
ИмяРеквизита = ПолучитьИмяРеквизитаПоСинониму(ИмяТабличнойЧасти,стр.Реквизит,ИмяДокумента);
Для каждого стрТЧ из Источник[ИмяТабличнойЧасти] Цикл
Если стр.Принудительно или Не ЗначениеЗаполнено(стрТЧ[ИмяРеквизита]) Тогда
Сообщить(" "+ПредставлениеДокумента+": выполнено "+?(ЗначениеЗаполнено(стрТЧ[ИмяРеквизита]),"изменение","автозаполнение")+" реквизита """+стр.Реквизит+""" табличной части """+стр.ТабличнаяЧасть+"""");
стрТЧ[ИмяРеквизита] = стр.Значение;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;

КонецПроцедуры



Функция ПолучитьИмяРеквизитаПоСинониму(ИмяТабличнойЧасти="",СинонимОбъекта,ИмяДокумента) Экспорт

Если Не ЗначениеЗаполнено(ИмяТабличнойЧасти) Тогда
// по синониму реквизита шапки документа находим его имя
Для каждого Реквизит из Метаданные.Документы[ИмяДокумента].Реквизиты Цикл
Если Реквизит.Синоним = СинонимОбъекта Тогда
Возврат Реквизит.Имя;
КонецЕсли;
КонецЦикла;
Иначе
// по синониму реквизита табличной части документа находим его имя
Для каждого Реквизит из Метаданные.Документы[ИмяДокумента].ТабличныеЧасти[ИмяТабличнойЧасти].Реквизиты Цикл
Если Реквизит.Синоним = СинонимОбъекта Тогда
Возврат Реквизит.Имя;
КонецЕсли;
КонецЦикла;
КонецЕсли;

КонецФункции

3. Создаем справочник "Параметры автозаполнения документов"

Типы значений реквизитов:

ТипДокумента - Строка(100)

ВидОперации - Строка(100)

Отключено - Булево

Реквизит - Строка(100)

Значение - ЛюбаяСсылка, Булево, Строка, Дата, Число

ТабличнаяЧасть - Строка(100)

Реквизит - Строка(100)

Значение - ЛюбаяСсылка, Булево, Строка, Дата, Число

Принудительно - Булево

Форма списка справочника:

Форма элемента справочника:

Модуль формы элемента справочника:


Перем ИмяДокумента;

Процедура ПриОткрытии()

ИмяДокумента = _ОбщегоНазначения.ПолучитьИмяОбъектаПоСинониму("Документ",ТипДокумента);
ЗаполнитьСписокТиповДокументов();

КонецПроцедуры

Процедура ТипДокументаПриИзменении(Элемент)

ВидОперации = "";
Условия.Очистить();
Настройки.Очистить();
ИмяДокумента = _ОбщегоНазначения.ПолучитьИмяОбъектаПоСинониму("Документ",ТипДокумента);

ЗаполнитьСписокВидовОперацийДокумента();

КонецПроцедуры

Процедура ВидОперацииНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)

Если ЭлементыФормы.ВидОперации.СписокВыбора.Количество() = 0 Тогда
ЗаполнитьСписокВидовОперацийДокумента();
КонецЕсли;

КонецПроцедуры


Процедура УсловияПередНачаломДобавления(Элемент, Отказ, Копирование)

Если Не ЗначениеЗаполнено(ИмяДокумента) Тогда
Отказ = Истина;
КонецЕсли;

КонецПроцедуры

Процедура НастройкиПередНачаломДобавления(Элемент, Отказ, Копирование)

Если Не ЗначениеЗаполнено(ИмяДокумента) Тогда
Отказ = Истина;
КонецЕсли;

КонецПроцедуры


Процедура НастройкиТабличнаяЧастьНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)

ЗаполнитьСписокТабличныхЧастейДокумента();

КонецПроцедуры



Процедура НастройкиТабличнаяЧастьПриИзменении(Элемент)

стр = ЭлементыФормы.Настройки.ТекущаяСтрока;
стр.Реквизит = "";
стр.Значение = "";

КонецПроцедуры


Процедура УсловияРеквизитНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)

ЗаполнитьСписокРеквизитовДокумента_Условия();

КонецПроцедуры



Процедура НастройкиРеквизитНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)

стр = ЭлементыФормы.Настройки.ТекущаяСтрока;
ЗаполнитьСписокРеквизитовДокумента_Настройки(_ОбщегоНазначения.ПолучитьИмяОбъектаПоСинониму("ТабличнаяЧасть",стр.ТабличнаяЧасть,ИмяДокумента));

КонецПроцедуры


Процедура УсловияРеквизитПриИзменении(Элемент)

стр = ЭлементыФормы.Условия.ТекущаяСтрока;
стр.Значение = "";

КонецПроцедуры



Процедура НастройкиРеквизитПриИзменении(Элемент)

стр = ЭлементыФормы.Настройки.ТекущаяСтрока;
стр.Значение = "";

КонецПроцедуры


Процедура УсловияПриАктивизацииЯчейки(Элемент)

Если Элемент.ТекущаяКолонка.Имя = "Значение" Тогда
стр = ЭлементыФормы.Условия.ТекущаяСтрока;
Если стр = Неопределено Тогда
Возврат;
КонецЕсли;

Если ЗначениеЗаполнено(стр.Реквизит) Тогда
ЗадатьТипЗначенияРеквизита_Условия(стр);
КонецЕсли;
КонецЕсли;

КонецПроцедуры



Процедура НастройкиПриАктивизацииЯчейки(Элемент)

Если Элемент.ТекущаяКолонка.Имя = "Значение" Тогда
стр = ЭлементыФормы.Настройки.ТекущаяСтрока;
Если стр = Неопределено Тогда
Возврат;
КонецЕсли;

Если ЗначениеЗаполнено(стр.Реквизит) Тогда
ЗадатьТипЗначенияРеквизита_Настройки(стр);
КонецЕсли;
КонецЕсли;

КонецПроцедуры


Процедура ПередЗаписью(Отказ)

// удаляем пустые строки табличной части УСЛОВИЯ
ном = Условия.Количество()-1;
Пока ном >= 0 Цикл
Если Не ЗначениеЗаполнено(Условия[ном].Реквизит) Тогда
Условия.Удалить(ном);
КонецЕсли;
ном = ном - 1;
КонецЦикла;

// сортируем строки табличной части УСЛОВИЯ
Условия.Сортировать("Реквизит");

// проверяем наличие дублей строк табличной части УСЛОВИЯ
табУсловия = Условия.Выгрузить();
табУсловия.Колонки.Добавить("Счетчик");
табУсловия.ЗаполнитьЗначения(1,"Счетчик");

табУсловия.Свернуть("Реквизит","Счетчик");

Для каждого стр из табУсловия Цикл
Если стр.Счетчик > 1 Тогда
Сообщить("Обнаружены дубли строк в табличной части ""Условия отбора"" !");
Отказ = Истина;
КонецЕсли;
КонецЦикла;

// удаляем пустые строки табличной части НАСТРОЙКИ
ном = Настройки.Количество()-1;
Пока ном >= 0 Цикл
Если Не ЗначениеЗаполнено(Настройки[ном].Реквизит) Тогда
Настройки.Удалить(ном);
КонецЕсли;
ном = ном - 1;
КонецЦикла;

// сортируем строки табличной части НАСТРОЙКИ
Настройки.Сортировать("ТабличнаяЧасть,Реквизит");

// проверяем наличие дублей строк табличной части НАСТРОЙКИ
табНастройки = Настройки.Выгрузить();
табНастройки.Колонки.Добавить("Счетчик");
табНастройки.ЗаполнитьЗначения(1,"Счетчик");

табНастройки.Свернуть("ТабличнаяЧасть,Реквизит","Счетчик");

Для каждого стр из табНастройки Цикл
Если стр.Счетчик > 1 Тогда
Сообщить("Обнаружены дубли строк в табличной части ""Настройки заполнения"" !");
Отказ = Истина;
КонецЕсли;
КонецЦикла;

Если Отказ Тогда
Возврат;
КонецЕсли;

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

Запрос.Текст = "ВЫБРАТЬ
| ПараметрыАвтозаполненияДокументов.Ссылка
|ИЗ
| Справочник.ПараметрыАвтозаполненияДокументов КАК ПараметрыАвтозаполненияДокументов
|ГДЕ
| ПараметрыАвтозаполненияДокументов.ТипДокумента = &ТипДокумента
| И ПараметрыАвтозаполненияДокументов.ВидОперации = &ВидОперации
| И ПараметрыАвтозаполненияДокументов.Ссылка <> &Ссылка";
Выборка = Запрос.Выполнить().Выбрать();

ЕстьСовпадения = Ложь;
Пока Выборка.Следующий() Цикл
УсловияОтбора = Выборка.Ссылка.Условия;

Если Условия.Количество() <> УсловияОтбора.Количество() Тогда
Продолжить;
Иначе
Если Условия.Количество() = 0 Тогда
ЕстьСовпадения = Истина;
КонецЕсли;
КонецЕсли;

Для ном = 0 по Условия.Количество()-1 Цикл
Если Условия[ном].Реквизит <> УсловияОтбора[ном].Реквизит или Условия[ном].Значение <> УсловияОтбора[ном].Значение Тогда
Прервать;
Иначе
ЕстьСовпадения = Истина;
КонецЕсли;
КонецЦикла;

Если ЕстьСовпадения Тогда
Сообщить("В справочнике ""Параметры автозаполнения документов"" уже есть настройки для данного типа документа и вида операции с аналогичными условиями отбора !");
Отказ = Истина;
Прервать;
КонецЕсли;
КонецЦикла;

КонецПроцедуры



Процедура ЗаполнитьСписокТиповДокументов()


СписокТиповДокументов = Новый СписокЗначений;

// заполним список доступных типов документов
Для каждого эл из Метаданные.Документы Цикл
СписокТиповДокументов.Добавить(эл.Синоним,эл.Синоним);
КонецЦикла;

ЭлементыФормы.ТипДокумента.СписокВыбора = СписокТиповДокументов;

КонецПроцедуры



Процедура ЗаполнитьСписокВидовОперацийДокумента()

СписокВидовОперацийДокумента = Новый СписокЗначений;

РеквизитВидОперации = Метаданные.Документы[ИмяДокумента].Реквизиты.Найти("ВидОперации");
Если РеквизитВидОперации <> Неопределено Тогда
Реквизит = РеквизитВидОперации.Тип.ПривестиЗначение();

// заполним список возможных видов операций документа
Для каждого эл из Реквизит.Метаданные().ЗначенияПеречисления Цикл
СписокВидовОперацийДокумента.Добавить(эл.Синоним,эл.Синоним);
КонецЦикла;
КонецЕсли;

ЭлементыФормы.ВидОперации.СписокВыбора = СписокВидовОперацийДокумента;

Если СписокВидовОперацийДокумента.Количество() > 0 Тогда
ЭлементыФормы.НадписьВидОперации.Доступность = Истина;
ЭлементыФормы.ВидОперации.Доступность = Истина;
Иначе
ВидОперации = "";
ЭлементыФормы.НадписьВидОперации.Доступность = Ложь;
ЭлементыФормы.ВидОперации.Доступность = Ложь;
КонецЕсли;

КонецПроцедуры


Процедура ЗаполнитьСписокТабличныхЧастейДокумента()

СписокТабличныхЧастейДокумента = Новый СписокЗначений;

Для каждого тч из Метаданные.Документы[ИмяДокумента].ТабличныеЧасти Цикл
СписокТабличныхЧастейДокумента.Добавить(тч.Синоним,тч.Синоним);
КонецЦикла;

ЭлементыФормы.Настройки.Колонки.ТабличнаяЧасть.ЭлементУправления.СписокВыбора = СписокТабличныхЧастейДокумента;

КонецПроцедуры


Процедура ЗаполнитьСписокРеквизитовДокумента_Условия()

РеквизитВидОперации = Метаданные.Документы[ИмяДокумента].Реквизиты.Найти("ВидОперации");
СписокРеквизитовДокумента = Новый СписокЗначений;

Для каждого эл из Метаданные.Документы[ИмяДокумента].Реквизиты Цикл
Если эл = РеквизитВидОперации Тогда
Продолжить;
КонецЕсли;
СписокРеквизитовДокумента.Добавить(эл.Синоним,эл.Синоним);
КонецЦикла;

ЭлементыФормы.Условия.Колонки.Реквизит.ЭлементУправления.СписокВыбора = СписокРеквизитовДокумента;

КонецПроцедуры



Процедура ЗаполнитьСписокРеквизитовДокумента_Настройки(ИмяТабличнойЧасти)

РеквизитВидОперации = Метаданные.Документы[ИмяДокумента].Реквизиты.Найти("ВидОперации");
СписокРеквизитовДокумента = Новый СписокЗначений;

Если Не ЗначениеЗаполнено(ИмяТабличнойЧасти) Тогда
Для каждого эл из Метаданные.Документы[ИмяДокумента].Реквизиты Цикл
Если эл = РеквизитВидОперации Тогда
Продолжить;
КонецЕсли;
СписокРеквизитовДокумента.Добавить(эл.Синоним,эл.Синоним);
КонецЦикла;
Иначе
Для каждого эл из Метаданные.Документы[ИмяДокумента].ТабличныеЧасти[ИмяТабличнойЧасти].Реквизиты Цикл
СписокРеквизитовДокумента.Добавить(эл.Синоним,эл.Синоним);
КонецЦикла;
КонецЕсли;

ЭлементыФормы.Настройки.Колонки.Реквизит.ЭлементУправления.СписокВыбора = СписокРеквизитовДокумента;

КонецПроцедуры


Процедура ЗадатьТипЗначенияРеквизита_Условия(стр)

ИмяРеквизита = _ОбщегоНазначения.ПолучитьИмяРеквизитаПоСинониму(,стр.Реквизит,ИмяДокумента);
ТипРеквизита = _ОбщегоНазначения.ПолучитьТипРеквизитаПоИмени(,ИмяРеквизита,ИмяДокумента);

Если ТипЗнч(стр.Значение) <> ТипЗнч(ТипРеквизита.ПривестиЗначение()) Тогда
стр.Значение = ТипРеквизита.ПривестиЗначение();
ЭлементыФормы.Условия.Колонки.Значение.ЭлементУправления.ОграничениеТипа = ТипРеквизита;
ЭлементыФормы.Условия.Колонки.Значение.ЭлементУправления.Значение = ТипРеквизита.ПривестиЗначение();
КонецЕсли;

КонецПроцедуры



Процедура ЗадатьТипЗначенияРеквизита_Настройки(стр)

ИмяТабличнойЧасти = _ОбщегоНазначения.ПолучитьИмяОбъектаПоСинониму("ТабличнаяЧасть",стр.ТабличнаяЧасть,ИмяДокумента);
ИмяРеквизита = _ОбщегоНазначения.ПолучитьИмяРеквизитаПоСинониму(ИмяТабличнойЧасти,стр.Реквизит,ИмяДокумента);
ТипРеквизита = _ОбщегоНазначения.ПолучитьТипРеквизитаПоИмени(ИмяТабличнойЧасти,ИмяРеквизита,ИмяДокумента);

Если ТипЗнч(стр.Значение) <> ТипЗнч(ТипРеквизита.ПривестиЗначение()) Тогда
стр.Значение = ТипРеквизита.ПривестиЗначение();
ЭлементыФормы.Настройки.Колонки.Значение.ЭлементУправления.ОграничениеТипа = ТипРеквизита;
ЭлементыФормы.Настройки.Колонки.Значение.ЭлементУправления.Значение = ТипРеквизита.ПривестиЗначение();
КонецЕсли;

КонецПроцедуры

Как это работает

При срабатывании события "ПередЗаписью" документа выполняется проверка, есть ли элементы справочника с подходящим типом документа и видом операции, если есть, выполняется проверка дополнительных условий, и затем указанные в справочнике реквизиты шапки либо табличной части документа заполняются заданным в справочнике значением.

Замечания

1. Для табличной части реквизит заполняется одновременно для всех строк

2. Предполагается, что синонимы реквизитов объектов метаданных - уникальны в пределах этого объекта

Посмотри

wellknown

Цитата: cast от 21 янв 2016, 14:14
http://infostart.ru/public/201643/ Посмотри
Я ещё недавно начал работать с конфигураторам. Я даже не знаю куда эти коды писать. Задача проста.
ПриОткрииеДокумента(Производство) Строка.Добавить()
Номенклатура = Номенклатура1
Как то так :D ?

Теги: 8.3 УНФ 

Похожие темы (5)

Рейтинг@Mail.ru

Поиск