Странное поведение строки программно добавленной таблицы в реквизиты формы

1. fixin 4280 26.01.25 12:03 Сейчас в теме
Добавил в форму БС_ТаблицаРазделов - таблицу значений:

Форма.БС_ТаблицаРазделов - ДанныеФормыКоллекция

Перебираю ее элементы на сервере в СтрокаРаздела через Для Каждого:

СтрокаРаздела - ДанныеФормыЭлементКоллекции

Так вот, если что-то меняю в СтрокаРаздела, это не отражается в Форма.БС_ТаблицаРазделов

Если меняю что-то в Форма.БС_ТаблицаРазделов через индекс ([1]) то меняется.

1С:Предприятие 8.3 (8.3.24.1586)

Приходится писать так:

Для ИндРаздела = 1 ПО Форма.БС_ТаблицаРазделов.Количество()  Цикл
	СтрокаРаздела = Форма.БС_ТаблицаРазделов[ИндРаздела-1];
	...
	СтрокаРаздела.КоличествоЗадач = СтрокаРаздела.КоличествоЗадач + 1;
	...			
	//Почему-то не обновляется
	ЗаполнитьЗначенияСвойств(Форма.БС_ТаблицаРазделов[ИндРаздела-1],СтрокаРаздела); 
КонецЦикла;
Показать



Похоже, что ДанныеФормыЭлементКоллекции не связан с таблицей ДанныеФормыКоллекция? Создается его копия или как?
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
6. user2107191 26.01.25 16:09 Сейчас в теме +0.5 $m
(5) Дык ясен пень! ИзменитьРеквизиты() - это практическое перестроение формы заново, инициализация всех реквизитов с присваиванием им новых внутренних идентификаторов/ссылок. Соответственно, все существующие в оперативной памяти прямые ссылки на них становятся неактуальными.

А вот обращение по индексу - это всегда новое считывание данных в новую "переменную" (область памяти). Поэтому оно работает всегда.
user1936660; +1 Ответить
5. fixin 4280 26.01.25 15:50 Сейчас в теме
(4)

удалось воспроизвести ситуцию в отдельной обработке.
проблема проявляется только если внутри цикла добавлять новые реквизиты формы.
Тогда ссылка на строку перестает указывать каким-то образом на эту форму.

Я так понимаю, это недокументированная ошибка (фича)?


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

	ДобавляемыеРеквизиты = Новый Массив; //Определяем массив добавляемых реквизитов

	ИмяРеквизитаТаблицыРазделов = "БС_ТаблицаРазделов";
	НовыйРеквизит = Новый РеквизитФормы(ИмяРеквизитаТаблицыРазделов, Новый ОписаниеТипов("ТаблицаЗначений")); 
	ДобавляемыеРеквизиты.Добавить(НовыйРеквизит); 
	
	ЭтаФорма.ИзменитьРеквизиты(ДобавляемыеРеквизиты); //Применяем реквизиты 
	
	ДобавляемыеРеквизиты = Новый Массив; //Определяем массив добавляемых реквизитов
	
	
	ТипЧисло = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0));
	НовыйРеквизит = Новый РеквизитФормы("КоличествоЗадач",ТипЧисло,ИмяРеквизитаТаблицыРазделов); 
	ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
	
	ЭтаФорма.ИзменитьРеквизиты(ДобавляемыеРеквизиты); //Применяем реквизиты
	
КонецПроцедуры

&НаКлиенте
Процедура Тест(Команда)
	ТестНаСервере();
КонецПроцедуры

Функция ТестНаСервере()                             
	СчитатьНаСервере(ЭтаФорма);
КонецФункции

Функция СчитатьНаСервере(Форма)                             
	Форма.БС_ТаблицаРазделов.Очистить();
	Форма.БС_ТаблицаРазделов.Добавить();
	Форма.БС_ТаблицаРазделов.Добавить();
	Форма.БС_ТаблицаРазделов.Добавить();
	Форма.БС_ТаблицаРазделов.Добавить();
	Форма.БС_ТаблицаРазделов.Добавить();
	Форма.БС_ТаблицаРазделов.Добавить();
	
	Для Каждого СтрокаРаздела ИЗ Форма.БС_ТаблицаРазделов Цикл
		Для Инд = 1 по 5 Цикл
			
			ДобавляемыеРеквизиты = Новый Массив; //Определяем массив добавляемых реквизитов
			ТипЧисло = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0));
			guid = "БС_" + СтрЗаменить(Новый УникальныйИдентификатор(), "-", "");
			НовыйРеквизит = Новый РеквизитФормы(guid, ТипЧисло); 
			ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);  
	 		Форма.ИзменитьРеквизиты(ДобавляемыеРеквизиты); //Применяем реквизиты 

			НовыйЭлемент  = Форма.Элементы.Добавить(guid,Тип("ПолеФормы"));
			НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;      
			НовыйЭлемент.ПутьКДанным = guid;   
			
			Форма[guid] = guid;

			СтрокаРаздела.КоличествоЗадач = СтрокаРаздела.КоличествоЗадач + 1;
		КонецЦикла;
	КонецЦикла;                                             
	
	Сообщить("СтрокаРаздела.КоличествоЗадач = " + СтрокаРаздела.КоличествоЗадач);
	Сообщить("Форма.БС_ТаблицаРазделов[0].КоличествоЗадач = " + Форма.БС_ТаблицаРазделов[0].КоличествоЗадач);
КонецФункции

Показать
Прикрепленные файлы:
ТестДобавленнойТаблицы.epf
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. dmitrichenko.ivan 6 26.01.25 13:17 Сейчас в теме
Для Каждого Строка Из Форма.БС_ТаблицаРазделов Цикл 
Работает
3. fixin 4280 26.01.25 15:11 Сейчас в теме
4. user2107191 26.01.25 15:31 Сейчас в теме
А что должно обновиться-то? У тебя в ЗаполнитьЗначенияСвойств() и Приемник и Источник ссылаются на одну и туже сущность.
5. fixin 4280 26.01.25 15:50 Сейчас в теме
(4)

удалось воспроизвести ситуцию в отдельной обработке.
проблема проявляется только если внутри цикла добавлять новые реквизиты формы.
Тогда ссылка на строку перестает указывать каким-то образом на эту форму.

Я так понимаю, это недокументированная ошибка (фича)?


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

	ДобавляемыеРеквизиты = Новый Массив; //Определяем массив добавляемых реквизитов

	ИмяРеквизитаТаблицыРазделов = "БС_ТаблицаРазделов";
	НовыйРеквизит = Новый РеквизитФормы(ИмяРеквизитаТаблицыРазделов, Новый ОписаниеТипов("ТаблицаЗначений")); 
	ДобавляемыеРеквизиты.Добавить(НовыйРеквизит); 
	
	ЭтаФорма.ИзменитьРеквизиты(ДобавляемыеРеквизиты); //Применяем реквизиты 
	
	ДобавляемыеРеквизиты = Новый Массив; //Определяем массив добавляемых реквизитов
	
	
	ТипЧисло = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0));
	НовыйРеквизит = Новый РеквизитФормы("КоличествоЗадач",ТипЧисло,ИмяРеквизитаТаблицыРазделов); 
	ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
	
	ЭтаФорма.ИзменитьРеквизиты(ДобавляемыеРеквизиты); //Применяем реквизиты
	
КонецПроцедуры

&НаКлиенте
Процедура Тест(Команда)
	ТестНаСервере();
КонецПроцедуры

Функция ТестНаСервере()                             
	СчитатьНаСервере(ЭтаФорма);
КонецФункции

Функция СчитатьНаСервере(Форма)                             
	Форма.БС_ТаблицаРазделов.Очистить();
	Форма.БС_ТаблицаРазделов.Добавить();
	Форма.БС_ТаблицаРазделов.Добавить();
	Форма.БС_ТаблицаРазделов.Добавить();
	Форма.БС_ТаблицаРазделов.Добавить();
	Форма.БС_ТаблицаРазделов.Добавить();
	Форма.БС_ТаблицаРазделов.Добавить();
	
	Для Каждого СтрокаРаздела ИЗ Форма.БС_ТаблицаРазделов Цикл
		Для Инд = 1 по 5 Цикл
			
			ДобавляемыеРеквизиты = Новый Массив; //Определяем массив добавляемых реквизитов
			ТипЧисло = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0));
			guid = "БС_" + СтрЗаменить(Новый УникальныйИдентификатор(), "-", "");
			НовыйРеквизит = Новый РеквизитФормы(guid, ТипЧисло); 
			ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);  
	 		Форма.ИзменитьРеквизиты(ДобавляемыеРеквизиты); //Применяем реквизиты 

			НовыйЭлемент  = Форма.Элементы.Добавить(guid,Тип("ПолеФормы"));
			НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;      
			НовыйЭлемент.ПутьКДанным = guid;   
			
			Форма[guid] = guid;

			СтрокаРаздела.КоличествоЗадач = СтрокаРаздела.КоличествоЗадач + 1;
		КонецЦикла;
	КонецЦикла;                                             
	
	Сообщить("СтрокаРаздела.КоличествоЗадач = " + СтрокаРаздела.КоличествоЗадач);
	Сообщить("Форма.БС_ТаблицаРазделов[0].КоличествоЗадач = " + Форма.БС_ТаблицаРазделов[0].КоличествоЗадач);
КонецФункции

Показать
Прикрепленные файлы:
ТестДобавленнойТаблицы.epf
6. user2107191 26.01.25 16:09 Сейчас в теме +0.5 $m
(5) Дык ясен пень! ИзменитьРеквизиты() - это практическое перестроение формы заново, инициализация всех реквизитов с присваиванием им новых внутренних идентификаторов/ссылок. Соответственно, все существующие в оперативной памяти прямые ссылки на них становятся неактуальными.

А вот обращение по индексу - это всегда новое считывание данных в новую "переменную" (область памяти). Поэтому оно работает всегда.
user1936660; +1 Ответить
7. fixin 4280 26.01.25 16:20 Сейчас в теме
(6) это не особо очевидно, но похоже что так. ссылки не держатся. ссылаются на прошлую копию реквизита.
8. пользователь 26.01.25 16:24
Сообщение было скрыто модератором.
...
Оставьте свое сообщение

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