Имя: Пароль:
1C
1С v8
Заполнение программного созданных реквизитов формы на стороне клиента.
0 BelousovSergey
 
08.12.17
10:26
Опустим постановку задачи, перейдем к сути:

Есть форма, на которой программно создаются реквизиты формы и элементы к ним, заполняются данными из внешних файлов.

Проблема в следующем: к программно созданному реквизиту формы нельзя обратиться через ".", в следствии чего я не могу найти способ для заполнения / чтения этих реквизитов без вызова методов РеквизитФормыВЗначение() и ЗначениеВРеквизитФормы(), что заставляет для любого обращения к этим данным вызывать сервер.
Сейчас заполнение такого реквизита выглядит следующим образом:

1) На клиенте читается внешний файл, формируется массив из структур строк, передается на сервер.
2) На сервере вызывается РеквизитФормыВЗначение() заполняется реквизит и передается обратно через ЗначениеВРеквизитФормы()

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

Пример кода:

&НаКлиенте
Перем ExcelApplication;

&НаКлиенте
Процедура ПутьКФайлуНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    ДиалогОткрытияФайла.ПолноеИмяФайла = "";
    ДиалогОткрытияФайла.Фильтр = "(*.xls;*.xlsx)|*.xls;*.xlsx";
    ДиалогОткрытияФайла.МножественныйВыбор = Ложь;
    ДиалогОткрытияФайла.Заголовок = "Выберите файл";
    
    Если ДиалогОткрытияФайла.Выбрать() Тогда
        
        МассивФайлов = ДиалогОткрытияФайла.ВыбранныеФайлы;
        
        Если МассивФайлов.Количество() = 1 Тогда
            ПутьКФайлу = МассивФайлов[0];
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте                                                                          
Процедура ПрочитатьФайл(Команда)
    
    ОчиститьФорму();
    
    Если НЕ ЗначениеЗаполнено(ПутьКФайлу) Тогда
        Сообщить("Не выбран файл для загрузки!");
        Возврат;
    КонецЕсли;
    
    УстановитьСоединениеСExcel();
    
    МассивОписанийКолонов = СформироватьМассивОписанийКолонок();
    
    СформироватьТаблицуДанные(МассивОписанийКолонов);
    ЗаполнитьТаблицуДанные(МассивОписанийКолонов);
    
    РазорватьСоединениеСExcel();
    
КонецПроцедуры

&НаКлиенте
Процедура УстановитьСоединениеСExcel()
    
    Попытка
        ExcelApplication = Новый COMОбъект("Excel.Application");
        ExcelApplication.WorkBooks.Open(ПутьКФайлу);
        Состояние("Обработка файла Microsoft Excel...");
    Исключение
        ExcelApplication = Неопределено;
        Сообщить("Ошибка при открытии файла с помощью Excel! Загрузка не будет произведена!");
        Сообщить(ОписаниеОшибки() );
        Возврат;
    КонецПопытки;

    Попытка  
        ExcelApplication.Sheets(1).Select();
    Исключение
        РазорватьСоединениеСExcel();
        Сообщить("Файл " + Строка(ПутьКФайлу) + " не соответствует необходимому формату! Первый лист не найден!");
        Возврат;
    КонецПопытки;
    
КонецПроцедуры

&НаКлиенте
Процедура РазорватьСоединениеСExcel()
    
    ExcelApplication.ActiveWorkbook.Close();     
    ExcelApplication.Quit();
    ExcelApplication = Неопределено;
    
КонецПроцедуры

&НаКлиенте
Функция СформироватьМассивОписанийКолонок()
    
    МассивОписанийКолонок = Новый Массив;
    
    Сч = 1;
    Пока ЗначениеЗаполнено(ExcelApplication.Cells(1, Сч).Text) Цикл
        
        Структура = Новый Структура;
        Структура.Вставить("НомерКолонки", Сч);
        Структура.Вставить("ИмяКолонки", "Колонка" + Строка(Сч) );
        Структура.Вставить("СинонимКолонки", ExcelApplication.Cells(1, Сч).Text);
        Структура.Вставить("ТипКолонки", Неопределено);
        
        МассивОписанийКолонок.Добавить(Структура);
        
        Сч = Сч + 1;
        
    КонецЦикла;

    Возврат МассивОписанийКолонок;

КонецФункции

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

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

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

&НаКлиенте
Процедура ЗаполнитьТаблицуДанные(МассивОписанийКолонок)
        
    МассивСтруктурСтрок = Новый Массив;
    
    Версия = Лев(ExcelApplication.Version, Найти(ExcelApplication.Version, ".") - 1);
    Если Версия = "8" тогда
        ФайлСтрок = ExcelApplication.Cells.CurrentRegion.Rows.Count;
        ФайлКолонок = Макс(ExcelApplication.Cells.CurrentRegion.Columns.Count, 13);
    Иначе
        ФайлСтрок = ExcelApplication.Cells(1, 1).SpecialCells(11).Row;
        ФайлКолонок = ExcelApplication.Cells(1, 1).SpecialCells(11).Column;
    Конецесли;

    Для НС = 2 по ФайлСтрок Цикл
        
        ОбработкаПрерыванияПользователя();
        
        Состояние("Файл " + ПутьКФайлу + ": Обрабатывается первый лист " + Формат( ?(ФайлСтрок = 0, 0, (100 * НС) / ФайлСтрок) , "ЧЦ=3; ЧДЦ=0") + "%");
        
        СтруктураСтроки = Новый Структура;
                
        Для Каждого ОписаниеКолонки Из МассивОписанийКолонок Цикл
            ИмяКолонки = ОписаниеКолонки.ИмяКолонки;            
            ТекущееЗначение = ExcelApplication.Cells(НС, ОписаниеКолонки.НомерКолонки).Text;

            СтруктураСтроки.Вставить(ИмяКолонки, ТекущееЗначение);
            
        КонецЦикла;

        МассивСтруктурСтрок.Добавить(СтруктураСтроки);
    КонецЦикла;
    
    ЗагрузитьМассивСтруктурСтрокВТаблицуДанные(МассивСтруктурСтрок);

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

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

&НаСервере
Процедура ОчиститьФорму()
    
    МассивУдаляемыхРеквизитов = Новый Массив;
    
    МассивРеквизитовФормы = ПолучитьРеквизиты();
    Для Каждого РеквизитФормы Из МассивРеквизитовФормы Цикл    
        Если РеквизитФормы.Имя = "Данные" Тогда
            МассивУдаляемыхРеквизитов.Добавить("Данные");            
        КонецЕсли;
    КонецЦикла;
    
    Элемент = Элементы.Найти("Данные");
    
    Если Элемент <> Неопределено Тогда
        Элементы.Удалить(Элементы.Найти("Данные") );
    КонецЕсли;
    
    ИзменитьРеквизиты(, МассивУдаляемыхРеквизитов);
    
КонецПроцедуры
1 Волшебник
 
модератор
08.12.17
10:35
Опишите задачу
2 BelousovSergey
 
08.12.17
10:47
Я же написал: "Опустим постановку задачи". Это просто научный интерес, но можно привести массу примеров, где это может понадобиться.
3 vicof
 
08.12.17
10:51
ЭтотОбъект[ИмяРеквизита]
4 BelousovSergey
 
08.12.17
10:55
Хах, ларчик то просто открывался :) спасибо, vicof.