Добавление элементов в классификатор / Модуль

файл
#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Если Параметры.Свойство("АвтоТест") Тогда // Возврат при получении формы для анализа.
		Возврат;
	КонецЕсли;

	УстановитьУсловноеОформление();

	// У отчета <ОтчетИсточникДанных> есть макет <ИмяМакетаСписков> (например: Списки2012Кв1),
	// в макете <ИмяМакетаСписков> в области <ОбластьИсточникДанных> 
	// содержатся коды и наименования элементов классификатора,
	// реквизиты ОтчетИсточникДанных и ОбластьИсточникДанных получаем из параметров
	// ИмяМакетаСписков - берем по умолчанию последний макет.
	
	ИмяСправочника = Параметры.ИмяСправочника;
	ПараметрыКлассификатора = ПолучитьРасположениеКлассификатораСтатистикиИСписокВерсий();
	
	ОбластьИсточникДанных	= ПараметрыКлассификатора.ОбластьИсточникДанных; 
	ИсточникДанных			= ПараметрыКлассификатора.ИсточникДанных; 
	ВидОбъекта				= ПараметрыКлассификатора.ВидОбъекта;
	СписокВерсий			= ПолучитьВерсииСписковОтчета(ВидОбъекта + "." + ИсточникДанных);
	Заголовок				= Метаданные.Справочники[ИмяСправочника].Синоним;
	Подбор					= Параметры.Подбор;
	ВыборГрупп				= Параметры.ВыборГрупп;
	
	Элементы.Классификатор.МножественныйВыбор = Подбор;
	ЗакрыватьПриВыборе = Не Подбор;
	
	Если СписокВерсий.Количество() = 0 Тогда
		
		Отказ = Истина;
		
		ВызватьИсключение НСтр("ru = 'Невозможно выполнить подбор.
								|Классификатор не найден'");
		
	Иначе
		
		СписокВыбора = Элементы.ИмяМакетаСписков.СписокВыбора;
		
		Для Каждого Версия Из СписокВерсий Цикл
			СписокВыбора.Добавить(Версия.Значение, Версия.Представление);
		КонецЦикла;
		
		ИмяМакетаСписков = СписокВерсий[СписокВерсий.Количество() - 1].Значение;
		
	КонецЕсли;
	
	ЗаполнитьКлассификатор();
	
	Если Параметры.ДанныеКлассификатора Тогда
		
		ПолеНазначение = Элементы.Назначение;
		ПолеНазначение.Вид = ВидПоляФормы.ПолеНадписи;
		ПолеНазначение.ЦветТекста = ЦветаСтиля.ЗаблокированныйРеквизитЦвет;
		
	КонецЕсли;
	
	Элементы.ИмяМакетаСписков.Видимость = Не СписокВерсий.Количество() = 1;
	Элементы.Год.Видимость = Не СписокВерсий.Количество() = 1;
	Элементы.Назначение.Видимость = ЗначениеЗаполнено(Параметры.Назначение);
	Элементы.ПрослеживаемыйТовар.Видимость = ИсточникДанных = "КлассификаторТНВЭД"
												И УчетПрослеживаемыхТоваровЛокализация.ИспользоватьУчетПрослеживаемыхИмпортныхТоваров(
													Дата(1, 1, 1));
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура ИмяМакетаСписковПриИзменении(Элемент)
	
	ЗаполнитьКлассификатор();
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийТаблицыКлассификатораФормы

// Вызывается при двойном щелчке мыши или нажатии Enter.
//
&НаКлиенте
Процедура КлассификаторВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	ДобавленыНовыеЭлементыКлассификатора = Ложь;
	
	ВыбранныйЭлемент = КлассификаторВыборНаСервере(ВыбраннаяСтрока, ДобавленыНовыеЭлементыКлассификатора);
	
	Если ВыбранныйЭлемент <> Неопределено Тогда
		ОповеститьФормуИПользователяИЗакрыть(ВыбранныйЭлемент, ДобавленыНовыеЭлементыКлассификатора);
	КонецЕсли;
	
КонецПроцедуры

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

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

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

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

// Получает ранее добавленные элементы справочника
// 
// Параметры:
// 	ИмяСправочника - Строка -
// Возвращаемое значение:
// 	ТаблицаЗначений - таблица с колонками:
// 		* Ссылка - СправочникСсылка -
// 		* Код - Строка -
&НаСервереБезКонтекста
Функция ПолучитьРанееДобавленныеЭлементы(ИмяСправочника)
	
	ТекстЗапроса =
	"ВЫБРАТЬ
	|	ДанныеСправочника.Код КАК Код,
	|	ДанныеСправочника.Ссылка КАК Ссылка,
	|	&ПрослеживаемыйТовар КАК ПрослеживаемыйТовар
	|ИЗ
	|	&ТаблицаСправочника КАК ДанныеСправочника";
	
	ИмяТаблицыСправочника = Метаданные.Справочники[ИмяСправочника].ПолноеИмя();
	ИмяПоляПрослеживаемыйТовар = ?(ИмяТаблицыСправочника = Метаданные.Справочники.КлассификаторТНВЭД.ПолноеИмя(),
									"ДанныеСправочника.ПрослеживаемыйТовар",
									"НЕОПРЕДЕЛЕНО");
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ТаблицаСправочника", ИмяТаблицыСправочника);
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПрослеживаемыйТовар", ИмяПоляПрослеживаемыйТовар);
	
	Запрос = Новый Запрос;
	Запрос.Текст = ТекстЗапроса;
	
	Возврат Запрос.Выполнить().Выгрузить();
	
КонецФункции

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

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

// Вызывает оповещение об изменении справочника,
// вызывает оповещение пользователя,
// закрывает форму подбора из классификатора.
//
&НаКлиенте
Процедура ОповеститьФормуИПользователяИЗакрыть(ВыбранныйЭлемент, ДобавленыНовыеЭлементыКлассификатора = Ложь)
	
	Если ДобавленыНовыеЭлементыКлассификатора Тогда
		ОповеститьОбИзменении(Тип("СправочникСсылка." + ИмяСправочника));
		
		ПоказатьОповещениеПользователя(НСтр("ru = 'Сохранение'"),
										,
										ЭтаФорма.Заголовок,
										БиблиотекаКартинок.Информация32);
	КонецЕсли;
	
	ОповеститьОВыборе(ВыбранныйЭлемент);
	
КонецПроцедуры

&НаСервере
Функция ПолучитьРасположениеКлассификатораСтатистикиИСписокВерсий()
	
	ИмяКлассификатора = ИмяСправочника;
	
	СтруктураПараметров = Новый Структура("ВидОбъекта, ИсточникДанных, ОбластьИсточникДанных");
	
	Если ИмяКлассификатора = "КлассификаторТНВЭД" Тогда
		
		СтруктураПараметров.Вставить("ВидОбъекта", "Справочник");
		СтруктураПараметров.Вставить("ИсточникДанных", "КлассификаторТНВЭД");
		СтруктураПараметров.Вставить("ОбластьИсточникДанных", "Строки");
		
	//++ Локализация
	ИначеЕсли ИмяКлассификатора = "КлассификаторПродукцииПоВидамДеятельности" Тогда
		
		СтруктураПараметров.Вставить("ВидОбъекта", "Отчет");
		СтруктураПараметров.Вставить("ИсточникДанных", "РегламентированныйОтчетСтатистикаФормаП1");
		СтруктураПараметров.Вставить("ОбластьИсточникДанных", "s_okp");
		
	ИначеЕсли ИмяКлассификатора = "КлассификаторУслугНаселению" Тогда
		
		СтруктураПараметров.Вставить("ВидОбъекта", "Отчет");
		СтруктураПараметров.Вставить("ИсточникДанных", "РегламентированныйОтчетСтатистикаФормаП5М");
		СтруктураПараметров.Вставить("ОбластьИсточникДанных", "s_okun");
		
	ИначеЕсли ИмяКлассификатора = "КлассификаторВидовЭкономическойДеятельности" Тогда
		
		СтруктураПараметров.Вставить("ВидОбъекта", "Справочник");
		СтруктураПараметров.Вставить("ИсточникДанных", "Организации");
		СтруктураПараметров.Вставить("ОбластьИсточникДанных", "Классификатор");
		
	ИначеЕсли ИмяКлассификатора = "ОбщероссийскийКлассификаторПродукции" Тогда
		
		СтруктураПараметров.Вставить("ВидОбъекта", "Справочник");
		СтруктураПараметров.Вставить("ИсточникДанных", "ОбщероссийскийКлассификаторПродукции");
		СтруктураПараметров.Вставить("ОбластьИсточникДанных", "ОбщероссийскийКлассификаторПродукции");
		
	ИначеЕсли ИмяКлассификатора = "КлассификаторВидовПредпринимательскойДеятельностиПСН" Тогда
		
		СтруктураПараметров.Вставить("ВидОбъекта", "Справочник");
		СтруктураПараметров.Вставить("ИсточникДанных", "КлассификаторВидовПредпринимательскойДеятельностиПСН");
		СтруктураПараметров.Вставить("ОбластьИсточникДанных", "КлассификаторВидовПредпринимательскойДеятельностиПСН");
		
	//-- Локализация
	КонецЕсли;
	
	Возврат СтруктураПараметров;
	
КонецФункции

// Функция считывает версии списков отчета.
//
// Параметры: 
// - ИмяОтчета - Строка, идентификатор отчета для которого нужно вернуть версии списков.
//
// ВозвращаемоеЗначение:
// СписокЗначений с версиями списков отчета.
//
&НаСервере
Функция ПолучитьВерсииСписковОтчета(ПолноеИмяОбъекта)
	
	СписокВерсий = Новый СписокЗначений;
	
	// Ищем переданный отчет.
	ОбъектМетаданные = Метаданные.НайтиПоПолномуИмени(ПолноеИмяОбъекта);
	
	Если ОбъектМетаданные = Неопределено Тогда
		Возврат СписокВерсий;
	КонецЕсли;
	
	Для Каждого ТекМакет Из ОбъектМетаданные.Макеты Цикл
		
		Макет = ТекМакет;
		ИмяМакета = Макет.Имя;
		
		Если ИмяМакета = "ОКВЭД2"
			Или ИмяМакета = "КлассификаторТоварнойНоменклатурыВнешнеэкономическойДеятельности"
			Или ИмяМакета = "ОбщероссийскийКлассификаторПродукции" 
			Или ИмяМакета = "КлассификаторВидовПредпринимательскойДеятельностиПСН" Тогда
				
			СписокВерсий.Добавить(ИмяМакета, Лев(ИмяМакета, 25));
		
		//++ Локализация
		ИначеЕсли Лев(ИмяМакета, 6) = "Списки" Тогда
			
			СписокВерсий.Добавить(ИмяМакета, Лев(СтрЗаменить(ИмяМакета, "Списки", ""), 4));
			
		ИначеЕсли Лев(ИмяМакета, 20) = "ДанныеКлассификатора" Тогда
			
			СписокВерсий.Добавить(ИмяМакета, Лев(СтрЗаменить(ИмяМакета, "ДанныеКлассификатора", НСтр("ru = 'Данные классификатора'")), 25));
			
		//-- Локализация
		Иначе
			
			Если СписокВерсий.Количество() > 0 Тогда
				Прервать;
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат СписокВерсий;
	
КонецФункции

#КонецОбласти

Связанные материалы