[Регламенты] В справочнике запрет элементов и групп на одном уровне иерархии..?

Автор Злоп, 20 мая 2025, 02:08

« назад - далее »

Злоп

Хочется запретить смешивать на одном уровне иерархии справочника наличие одновременно и групп и элементов.
Как бы это сделать красиво/правильно/няшно с минимумом нагрузки на систему...?
Пока ограничится отлупом при интерактивном создании элементов/групп.
Работать и на файловой и на скульной чтобы форматобазонезависимо...
.
Какие могут быть варианты?

Харлампий Дымба

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

Для запрета ввода "в списке" - наверное, нормального решения не существует.

Злоп

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

Злоп

Цитата: Харлампий Дымба от 21 мая 2025, 22:35Для интерактивного запрета ввода "в диалоге" - универсальный код такой:

Человечище!
Просто круть, я не допер до такого варианта. Правда и не думал сильно, но есть сомнение что до этого додумался бы за разумное время.. или вообще...

Скопипастил в копилку!

vladmenleo

Вот вариант с использованием 1с++
ТекстSQLЗапроса =    "
    |SELECT
    |        СправочникТовары.ID [Товар $Справочник.Товары]
    |FROM
    |        SC55 СправочникТовары WITH (NOLOCK)
    |WHERE
    |        СправочникТовары.PARENTID = :Родитель
    |AND
    |        СправочникТовары.ISFOLDER = (1 + :Группа)
    |";
    
    ODBCRecordSet = СоздатьОбъект("ODBCRecordSet");
    ODBCRecordSet.УстановитьТекстовыйПараметр("Родитель", Родитель);
    ODBCRecordSet.УстановитьТекстовыйПараметр("Группа", ЭтоГруппа());
    
    ТзОтчета = СоздатьОбъект("ТаблицаЗначений");
    ТзОтчета = ODBCRecordSet.ВыполнитьИнструкцию(ТекстSQLЗапроса);
    
    Если ТзОтчета.КоличествоСтрок() > 0 Тогда
        сообщить("Элементы и группы не могут создаваться на одном уровне иерархии", "i");
        СтатусВозврата(0);
        Возврат;
    КонецЕсли;

Харлампий Дымба

Цитата: vladmenleo от 22 мая 2025, 12:04Вот вариант с использованием 1с++
Да, наверняка гораздо быстрее будет. А ещё наверное, можно
 SELECT TOP (1) ?
Ну и для подчиненных справочников допилить

Цитата: Злоп от 22 мая 2025, 03:40Скопипастил в копилку!
Там тогда лучше бы сделать глобальной функцией, типа
глПроверкаСоответствияИерархии(Конт, Родитель)
потому что эту проверку надо будет вызывать как минимум в трех местах:
ВводНового в форме элемента;
ВводНового в форме группы;
ПриПереносеЭлементаВДругуюГруппу(<Элемент>,<Группа>) в формах списка с отображением дерева групп.
Причем в последнем случае, надо будет в качестве Родителя передавать <Группа>. А вот владельца брать не и Группа.Владелец, а из Элемент.Владелец, потому что если переносим в корень (группа пустая), то Группа.Владелец будет пуста, хотя по факту владелец элемента не меняется и равен Элемент.Владелец.



 

Злоп

Цитата: Харлампий Дымба от 23 мая 2025, 00:34Там тогда лучше бы сделать глобальной функцией, типа
так примерно и сделал. Про перенос групп помню, но делать пока не стал, сделал по твоей указивке, норм.

Еще скрипт набросал, для разноски элементов в автосоздаваемые группы. Разовая задачка, руками бы задолбались вычищать большой справочник от смеси элементов и групп

Злоп

В результате примерно вот так
отдельно используется СтатусВозврата(0) и Результат - если придется использовать где-то в коде обработок/отчетов для проверки

//***************************************************************************************************
// при вводе нового элемента и группы:
//		Процедура ВводНового()
// 			Конт = глВзятьКонтекст(Контекст);
//			Результат = глЗапретСмешенияГруппЭлементов(Конт,Родитель,0);
//				Если СтатусВозврата() = 0 Тогда
//				Возврат;
//			КонецЕсли;
//		КонецПроцедуры // ВводНового()
//
// при переносе в другую группу ПриПереносеЭлементаВДругуюГруппу(<Элемент>,<Группа>) 
// в формах списка с отображением дерева групп:
// 	надо в качестве Родителя передавать <Группа>. А вот владельца брать не из Группа.Владелец,
//	а из Элемент.Владелец, потому что если переносим в корень (группа пустая), то Группа.Владелец
//	будет пуста, хотя по факту владелец элемента не меняется и равен Элемент.Владелец
//		Процедура ПриПереносеЭлементаВДругуюГруппу(Элемент,Группа)
//			Результат = глЗапретСмешенияГруппЭлементов(Элемент,Группа,0);
//			Если СтатусВозврата() = 0 Тогда
//				Возврат;
//			КонецЕсли;
//		КонецПроцедуры // ПриПереносеЭлементаВДругуюГруппу
//	
Функция глЗапретСмешенияГруппЭлементов(Конт,Родитель,Режим=0) Экспорт
	
	Результат = 1;
	Если ПустоеЗначение(Режим) = 0 
	Тогда // режим игнорирования проверки, разрешено смешивание
		Возврат Результат;
	КонецЕсли;
	
	ВидСправочника = ВРег(Конт.Вид());
	поз = Найти(ВРег("%Номенклатура%"),"%"+ВидСправочника+"%"); // упрощенно, перечнь где работает
	
	Если поз = 0
	Тогда // разрешено смешивание
	Иначе // проверить запрет

	    МетаСпр = Метаданные.Справочник(ВидСправочника);
	    Если МетаСпр.КоличествоУровней>1 Тогда
	        Спр = СоздатьОбъект("Справочник."+ВидСправочника);
	        Если ПустоеЗначение(МетаСпр.Владелец.Выбран()) = 0 Тогда
	            Спр.ИспользоватьВладельца(Конт.Владелец);
	        КонецЕсли;
      	        Спр.ИспользоватьРодителя(Родитель);
	        Если Спр.ВыбратьЭлементы() = 1 Тогда
	            Если Спр.ПолучитьЭлемент(0) = 1 Тогда
			ЭтоЕстьГруппа = Конт.ЭтоГруппа();
	                Если Спр.ЭтоГруппа() <> ЭтоЕстьГруппа Тогда
						Сообщение1 = "Создание "+?(ЭтоЕстьГруппа=0,"элемента","группы");
						Предупреждение(Сообщение1+": ОТКАЗ
						|здесь разрешено создавать только "+?(ЭтоЕстьГруппа=0,"группы...","элементы..."),5);
						Результат = 0;
	                    СтатусВозврата(0);
	                    Возврат Результат;
	                КонецЕсли;
	            КонецЕсли;
	        КонецЕсли;
		КонецЕсли;   
	    //[*]_progadmin 2025-05-23 00:54 добавлено нетиповое

	КонецЕсли;
	
	Возврат Результат;
КонецФункции // глЗапретСмешенияГруппЭлементов()