gifts2017

Особенность использования метода ИзменитьРеквизиты()

Опубликовал Серега Веретенников (veretennikoff) в раздел Программирование - Практика программирования

Обнаружил странное поведение платформы, которым и хочу поделиться

Исходные данные:

На форме имеется реквизит ТЗ с типом "таблица значений"

При создании формы на сервере эта таблица заполняется данными (все поля, кроме первого - "Идентификатор")

 

Что должно происходить:

По нажатию на кнопку для каждой строки должно создаться поле ввода и имя этого поля должно записаться в первую колонку ТЗ ("Идентификатор")

 

Что происходит:

Заполняется только первая строка, а далее все строки пустые

 

Код

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Для Сч=1 По 4 Цикл
		НоваяСтрока = тзПробег.Добавить();
		НоваяСтрока.Автомобиль = "Автомобиль" + Сч;
		НоваяСтрока.ВидТоплива = "ВидТоплива" + Сч;
		НоваяСтрока.ВидОборудования = "ВидОборудования" + Сч;
		НоваяСтрока.Пробег = Сч *1000;
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура СоздатьНовыеПоляВвода(Команда)
	ОбновитьРеквизитыФормыПоВидамТоплива();
КонецПроцедуры

&НаСервере
Процедура ОбновитьРеквизитыФормыПоВидамТоплива()
	
	// переменнные
	ГруппаРодитель = Элементы.ГруппаПробегиПоВидамТоплива;
	
	// удалим старые поля и реквизиты
	МассивУдаляемыхРеквизитов = Новый Массив;
	Для Сч = -ГруппаРодитель.ПодчиненныеЭлементы.Количество() По -1 Цикл
		МассивУдаляемыхРеквизитов.Добавить(ГруппаРодитель.ПодчиненныеЭлементы[-Сч-1].Имя);
		Элементы.Удалить(ГруппаРодитель.ПодчиненныеЭлементы[-Сч-1]);
	КонецЦикла;
	Если МассивУдаляемыхРеквизитов.Количество() Тогда 
		ИзменитьРеквизиты(, МассивУдаляемыхРеквизитов);
	КонецЕсли;
	
	// создание описания типов для реквизита формы
	КЧ = Новый КвалификаторыЧисла(10,2);
	Массив = Новый Массив;
	Массив.Добавить(Тип("Число"));
	ОписаниеТиповЧ = Новый ОписаниеТипов(Массив, , ,КЧ); 
	
	// создадим новые
	Для каждого СтрокаТЗ Из тзПробег Цикл
		
		// создаем уникальное наименование поля
		УникальноеИмя = "Поле" + СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
		
		// помещаем в таблицу, чтобы потом можно было найти данные, соответствующие этому полю
		СтрокаТЗ.Идентификатор = УникальноеИмя;
		
		// создаем реквизит формы
		ДобавляемыеРеквизиты = Новый Массив;
		НовыйРеквизит = Новый РеквизитФормы(УникальноеИмя, ОписаниеТиповЧ);
		НовыйРеквизит.Заголовок = "Пробег по топливу " + СтрокаТЗ.ВидТоплива;
		ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
		
		Сообщить("В поле Идентификатор строки содержится значение: " + тзПробег[СтрокаТЗ.ПолучитьИдентификатор()].Идентификатор);
		Сообщить("тзПробег[СтрокаТЗ.ПолучитьИдентификатор()] = СтрокаТЗ: " + (тзПробег[СтрокаТЗ.ПолучитьИдентификатор()] = СтрокаТЗ));
		ИзменитьРеквизиты(ДобавляемыеРеквизиты);
		Сообщить("После применения команды ИзменитьРеквизиты: " + тзПробег[СтрокаТЗ.ПолучитьИдентификатор()].Идентификатор);
		Сообщить("тзПробег[СтрокаТЗ.ПолучитьИдентификатор()] = СтрокаТЗ: " + (тзПробег[СтрокаТЗ.ПолучитьИдентификатор()] = СтрокаТЗ));
		Сообщить("");
		// заполним значением из ПЛ
		ЭтаФорма[УникальноеИмя] = СтрокаТЗ.Пробег;
		
		// добавляем новое поле ввода на форму
		Элемент = ЭтаФорма.Элементы.Добавить(УникальноеИмя, Тип("ПолеФормы"), ГруппаРодитель); 
		Элемент.Вид = ВидПоляФормы.ПолеВвода;
		Элемент.ПутьКДанным = УникальноеИмя;
		ШаблонШрифта = Новый Шрифт(, 24, Истина);
		Элемент.Шрифт = ШаблонШрифта;
		Элемент.ШрифтЗаголовка = ШаблонШрифта;
		
		// TO DO: заменить на вызов в процедуре по кнопке ввести данные перезаполнения ТЗ, если поля были из конкретной группы
		Элемент.УстановитьДействие("ПриИзменении", "ПробегПоТопливуПриИзменении");
		
	КонецЦикла;

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

Комментарий: 

Конкретно эта обработка конечно надуманная, не претендует на оптимальность выполнения кода и т.п.

Она служит только для демонстрации замеченной мной особенности

Специально обрамил ИзменитьРеквизиты() выводом сообщений, чтобы показать, что СтрокаТЗ становится "чем-то другим" именно после применения этого метода

В данном случае Истину вернет только один раз - только для первой строки


Вывод: 

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

ТЗ[СтрокаТЗ.ПолучитьИдентификатор()]

Так мы точно будем уверены, что ТЗ заполнится корректно


UPD: на некоторых тестах возникала ошибка, вот это обращение более универсальное

тзПробег.НайтиПоИдентификатору(СтрокаТЗ.ПолучитьИдентификатор()).Идентификатор = УникальноеИмя; 

Скачать файлы

Наименование Файл Версия Размер
ТестоваяОбработка 1
.epf 7,71Kb
22.04.15
1
.epf 1 7,71Kb Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Константин Юрин (kostyaomsk) 04.05.15 18:19
Интересную Вы заметили особенность метода ИзменитьРеквизиты(). Нужно учесть.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа