Имя: Пароль:
1C
1С v8
Запрет записи любого документа или справочника
0 tatyana12
 
08.06.16
15:41
Подскажите пожалуйста, нужно через подписку на событие создать процедуру, которая при записи любого документа или справочника проверяла, есть ли у него(выбранного документа или справочника) хоть один реквизит с пометкой на удаление. Если есть - запретить запись. Заранее спасибо!)
1 sergeev-ag-1977
 
08.06.16
15:45
Событие ПередЗаписью
2 sergeev-ag-1977
 
08.06.16
15:47
Методологический вопрос: а что делать если ошибочно пометили на удаление? Как быть с пере-проведением ?
3 tatyana12
 
08.06.16
15:48
(1) Это понятно, я беру событие ПриЗаписи, я не могу понять как правильно нужно перебрать реквизиты из Источника?
4 FIXXXL
 
08.06.16
15:49
(3) через Метаданные
5 tatyana12
 
08.06.16
15:50
(4) Метаданные не содержат значения
6 FIXXXL
 
08.06.16
15:51
(4) в цикле получаете ИмяРеквизита, проверяете как
Источник[ИмяРеквизита].ПометкаУдаления

не забудьте проверить, что пометка есть у метаданного
7 Torquader
 
08.06.16
15:51
Можно ещё в сторону подписки на события посмотреть, чтобы для всех сразу.
Но, если в реквизите есть ссылка на объект, внутри которого тоже есть ссылка на другой объект, который также может быть помечен на удаление - это тоже нужно проверять ?
8 sergeev-ag-1977
 
08.06.16
15:51
СписокРеквизитов = Справочники.Номенклатура.НайтиПоКоду("").Метаданные().Реквизиты;
9 sergeev-ag-1977
 
08.06.16
15:52
Остается только обобщить
10 Torquader
 
08.06.16
15:52
(5) Через метаданные ты можешь узнать только какой тип значения может содержаться в реквизите, если это объект базы, то нужно будет у него проверять пометку удаления - то есть проверить, что ссылка не пустая, и что это не перечисление и выполнить запрос элемента с данными пометки удаления.
11 Torquader
 
08.06.16
15:53
(8) Тогда уж Метаданные.Справочники.Номенклатура.Реквизиты
12 В тылу врага
 
08.06.16
16:03
(5) метаданные содержат все реквизиты, их имена и типы значений
13 В тылу врага
 
08.06.16
16:04
+(12) вот реальный пример:

Процедура ЗаполнитьРеквизиты(Об,Ссылка)

    Мета = Об.Метаданные();
    
    Для каждого Реквизит Из Мета.Реквизиты Цикл
        ИмяРеквизита = Реквизит.Имя;
        Если Ссылка.Метаданные().Реквизиты.Найти(ИмяРеквизита)<>Неопределено Тогда
            Об[ИмяРеквизита] = ВыгрузитьДанные(Ссылка[ИмяРеквизита]);        
        КонецЕсли;     
    КонецЦикла;

КонецПроцедуры
14 xxTANATORxx
 
08.06.16
16:18
(6)лучше одним динамическим запросом
15 В тылу врага
 
08.06.16
16:21
+(14) что вы так боитесь объектов? там все данные есть уже
16 tatyana12
 
09.06.16
11:23
(9) (6) (11) (15) (14) Спасибо всем!
В совокупности всё получилось. Вот моя процедура)

Реквизиты = Источник.Метаданные().Реквизиты;
     Ии = 0;
     Для Ии = 0 По (Реквизиты.Количество()-1) Цикл         
         Если (Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Источник.Ссылка[Реквизиты[Ии].Имя]))
             Или Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Источник.Ссылка[Реквизиты[Ии].Имя])))
             И Источник.Ссылка[Реквизиты[Ии].Имя] <> Неопределено Тогда
             Если Источник.Ссылка[Реквизиты[Ии].Имя].ПометкаУдаления = ИСТИНА Тогда
                 ОбщегоНазначения.СообщитьОбОшибке("Значение """ + Реквизиты[Ии] + """ помечено на удаление!");
                 Отказ = ИСТИНА;
                 Возврат;
             КонецЕсли;
         КонецЕсли;
    КонецЦикла;
                                                                                    
    ТабличныеЧасти = Источник.Метаданные().ТабличныеЧасти;
    Ии = 0;
    Для Ии = 0 По (ТабличныеЧасти.Количество()-1) Цикл
        Для Каждого Строка ИЗ Источник[ТабличныеЧасти[Ии].Имя] Цикл
                РеквизитыТЧ = Источник.Метаданные().ТабличныеЧасти[Ии].Реквизиты;
                Ит = 0;                                                      
                Для Ит = 0 По (РеквизитыТЧ.Количество() - 1) Цикл                      
                    Если (Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Источник[Источник.Метаданные().ТабличныеЧасти[Ии].Имя][Строка.НомерСтроки-1][РеквизитыТЧ[Ит].Имя]))
                         Или Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Источник[Источник.Метаданные().ТабличныеЧасти[Ии].Имя][Строка.НомерСтроки-1][РеквизитыТЧ[Ит].Имя])))
                         И Источник[Источник.Метаданные().ТабличныеЧасти[Ии].Имя][Строка.НомерСтроки-1][РеквизитыТЧ[Ит].Имя] <> Неопределено  Тогда
                         Если Источник[Источник.Метаданные().ТабличныеЧасти[Ии].Имя][Строка.НомерСтроки-1][РеквизитыТЧ[Ит].Имя].ПометкаУдаления = ИСТИНА Тогда
                             ОбщегоНазначения.СообщитьОбОшибке("В табличной части " + ТабличныеЧасти[Ии].Имя + " в строке №" + Строка(Строка.НомерСтроки) +" значение реквизита """ + РеквизитыТЧ[Ит] + """ помечено на удаление!");
                             Отказ = ИСТИНА;
                             Возврат;
                         КонецЕсли;
                     КонецЕсли;
                 КонецЦикла;
        КонецЦикла;
    КонецЦикла;
17 xxTANATORxx
 
09.06.16
11:26
(15)в Объекте есть информация о пометке удаления реквизита?
(16)ты написал запрос(ы) в цикле, как это скажется на производительности?
18 tatyana12
 
09.06.16
11:28
(17) На производительность это никак не повлияло, замерили, проверили на большом документе) так что всё хорошо
19 xxTANATORxx
 
09.06.16
11:30
(18)ок, как повлияет на производительность системы в целом? при параллельной активной работе пользователей
20 Dmitrii
 
гуру
09.06.16
11:36
(18) >> На производительность это никак не повлияло

Врешь. Не может не повлиять. Хотя влияние и не сильно заметное.
На одном документе выявить влияние невозможно, но при перепроведении документов (закрытие месяца, например) это может вылиться в весьма ощутимую разницу.
21 tatyana12
 
09.06.16
11:36
(19) Согласна, вот это надо будет еще проверить
22 lodger
 
09.06.16
11:38
(16) если честно - когда-нибудь это место станет костью в горле. лучше на основании метаданных слепить запрос, который в 1 проход вернет истину или ложь.
p.s. классный ник, Тату )
23 EugeniaK
 
09.06.16
11:39
(18) Плохо меряли. На производительность это заметно влияет.
24 Dmitrii
 
гуру
09.06.16
11:42
(16) >> Источник.Ссылка[Реквизиты[Ии].Имя]

Это что?
А если документ или элемент справочника новый (только что создан)? У него не будет ссылки. Что вернёт твой код?
Правильно: Источник[Реквизиты[Ии].Имя]
Еще момент. Я бы предварительно проверял на заполненность:
Если ЗначениеЗаполнено(Источник[Реквизиты[Ии].Имя])

А вообще правы коллеги - правильнее написать запрос.
25 tatyana12
 
09.06.16
11:48
(24) ПриЗаписи нового документа ссылка уже существует
26 xxTANATORxx
 
09.06.16
11:55
(25)это надо делать перед записью
+ учтите права и РЛСы всякие
AdBlock убивает бесплатный контент. 1Сергей