Отражение реквизита другого документа в Форме Списка.

Версия для печатиPDF-версия
Вы уже научили выводить реквизит иного справочника и документа в форме документа. И даже редактировать.
Тут: 

http://novichok1c.ru/comment/1451#comment-1451

Отлично работает, за что еще раз ОГРОМНОЕ Спасибо!
Так же Вы научили редактировать «дистанционно» реквизит другого справочника или документа.
 
Однако у данного метода есть существенный недостаток:
Чтобы произошли измененния, необходимо, чтобы документ, в который выводится реквизит был открыт и перезаписан.
В связи с чем 2 вопроса: 
 
Вопрос 1.
1С возможно объединить реквизит?
Т.е. создать один реквизит для нескольких документов?
К которому документы обращаются, при открытии форм, который можно редактировать из любого документа связанного с этим реквизитом.
 
 
Вопрос 2.
Как вывести данные реквизита документа(справочника) из формы списка другого документа?
(когда документы находятся в подчинении друг друга или связаны, как ЗаказПокупателя и РеализацияТоваровУслуг, Контрагенты и ЗаказПокупателя и т.д.)

1. Возможности использовать 1 реквизит для нескольких документов нет.

2. Не понял вопроса. Нужно выводить значение реквизита подчиненного документа в форме списка основного документа?

В общем - не совсем.

В данном случае в списке подчиненного отразить реквизит родительского.

У Документа ЗаказПокупателя существует реквизит - ЭтапыПродажи.

Он выведен как в сам документ, так и в Форму Списка ЗаказПокупателя.

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

Данный метод был признан очень эффективным и принят на ура!

Однако сотрудницы другого отдела, которые работают, в основном с Документами РеализацияТоваровУслуг, настоятельно, почти на коленях, попросили сделать им вывод этого реквизита, что я и сделал с Вашей помощью. В Форме документа РеализацияТоваровУслуг теперь выведен реквизит ЭтапыПродажи из документа ЗаказПокупателя.

А вот в Форму Списка РеализацияТоваровУслуг не могу.

Т.е. могу лишь так:

 Не интерактивно.

Для того, чтобы увидеть изменение в реквизите, необходимо открыть документ РеализацияТоваровУслуг, чтобы реквизит странслировался, затем записался (приравнялся) в аналогичный Реквизит в документе РеализацияТоваровУслуг, после чего он станет виден в списке.

Однако, если в реквизите ЭтапыПродажи документа ЗаказПокупателя произошли изменения, то они не будут видны в форме Списка РеализацияТоваровУслуг. Там попрежнему будет красоваться устаревшее значение.

Я уже писал в какой-то теме, что не надо создавать в Реализации всяких лишних и ненужных реквизитов, которые дублируют значения соответствующих реквизитов Заказа. Достаточно того, что в Реализации есть реквизит (Сделка), в котором хранится ссылка на Заказ. По этой ссылке можно в любой момент получить значение любого реквизита Заказа и использовать его хоть в форме документа, хоть в форме списка документов, хоть в любом другом месте.

Попробовал:

В процедуре СписокПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)


	    ОформлениеСтроки.Ячейки.ЭтапыПродажи.ОтображатьКартинку = Ложь;
    	ОформлениеСтроки.Ячейки.ЭтапыПродажи.ОтображатьТекст    = Истина;
    	ОформлениеСтроки.Ячейки.ЭтапыПродажи.ОтображатьФлажок   = Ложь;

     	ОформлениеСтроки.Ячейки.ЭтапыПродажи.Текст = ДанныеСтроки.Сделка.ЭтапыПродажи;

 

И вроде все ок, отражает корректно.

Однако стоило коснуться вертикально прокрутки, выдает ошибку:

{Документ.РеализацияТоваровУслуг.Форма.ФормаСпискаAnytos.Форма(197)}: Значение не является значением объектного типа (ЭтапыПродажи)
      ОформлениеСтроки.Ячейки.ЭтапыПродажи.Текст = ДанныеСтроки.Сделка.ЭтапыПродажи;
 
Тоже выдает при движениях по списку клавишами End и PageDown

 

Попробовал так:


   ОформлениеСтроки.Ячейки.ЭтапыПродажи.УстановитьТекст(ДанныеСтроки.Сделка.ЭтапыПродажи);

Лучше не стало.

Причем не на одной машине.

Закинул конфиг на базу на работе, проверил, реже, но выскакиват.

 Скажем так:


 ОформлениеСтроки.Ячейки.ЭтапыПродажи.Текст = "1234567";

  ошибки нет.

  Да, что же я снова не так делаю???.

Нужно учитывать, что Сделка в Реализации имеет составной тип и может быть незаполнена. Т.е. для корректной работы нужно добавить проверку:

Если ЗначениеЗаполнено(ДанныеСтроки.Сделка) И ТипЗнч(ДанныеСтроки.Сделка) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
   ОформлениеСтроки.Ячейки.ЭтапыПродажи.УстановитьТекст(ДанныеСтроки.Сделка.ЭтапыПродажи);
КонецЕсли;

Ура!

Все получилось!

Я под утро ставил проверку на пустое значение, не помогло.

О проверке типа - значения сделки, я смутно догадовался, но от недостатка знаний, не смог бы написать строку...

Огромное Спасибо!

Караул!
Спасите!
 
Все прекрасно выводится, до того момента пока не настал момент Отбора по значению в текущей колонке.
Ни аппаратно, ни программно не работает…
 
Отлично работает отбор с колонками, если у них есть Реквизит:

		 ДокументСписок.Отбор.Сбросить();
		 ДокументСписок.Отбор.ЭтапыПродажи.ВидСравнения=ВидСравнения.Равно;
		 ДокументСписок.Отбор.ЭтапыПродажи.Значение="Отгружать ТК"; 
		 ДокументСписок.Отбор.ЭтапыПродажи.Установить(); 
А с выведенными так:

		ОформлениеСтроки.Ячейки.ЭтапыПродажи.ОтображатьКартинку = Ложь;
		ОформлениеСтроки.Ячейки.ЭтапыПродажи.ОтображатьТекст    = Истина;
		ОформлениеСтроки.Ячейки.ЭтапыПродажи.ОтображатьФлажок   = Ложь;
		 		ОформлениеСтроки.Ячейки.ЭтапыПродажи.УстановитьТекст(ДанныеСтроки.Сделка.ЭтапыПродажи);
Ничего не работает((((
Перепробовал все возможные комбинации известные мне.
С этим можно, что-то сделать?

Боюсь, что тут ничего не сделать.

Как вариант можно выводить на форму не ДокументСписок, а таблицу значений, сформированную программно. Т.е. при открытии формы списка документов подключаете обработчик ожидания, в котором будет делаться запрос к таблице документа с выбором необходимых полей и добавлением дополнительных полей. Результат выполнения запроса выгружается в таблицу значений, связанную с табличным полем на форме. И пользователь работает уже с этой промежуточной таблицей. Но это очень неудобно.

Или попробовать сделать управляемую форму списка. В динамическом списке всё должно работать. Но я не знаю, будет ли управляемая форма работать в этой конфигурации.

Хорошо, с отбором понятно, а как еще можно вывести в Форму Списка Документы РеализацияТоваровУслуг с определенным значением Реквизита «родительского» ЗаказаПокупателя?

Может запросом, или еще как?

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

 

Это слишком все сложно для меня.

На данном этапе я такое не смогу написать…

Идея такая.

Создать в Документе РеализацияТоваровУслуг Реквизит, например, РЭтапТК.

В тех формах, в том числе в Формах Спиков в процедуру при изменении ПоляЭтапПродажи вывести команду, при которой, Если совпадает значение с Отгружать ТК, то будет открываться Специализорованная форма документа РеализацияТоваровУслуг модально, с минимальным набором процедур, где в процедуре ПриОткрытии будет записано приравнивание значение реквизита ЭтапыПродажи документа ЗаказаПокупателей в реквизит  РЭтапТК.

Естественно все это с Оповещением.

После чего, вызванная форма закрывается.

 

Как-то криво выразился. Очень надеюсь, что был понят.

В связи с задумкой хотелось бы получить совет.

1.       Где-то попадалось, что можно «открыть» нужную форму без открытия, но с заданными командами – процедурами. Если это так, подскажите, как это сделать?

2.    Как наиболее эффективно можно вызвать Форму подчиненного докумена? В данном случае - документ Реализации из ЗаказаПокупателя?   

3. Есть другие возможности записи значения в удаленный реквизит подчинённого Документа? Каким-нить оповещением, или еще чем-то, чего я еще не знаю?

4. Подскажите, пожалуйста, комманду которой можно очистить Реквизит.

 

 

Форму вызывать-открывать вообще необходимости нет.

Получаете запросом список подчиненных документов. Обходите выборку. Получаете объект каждого документа. Меняете нужный реквизит. Записываете документ. И всё.

Для этого в модуль объекта документа Заказ покупателя нужно добавить примерно такой код:

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

Желательно перед запуском этого запроса сделать проверку измянялся ли НужныйРеквизит или нет (чтобы лишний раз Реализации не перезаписывать). Это надо делать в процедуре ПередЗаписью модуля объекта документа Заказ покупателя. Примерно так: сначала в модуле объекта объявляете переменную РеквизитИзменен, потом в процедуре ПередЗаписью добавляете код:

РеквизитИзменен = ?(НужныйРеквизит = Ссылка.НужныйРеквизит, Ложь, Истина);

В процедуре ПриЗаписи перед запуском запроса добавляете проверку:

Если РеквизитИзменен Тогда

Для очистки реквизита можно присвоить ему значение Неопределено или "".

 
 
Сделал все согласно Вашим рекомендациям.
Все заработало, с одним минусом.
Только Запись в РеализацииТоваровУслуг перестала корректно работать.
Описываю:
В модуле ЗаказПокупателя в процедуру ПередЗаписью установил следующий код:

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

		КонецЕсли;
		КонецЕсли;

Пробовал, для снижения нагрузки вставить код в форму документа ЗаказПокупателя (а позже и списка) в процедуру ПриИзменении.
Ничего не получилось, ругается, типа РеализацияОбъект.ЭтапыПродажиРТУ – найти не может…
(Перепробовал свой "багаж" знаний – не получилось)
 
 
В Форма Документа РеализацияТоваровУслуг в процедуре ПриИзменении реквизита стоиит следующий код:

Процедура ЭтапыПродажиПриИзменении(Элемент)
	
		Если ТипЗнч(Сделка) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда

	
		Если ЗначениеЗаполнено(Сделка) Тогда 
		ЗаказПокупателяОбъект = Сделка.ПолучитьОбъект();
		Если ЗаказПокупателяОбъект = Неопределено Тогда 
			Возврат;
		КонецЕсли;
		ЗаказПокупателяОбъект.ЭтапыПродажи = РФЭтапыПродажи;
//РФЭтапыПродажи – реквизит формы
		Попытка
			ЗаказПокупателяОбъект.Записать();
		Исключение
			Сообщить(ОписаниеОшибки());
		КонецПопытки;
	КонецЕсли;	
КонецЕсли;	
КонецПроцедуры

 
Все работает, пока не пытаешься выбрать значение "Отгружать ТК"
В этот момент он записывает значения реквизита. Все ок.
А вот изменения в Документе РеализацияТоваровУслуг – нет
И выдает ошибку :
 
Операция не может быть выполнена из-за несоответствия версий или отсутствия записи базы данных (возможно, запись была изменена или удалена)!
 
Помогите, пожалуйста.
1. Что я сделал не так?
2. Можно ли процедуру перенести из модуля Документа в Модуль Формы в процедуру при ЭтапыПродажиПриИзменении?
 

Приношу извинения.

Только написал, психанул, скопировал код из модуля в процедуру ЭтапыПродажиПриИзменении Документа ЗаказПокупателя:


	РеквизитИзменен = ?(ЭтапыПродажи = Ссылка.ЭтапыПродажи, Ложь, Истина);	


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

	
		КонецЕсли;
		КонецЕсли;
		КонецЕсли;

Как тут же все заработало!!!

Вероятно, я - старый балбес где-то допускал очипятку…

ПРОСТИТЕ.

Огромное спасибо за терпение и неоценимую помощь.

Ошибка с несоответствием версий к размещению кода отношения не имеет. Она связано с тем, что изменения в заказ вносятся при открытой и изменённой реализации. Эту ситуацию надо обрабатывать отдельно (через оповещения).

А перезапись Реализации всё-таки лучше делать в ПриЗаписи модуля объекта документа Заказ покупателя. Зачем при каждом изменении реквизита перезаписывать документ реализации? Это неоптимально.

Вот как раз ошибку выдает при записи из РеализацияТоваровУслуг.

Т.е. когда пытаюсь изменить реквизит в открытом документе РеализацияТоваровУслуг.

А из ЗаказПокупателя - проходит нормально, даже при открытом документе РеализацияТоваровУслуг.

 

В общем-то ситуация такая, как я описывал раньше. Сначала происходит интерактивное изменение документа РТУ, из него изменяется и перезаписывается ЗП, из которого пытается перезаписаться РТУ.

Для решения проблемы можно использовать ДополнительныеСвойства документа ЗП. Нужно в документе РТУ перед записью ЗП добавить подобную строчку:

ЗаказОбъект.ДополнительныеСвойства.Вставить("НеПерезаписыватьРеализацию", Истина);

А в документе ЗП ПриЗаписи перед перезаписью РТУ добавить проверку:

Если ДополнительныеСвойства.Свойство("НеПерезаписыватьРеализацию") Тогда
    Возврат;
КонецЕсли;
Сейчас попробую Ваш способ.
А сегодня ночью выкрутился так:
В Модуле Документа ЗаказПокупателя добавил следующее условие:
Если ЭтапыПродажи = РеализацияОбъект.ЭтапыПродажиРТУ Тогда
 
ЭтапыПродажиРТУ – Реквизит РеализацииТоваровУслуг.
Смысл в том, что если изменения Реквизита происходит из формы Документа РеализацияТоваровУслуг, то в реквизите уже нужное значение, тогда и смысла записи и внесения изменения в РеализациюТоваровУслуг нет.
Вот что получилось:


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

	Если ЭтапыПродажи =  РеализацияОбъект.ЭтапыПродажиРТУ Тогда
 				
	Попытка 
			РеализацияОбъект.ЭтапыПродажиРТУ = ЭтапыПродажи;
			РеализацияОбъект.Записать();
		Исключение
		КонецПопытки;
		
	КонецЕсли;	
	
		КонецЕсли;
	КонецЦикла;


Ну тут, конечно, хитро сделано. Сначала присвоить нужное значение реквизиту, а потом сравнить значение реквизита с нужным значением. Это ж всегда Истина будет.

Я понял свою ошибку.

В торопях, когда писал ответ, не туда строчку влепил, получилось глупость, конечно, сначало сравнение, а потом записть если иначе.

Сейчас сделал по Вашему.

Все проблемы исчерпались.

Правда я ничего не понял, что это за дополнительные свойства???

Получилось так:


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

		Если РеализацияОбъект = Неопределено Тогда 
			Продолжить;
		КонецЕсли;
		
		РеализацияОбъект.ЭтапыПродажиРТУ = ЭтапыПродажи;
		Попытка
			РеализацияОбъект.Записать();
		Исключение
		КонецПопытки;
	КонецЦикла;
	
Иначе	
	
// Тут собираюсь повторить код, только  

//РеализацияОбъект.ЭтапыПродажиРТУ = Неопределено;

	

		//КонецЕсли;
		КонецЕсли;