Форум Кладовочки АЛьФ`а

Общие вопросы => 7.7 => Тема начата: Злоп от 20 мая 2025, 02:08

Название: [Регламенты] В справочнике запрет элементов и групп на одном уровне иерархии..?
Отправлено: Злоп от 20 мая 2025, 02:08
Хочется запретить смешивать на одном уровне иерархии справочника наличие одновременно и групп и элементов.
Как бы это сделать красиво/правильно/няшно с минимумом нагрузки на систему...?
Пока ограничится отлупом при интерактивном создании элементов/групп.
Работать и на файловой и на скульной чтобы форматобазонезависимо...
.
Какие могут быть варианты?
Название: Re: [Регламенты] В справочнике запрет элементов и групп на одном уровне иерархии..?
Отправлено: Харлампий Дымба от 21 мая 2025, 22:35
Для интерактивного запрета ввода "в диалоге" - универсальный код такой:
Процедура ВводНового()
    МетаСпр=Метаданные.Справочник(Вид());
    Если МетаСпр.КоличествоУровней>1 Тогда
        Спр=СоздатьОбъект("Справочник."+Вид());
        Если ПустоеЗначение(МетаСпр.Владелец)=0 Тогда
            Спр.ИспользоватьВладельца(Владелец);
        КонецЕсли;
        Если ПустоеЗначение(Родитель)=0 Тогда
            Спр.ИспользоватьРодителя(Родитель);
        КонецЕсли;
        Если Спр.ВыбратьЭлементы()=1 Тогда
            Если Спр.ПолучитьЭлемент(0)=1 Тогда
                Если Спр.ЭтоГруппа()<>ЭтоГруппа() Тогда
                    СтатусВозврата(0);
                    Возврат;
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;   
КонецПроцедуры   
Нагрузки там особой нет - если Спр.ВыбратьЭлементы() нагружает систему, то универсальные средства и не должны использоваться, тогда надо под конкретную задачу лепить.

Для запрета ввода "в списке" - наверное, нормального решения не существует.
Название: Re: [Регламенты] В справочнике запрет элементов и групп на одном уровне иерархии..?
Отправлено: Злоп от 22 мая 2025, 00:37
Ввод по строке - я от этого отказался, для "прикладных объектов" - ввод в диалоге.
Ввод по строке оставляю только в простейших классификаторах, где не предполагается никакой логики/ограничений при создании/редактировании групп/элементов.
Название: Re: [Регламенты] В справочнике запрет элементов и групп на одном уровне иерархии..?
Отправлено: Злоп от 22 мая 2025, 03:40
Цитата: Харлампий Дымба от 21 мая 2025, 22:35Для интерактивного запрета ввода "в диалоге" - универсальный код такой:

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

Скопипастил в копилку!
Название: Re: [Регламенты] В справочнике запрет элементов и групп на одном уровне иерархии..?
Отправлено: vladmenleo от 22 мая 2025, 12:04
Вот вариант с использованием 1с++
ТекстSQLЗапроса =    "
    |SELECT
    |        СправочникТовары.ID [Товар $Справочник.Товары]
    |FROM
    |        SC55 СправочникТовары WITH (NOLOCK)
    |WHERE
    |        СправочникТовары.PARENTID = :Родитель
    |AND
    |        СправочникТовары.ISFOLDER = (1 + :Группа)
    |";
   
    ODBCRecordSet = СоздатьОбъект("ODBCRecordSet");
    ODBCRecordSet.УстановитьТекстовыйПараметр("Родитель", Родитель);
    ODBCRecordSet.УстановитьТекстовыйПараметр("Группа", ЭтоГруппа());
   
    ТзОтчета = СоздатьОбъект("ТаблицаЗначений");
    ТзОтчета = ODBCRecordSet.ВыполнитьИнструкцию(ТекстSQLЗапроса);
   
    Если ТзОтчета.КоличествоСтрок() > 0 Тогда
        сообщить("Элементы и группы не могут создаваться на одном уровне иерархии", "i");
        СтатусВозврата(0);
        Возврат;
    КонецЕсли;
Название: Re: [Регламенты] В справочнике запрет элементов и групп на одном уровне иерархии..?
Отправлено: Харлампий Дымба от 23 мая 2025, 00:34
Цитата: vladmenleo от 22 мая 2025, 12:04Вот вариант с использованием 1с++
Да, наверняка гораздо быстрее будет. А ещё наверное, можно
 SELECT TOP (1) ?
Ну и для подчиненных справочников допилить

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



 
Название: Re: [Регламенты] В справочнике запрет элементов и групп на одном уровне иерархии..?
Отправлено: Злоп от 23 мая 2025, 01:31
Цитата: Харлампий Дымба от 23 мая 2025, 00:34Там тогда лучше бы сделать глобальной функцией, типа
так примерно и сделал. Про перенос групп помню, но делать пока не стал, сделал по твоей указивке, норм.

Еще скрипт набросал, для разноски элементов в автосоздаваемые группы. Разовая задачка, руками бы задолбались вычищать большой справочник от смеси элементов и групп
Название: Re: [Регламенты] В справочнике запрет элементов и групп на одном уровне иерархии..?
Отправлено: Злоп от 23 мая 2025, 22:54
В результате примерно вот так
отдельно используется СтатусВозврата(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 добавлено нетиповое

КонецЕсли;

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