gifts2017

1с v8.2.13 ХранилищеЗначений в Табличной части объекта

Опубликовал Константин Пономаренко (kostia.ck) в раздел Программирование - Практика программирования

В тонком и веб-клиенте имеется возможность загружать внешние файлы, но сохранение в реквизите табличной части отрабатывается некорректно. Предлагаю свой метод решения этой задачи.

В табличных частях объектов 8.2 имеется возможность создавать реквизиты типа ХранилищеЗначения но сохранеие этих реквизитов в тонком клиенте отрабатывается некорректно, разве что каждый раз после присваивания вызывать метод записи объекта Записать(), что не очень то удобно использовать каждый раз при изменении отдельной строки. Для корректной работы с реквизитами такого типа предлагаю сохранять значения в соответствия, которое в свой черед помещается в реквизит формы типа ХранилищеЗначения. Ключом соответствия является идентификатор строки табличной части


////////////////////////////////////////////////////////////////////////
/////////////////////// Обработчик событий на клиенте

&НаКлиенте
Процедура ПрикрепленныеФайлыПередУдалением(Элемент, Отказ)
   
ТекущаяСтрока = Элементы.ПрикрепленныеФайлы.ТекущаяСтрока;
   
ДанныеСтроки = Элементы.ПрикрепленныеФайлы.ДанныеСтроки(ТекущаяСтрока);

   
УдалитьДанныеИзСоответствия(ДанныеСтроки.НомерСтроки);
КонецПроцедуры

////////////////////////////////////////////////////////////////////////
/////////////////////// Обработчик событий на сервере

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
   
Хранилище = Новый ХранилищеЗначения(Новый Соответствие);

   
Индекс = -1;
    Для Каждого
Строка Из Объект.ПрикрепленныеФайлы Цикл
       
Индекс = Макс(Индекс, Строка.ПолучитьИдентификатор());
    КонецЦикла;
КонецПроцедуры

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
   
Соответствие = Хранилище.Получить();

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

   
Хранилище = Новый ХранилищеЗначения(Соответствие);
КонецПроцедуры

////////////////////////////////////////////////////////////////////////
/////////////////////// Серверные процедуры и функции

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

   
Соответствие = Хранилище.Получить();
   
Соответствие.Вставить(Индекс, Новый ХранилищеЗначения(Файл));
   
Хранилище = Новый ХранилищеЗначения(Соответствие);

   
ЗначениеВРеквизитФормы(СправочникОбъект, "Объект");
КонецПроцедуры

&НаСервере
Процедура УдалитьДанныеИзСоответствия(ТекущаяСтрока);
   
ИндексТекущейСтроки = Объект.ПрикрепленныеФайлы[ТекущаяСтрока-1].ПолучитьИдентификатор();

   
Соответствие = Хранилище.Получить();
   
Соответствие.Удалить(ИндексТекущейСтроки);
   
Хранилище = Новый ХранилищеЗначения(Соответствие);
КонецПроцедуры
.

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Максим Полянский (yandextesting) 22.12.11 00:12
Если не ошибаюсь эта задача решаема через временное хранилище, вот например получение данных (присвоение делается в обратном порядке, под рукой примера сейчас нет, но тоже через АдресХранилища - ПоместитьВоВременноеХранилище):

&НаСервере 
Функция ПолучитьИзХранилища(НомерСтроки)
ЭтотОбъект=РеквизитФормыВЗначение("Объект");
Хранилище=ЭтотОбъект.Товары[НомерСтроки].Файл;
АдресХранилища=ПоместитьВоВременноеХранилище(Хранилище,ЭтаФорма.УникальныйИдентификатор);
Возврат АдресХранилища;
КонецФункции

&НаКлиенте
Процедура КнопкаНажатие(Элемент)
НомерСтроки=Элементы.Товары.ТекущаяСтрока;
Адрес=ПолучитьИзХранилища(НомерСтроки);
Хранилище=ПолучитьИзвременногоХранилища(Адрес);
КонецПроцедуры
...Показать Скрыть
2. Константин Пономаренко (kostia.ck) 22.12.11 02:13
Задача решаема через временное хранилище для реквизитов объекта
&НаСервере
Процедура ПоместитьФайлИзВременногоХранилищаВТЗ(МассивФайлов)
	Для Каждого ЭлементМассиваФайлов Из МассивФайлов Цикл 
		ФайлИзХранилища = ПолучитьИзВременногоХранилища(ЭлементМассиваФайлов.Хранение);
		ЭлементХранилища  = Новый ХранилищеЗначения(ФайлИзХранилища);
		
		НовыйЭлементСправочника = Справочники.Контент.СоздатьЭлемент();
		НовыйЭлементСправочника.Файл = ЭлементХранилища;
		НовыйЭлементСправочника.Записать();
	КонецЦикла;
КонецПроцедуры
...Показать Скрыть

Для реквизита табличной части, по идеи, тоже должно быть так, но на самом деле после выхода из процедуры помещения в реквизит именно табличной части значение "ПрикрепленныйФайл" не сохраняется.
&НаСервере
Процедура ПоместитьФайлИзВременногоХранилищаВТЗ(МассивФайлов)
	ДокументОбъект = РеквизитФормыВЗначение("Объект");
	Для Каждого ЭлементМассиваФайлов Из МассивФайлов Цикл 
		ФайлИзХранилища = ПолучитьИзВременногоХранилища(ЭлементМассиваФайлов.Хранение);
		ЭлементХранилища  = Новый ХранилищеЗначения(ФайлИзХранилища);
		
		НоваяСтрокаВложения = ДокументОбъект.ТаблицаПрикрепленныхФайлов.Добавить();
		НоваяСтрокаВложения.ПрикрепленныйФайл = ЭлементХранилища; // Не отрабатывает сохранение после выхода из процедуры
	КонецЦикла;
	ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");     
КонецПроцедуры
...Показать Скрыть
Брекпоинт перед записью на сервере:
ТекущийОбъект.ТаблицаПрикрепленныхФайлов[0].Файл.Получить() = Неопределено
veretennikoff; +1 Ответить
3. Юрий Осипов (yuraos) 23.05.13 14:37
А почему

1с v8.2.13

для других версий 8.2 и под 8.3 может не работать???
4. TMV 24.05.13 06:38
(3) yuraos,
А почему
Может, потому что год 2011?
для других версий 8.2 и под 8.3 может не работать?
Мне кажется, преемственность здесь будет соблюдаться..