четверг, 25 июня 2015 г.

Алгоритм Нарайаны для 1С 8.2

Данный код реализует алгоритм Нарайаны на движке 1С 8.2.

Функция ВсеПерестановки(ЧислоЭлементов) Экспорт

	Результат = Новый Массив;
	Массив = Новый Массив;
	Для й=1 По ЧислоЭлементов Цикл
		Массив.Добавить(й);	
	КонецЦикла; 
	Результат.Добавить(Массив);
	
	Пока Истина Цикл
		Список = Новый СписокЗначений;
		Список.ЗагрузитьЗначения(Массив);
		Массив = Список.ВыгрузитьЗначения();
		
		Ключ = Неопределено;
		Для й=0 по ЧислоЭлементов-2 Цикл
			Если Массив[й]<Массив[й+1] Тогда
				Ключ = й;			
			КонецЕсли; 			
		КонецЦикла; 
		
		Если Ключ=Неопределено Тогда
			Прервать;		
		КонецЕсли; 
		
		Для й=1-ЧислоЭлементов По 0 Цикл
			Если Массив[Ключ]<Массив[-й] Тогда
				Прервать;			
			КонецЕсли; 		
		КонецЦикла; 	
		Поменять(Массив[Ключ],Массив[-й]);
		
		й = Ключ+1;
		к = ЧислоЭлементов-1;
		Пока й<к Цикл
			Поменять(Массив[й],Массив[к]);
			й = й+1;
			к = к-1;
		КонецЦикла; 
		
		Результат.Добавить(Массив);
		
	КонецЦикла; 
	
    Возврат Результат;
	
КонецФункции

Процедура Поменять(А,Б)

	Т = А;
	А = Б;
	Б = Т;

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


среда, 8 апреля 2015 г.

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

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

 МассивЗаполнения =  Новый Массив(НЗ.Количество());
 Для каждого Эл Из НЗ.Отбор Цикл
  Если Эл.Использование Тогда
   Для й=0 По МассивЗаполнения.ВГраница() Цикл
    МассивЗаполнения[й] = Эл.Значение;   
   КонецЦикла; 
   НЗ.ЗагрузитьКолонку(МассивЗаполнения,Эл.Имя);
  КонецЕсли; 
 КонецЦикла; 
 НЗ.Записать(Замещать);

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