Найти все реквизиты документа с ссылкой на объект.

1. XiPyPg 23.09.20 12:50 Сейчас в теме
Подскажите у меня есть документ в нем в табличной части есть столбец "документ".

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

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

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

&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
	Режим = РежимДиалогаВопрос.ДаНет;
	
	Ответ = Вопрос("Вы хотите изменить контрагента?", Режим, 0);
	Если Ответ =КодВозвратаДиалога.Да Тогда
		КонтрагентПриИзмененииНаСервере();
	Иначе
		Объект.Контрагент = ПолучитьСтарогоКонтрагента("Контрагент");
	КонецЕсли;
КонецПроцедуры
Показать


Интересует как - перебрать все реквизиты Стр.Документ , может кто-то чтото подскажет. Дальше будут идти изменения по аналогии с этим.
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Азбука Морзе 105 23.09.20 12:55 Сейчас в теме
реквизита можно получить из объекта Метаданные, например: Метаданные.Документы.АвансовыйОтчет.Реквизиты
3. XiPyPg 23.09.20 12:58 Сейчас в теме
(2)Мне надо значение каждого реквизита объекта сверить по типу и в случае чего его заменить
Контр = ПолучитьСтарогоКонтрагента("Контрагент");
Если Метаданные.Документы.АвансовыйОтчет.Реквизиты.Значение = Контр тогда Метаданные.Документы.АвансовыйОтчет.Реквизиты.Значение = Документ.Контрагент КонецЕсли;
4. XiPyPg 23.09.20 13:02 Сейчас в теме
(2)Только я еще и не знаю тип документа .
Получается что-то типо такого :

Для каждого стр из Документ.ДокументыЦепочки цикл
Док = Стр.Документ.ПолучитьОбъект();
//////////ВОТ тут перебрать все реквизиты Док надо
Если Док.Рекв = ПолучитьСтарогоКонтрагента("Контрагент")
 тогда Док.Рекв = Документ.Контрагент 
КонецЕсли;
///////////КонецПеребора
КонецЦикла;
5. FatPanzer 23.09.20 13:07 Сейчас в теме
Сразу не советую. Слишком скользкая дорожка...

По коду:
1. Колонка "Документ" в табличной части строго типизирована? Или там могут появляться документы абсолютно любого типа?
2. Старого контрагента вы можете получить по ссылке Объект.Ссылка.Контрагент, для этого не надо городить запросы.
(4) А тем более получать старого контрагента в цикле.
6. XiPyPg 23.09.20 13:08 Сейчас в теме
(5)цикл это понятно, этого кода нет , он получаться будет в начале процедуры) Колонка документ там составной тип данных 7-9 видов разных документов могут быть.
9. FatPanzer 23.09.20 13:16 Сейчас в теме
(6) Прекрасно, значит вы знаете типы документов, и знаете их реквизиты. Ставьте цикл на табличную часть и по условию выполняйте.

Для Каждого Строка ТЧ Из ТЧ Цикл
    ТипДокумента = ТипЗнч(СтрокаТЧ.Документ);
    Если (ТипДокумента = Тип("ДокументСсылка.Документ1") ИЛИ ТипДокумента = Тип("ДокументСсылка.Документ2")) 
        И СтрокаТЧ.Документ.Покупатель = Объект.Ссылка.Контрагент Тогда
        ДокОбъект = СтрокаТЧ.Документ.ПолучитьОбъект();
        ДокОбъект.Покупатель = Объект.Контрагент;
        ДокОбъект.Записать();
    ИначеЕсли ТипДокумента = Тип("ДокументСсылка.Документ3") И СтрокаТЧ.Документ.Поставщик = Объект.Ссылка.Контрагент Тогда
        ДокОбъект = СтрокаТЧ.Документ.ПолучитьОбъект();
        ДокОбъект.Поставщик = Объект.Контрагент;
        ДокОбъект.Записать();
    Иначе...
        ...
    КонецЕсли;
КонецЦикла;
Показать
12. XiPyPg 23.09.20 13:19 Сейчас в теме
(9) Можно чтото пропустить, могут добавиться новые реквизиты документа, могут добавиться новые документы и так далее. Поэтому и надо универсально по всему пробегаться.
15. FatPanzer 23.09.20 13:23 Сейчас в теме
(12) Это порочная практика. Да, могут добавиться новые реквизиты. Но вполне вероятно, что они и не должны будут изменяться по вашему алгоритму, и предназначены совсем для другого. А вы их ковровой бомбардировкой поменяете...
alex-l19041; +1 Ответить
7. XiPyPg 23.09.20 13:14 Сейчас в теме
Смысл в том что при изменение контрагента, должны меняться всякие грузоотправители и так далее если они были первоначально равны контрагенту. И если в ручную прописывать все то получается слишком много и условий и всякого другого муссора, а по факту при изменении контрагента(Пупкина), надо во всех документах связанных с текущим документом все реквизиты где (Пупкин) поменять аналогично с текущем документом.
8. alex-l19041 8 23.09.20 13:15 Сейчас в теме
(7)
во всех документах связанных с текущим документом
- запросом выбирайте все такие документы и меняйте в них
10. XiPyPg 23.09.20 13:17 Сейчас в теме
(8)эти все документы есть в табличной части

Для каждого стр из Документ.ДокументыЦепочки цикл
Док = Стр.Документ.ПолучитьОбъект();

Теперь в каждом из этих документов надо проверить все реквизиты и узнать в каких значение Пупкин ......в одном документе это может быть контрагент, в другом покупатель, в третьем, грузоотправитель, в четвертом поставщик , в пятом посредник ну и так далее, в каких-то документах Пупкин будет в 4 реквизитах документа.
13. FatPanzer 23.09.20 13:20 Сейчас в теме
(10) Не надо проверять ВСЕ реквизиты. Вы их и так знаете, если у вас поле составное, и необходимые типы документов в нем перечислено.
11. FatPanzer 23.09.20 13:19 Сейчас в теме
(8) Но запросом правильнее, согласен.
14. starjevschik 23.09.20 13:20 Сейчас в теме
Подобные алгоритмы сейчас во всех стандартных конфигурациях, в процедурах типа при изменении количества в табличной части или ставки НДС. Можно просто стянуть готовое. Там никаких секретов, перебор метаданных.
17. XiPyPg 23.09.20 13:35 Сейчас в теме
(14)А можно поподробней :-)
16. FatPanzer 23.09.20 13:28 Сейчас в теме
Ну и главное. В нормальном прикладном случае алгоритм скорее всего не сработает.
Нельзя просто так и взять и поменять контрагента в цепочке документов. Очень вероятно, что для начала придется ОТМЕНЯТЬ всю цепочку документов, а потом заново проводить их по хронологии.(Тот же заказ вы не сможете переоформить на другого контрагента, если он уже отгружен, и т.д.)
А там уже и связанные реквизиты (договоры), и закрытые периоды, и контроли по дебиторке, и прочие радости появятся...

Удачи вам на минном поле )))
18. starjevschik 23.09.20 13:38 Сейчас в теме
ну покопайся в какой-нибудь УТ или БП по слову Метаданные() например.
19. andy_zhav 197 23.09.20 17:07 Сейчас в теме
(1) Я бы для этих целей использовал бы критерии отбора. Перед изменением запоминаем контрагента, после изменения делаем запрос по критерию отбора и пробегаем все объекты и меняем на нового контрагента
20. XiPyPg 25.09.20 11:55 Сейчас в теме
получилось примерно так:
СтКонт = ПолучитьСтарогоКонтрагента("Контрагент");	
	Для каждого стр из Документы.ДокументыЦепочки цикл
		Док = Стр.Документ.ПолучитьОбъект();
		
		Для каждого Реквизит из  Док.Метаданные().Реквизиты Цикл
			мТипов = Реквизит.Тип.Типы();
			Для каждого Тип из мТипов Цикл
				Если Тип = Тип("СправочникСсылка.Контрагенты") и Док[Реквизит.Имя] = СтКонт тогда
					Док[Реквизит.Имя] = Объект.Контрагент;
				КонецЕсли;
			КонецЦикла;
		КонецЦикла;
		
		Для каждого ТабЧасть из Док.Метаданные().ТабличныеЧасти Цикл
			Для каждого Реквизит из ТабЧасть.Реквизиты  Цикл
				мТипов = Реквизит.Тип.Типы();
				Для каждого Тип из мТипов Цикл
					Если Тип = Тип("СправочникСсылка.Контрагенты") тогда
						Для каждого Строка из Док[ТабЧасть.Имя] Цикл
							Если строка[реквизит.Имя] = СтКонт тогда
								строка[реквизит.Имя]= Объект.Контрагент;
							КонецЕсли;
						КонецЦикла;
					КонецЕсли;
				КонецЦикла;
			КонецЦикла;
		КонецЦикла;
	Объект.ДоговорКонтрагента = ДляДокументов.ДокументПодобратьДоговор(Объект.Контрагент,Объект.Организация,Тип("ДокументОбъект.ПриложениеПокупателя"));	
	ДоговорПриИзмененииНаСервере();	
	//Док.Записать();	
	КонецЦикла;
Показать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот