Как отследить пометку на удаление 1с
Многие, наверное, сталкивались с тем, что пользователь в форме списка помечает или снимает "пометку на удаление", а вам нужно отловить, подтвердил он или отказался от ее установки. И в связи с этим вам нужно выполнить некоторые действия, в моем случае снять или поставить пометку на подчиненые документы. Рассказываю, как этого добился я, может, кому пригодится.
Для реализации этого нужно проделать слдующее:
В любом из общих модулей вставляем процедуру:
Процедура глОбработкаОповещения ( Событие , Параметр , Источник ) Экспорт
Если Событие = «ПоставитьСнятьПометкуУдаления» Тогда
Если Источник <> Неопределено Тогда
ЕстьПодчиненныеДокументы = НайтиПодчиненныеДокументы ( Источник . Ссылка , ,НЕ Параметр );
Сообщить ( «Так же » + ?(НЕ Параметр , «сняты пометки удаления: « , «помечены на удаление: « ));
Для Каждого ТекСтрока Из ЕстьПодчиненныеДокументы Цикл
ДокументОбъект = ТекСтрока . Ключ . ПолучитьОбъект ();
ДокументОбъект . УстановитьПометкуУдаления (?( ТекСтрока . Ключ . ПометкаУдаления , Ложь, Истина));
Сообщить ( Строка ( ДокументОбъект ));
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
затем в форме списка документа создаем следующую процедуру:
Процедура ДокументСписокПередУстановкойПометкиУдаления ( Элемент , Отказ )
Если Не Отказ Тогда
ТекущаяСсылка = ЭлементыФормы . ДокументСписок . ТекущиеДанные . Ссылка ;
// отлавливаем установку пометки удаления на док. по ОУ из формы списка документа
// т.к. автоматически ставить пометку на удаление надо только для ОН, то соответственно ограничим вид документа.
//
Если ТекущаяСсылка . ВидОперации = Перечисления . ВидыОперацииОбъектов . ОбъектыУчета Тогда
ПодключитьОбработчикОповещения ( «глОбработкаОповещения» );
КонецЕсли;
и в заключении, в модуле документа:
Процедура ПередЗаписью ( Отказ , РежимЗаписи , РежимПроведения )
// отлавливаем установку пометки удаления на док. по ОУ из формы списка документа
//
// Как работает:
//
// В форме списка вызывается подключение «ПодключитьОбработчикОповещения(«глОбработкаОповещения»);»,
// далее после при любом действии с документом не важно откуда он выполняется, из формы списка или из самого док. или из обработки
// мы всегда попадем сюда.
// Далее мы проверяем что происходит с док. и говорим что конфигурацию надо оповестить, тоесть в Общем модуле «ПараметрыОбъектов»
// вызывается «процедура глОбработкаОповещения(Событие, Параметр, Источник) Экспорт» в которой мы и обрабатываем нужные действия.
// . — Внимание . — После выполнения, необходимо обязательно «ОтключитьОбработчикОповещения(«глОбработкаОповещения»);» — чтобы он не выполнялся опять.
Если ЭтотОбъект . ВидОперации = Перечисления . ВидыОперацииОбъектов . ОбъектыУчета Тогда
Если РежимЗаписи = РежимЗаписиДокумента . Запись Тогда
// если док. просто перезаписывается, то сюда попадем в любом случае. Но это оповещение не сработает. т.к. он не подключено в форме списка.
// ЕСЛИ же оно сработало, значит кто-то накосячил, и после подключения «ПодключитьОбработчикОповещения(«глОбработкаОповещения»);» не отключил его.
Оповестить ( «ПоставитьСнятьПометкуУдаления» , ЭтотОбъект . ПометкаУдаления , ЭтотОбъект );
ОтключитьОбработчикОповещения ( «глОбработкаОповещения» );
КонецЕсли;
КонецЕсли;
Ну вот и все. Теперь если пользователь в форме списка на документе выбрал пункт контекстного меню «Установить пометку удаления» и на вопрос подтвеждения сказал «Да», то и у под чиненых док. тоже поставится пометка. Так же и с распроведением. Если на вопрос он сказал «Нет», то и подчиненые документы, обрабатываться не будут.
Хочу отловить пометку удаления из формы документа. В официальной методичке написано, что пометка удаления вызывает ПередЗаписью() и ПриЗаписи(). Видимо методичка устарела, у меня ПередЗаписью() не вызывается, ПриЗаписи() - вообще нету. ОбработкаОповещения() тоже не вызывается. Короче, при пометке удаления вообще ничего не происходит. Кто сталкивался?
Эти события вызываются не в модуле формы, а в модуле объекта.
А для чего вам это надо? Возможно придется стандартную команду заглушить и написать свою.
Нет методичка не изменилась. Модифицированность формы не изменяется, потому и ни чего не происходит приЗаписи.
Зато срабатывает ПриЧтенииНаСервере
Как вариант можно:
1. Добавить на форму переменную ИзмениласьПометкаНаУдаление типа булево.
2. Добавить на клиенте Обработку ожидания, которое проверяет значение этой переменной на Истина, отправлять Оповещение и ставит значение Ложь этой переменной.
3. Если и правда срабатывает событие ПриЧтенииНаСервере как говорит (4), то устанавливать в этой процедуре значение переменной формы ИзмениласьПометкаНаУдаление в Истина.
(5) Stackmann, ну тогда уж можно просто поставить обработчик ожидания, который раз в секунду будет проверять не помечен ли документ на удаление и если помечен, то посылать оповещение. но как-то это не элегантно..
(7) то что вы предлагаете - это некорректно с точки зрения программирования под управляемые формы. В вашем случае сервер будет вызываться каждый раз, как только срабатывает обработчик ожидания. Я же предложил более рациональный способ. Сервер лишний раз не вызовется совсем.
(9) Stackmann, зачем будет вызываться сервер? Обработчик ожидания выполняется на клиенте, а в нем код
(4) tusv, на сервере не работает Оповестить(). Видимо это невозможно. во всяком случае в типовых конфигурациях оповещение об изменении документа отправляется только из ПослеЗаписи(). А пометка удаления остается незамеченной.
А с чего вы решили, что свойство ПометкаУдаления у реквизита формы Объект само обновится из базы данных? Вы это проверяли? IMHO там будет старое значение. которое было до открытия формы.
(12) Stackmann, а почему вы сами не проверили прежде чем давать вредные советы по беспричинному усложнению кода?
1) запустите Таймер()
2) Еще (Все действия) > Пометить на удаление/Снять пометку
3) наслаждайтесь своей неправотой
(13) Это замечательно, что реквизит обновляется, а код упрощается. Не понимаю. что вам еще не хватает. Юзайте и наслаждайтесь. Тем более вариантов более вам не предложили.
Если внимательней посмотреть на мои посты, то ничего я в них не утверждал. Я лишь приводил свое мнение, основанное на опыте. Однако всех мелочей не упомнить. У вас под рукой ваша задача, у меня этого нет - вам легче это проверить, чем мне.
(16) Stackmann, на самом деле вы правы. Мой вариант будет постоянно дёргать обработку оповещения, а уж она-то точно будет обращаться к серверу.
Посмотрите как работает реквизит формы "СостояниеДокумента" в БП 3.0 - там не токо пометка, но проведение или ручная корректировка и пр. отображаются на форме.
(14) Alex_E, не катит. Там вся цепочка вызовов выполняется на сервере начиная с
ищу негодяя - кто пометил весь спр. физ лица на удаление. Через Журнал регистрации не нашел. в отборе поставил фильтр на "Данные"-"Удаление".
Что я делаю не так?
ну да. согласен. изменения были зафиксированы, их я нашел, но вот как доказать что это именно пометка на удаление? там об этом не написано.
(5) Восстановить из резервной копии на момент до этого изменения, посмотреть на пометку. Если ее нет, и в ЖР события Изменения только от одного пользователя - значит он)
Если "весь спр. физ лица" то будет на каждом элементе.
А вообще ты подумай, может сам написал г*вно код который метит на удаление, вот он и на метил! (встречал такое!)
(9) . паяешь машину времени, возвращаешься назад и настраиваешь каждодневные бекапы?
(10) (15) пользователь сделает корочьи глаза и скажет - я ни чо не это, аносамо. Следствие зайдет в тупик - проходили неоднократно
(0) Да то же с удивлением узнал что 1С убрал из журнала регистрации логирование такого полезного дествия.
А то пометили, а ты потом удалил если ссылок на объект нет и ппц. Кто чо ищи потом ветра в поле.
Чует моё сердце, что _весь_справочник пометить на удаление - не руками сделано. А стало быть, либо какая обработка была написана, либо "Обработка справочников и документов" была сделана. Что касается самописной обработки - это к автору. А вот насчёт штатной - выполнение обработки журнал не фиксирует. Но вот изменения по всему справочнику от одного пользователя - как бы намекают.
(19) Может у них весь справочник в одной группе - тогда достаточно группу на удаление поменить - вот и весь справочник :)
(20) у рядовых пользюков, у которых ни мозгов, ни ответственности, не должно быть прав на пометку удаления
(21) Тогда в журнале будет "изменение" для той самой верхней группы. И этого изменившего - брать за жабры и иные деликатные места.
(24) по всем записям будет событие (кроме тех, которые уже были помечены) + по всем подчиненным справочникам.
Но за жабры однозначно :)
(25) А тут (если все - в одной группе) все записи смотреть не надо. Отфильтровать по головной группе - и того за жабры.
(0) > кто пометил весь спр. физ лица на удаление
Нефиг разрешать юзверю множественное выделение в списках
(31) Что-то потерял нить той дискуссии, если не трудно, скинь, пожалуйста ссылку на тему. Давно это было, кажись
А по делу: в 1С есть возможно программно логгировать действия пользователя в журнале регистрации. Интреактивные действия с объектами конфигурации (открыти, сохранение, начало проведения. ) сохраняются автоматически. Никто не мешает натыкать своих записей
Пока был 1с-ником, все действия над БД отлавливал. Опасные обработки снабжал "ручными" записями в журнал регистрации. Ни одна бабушка не ушла ))
буквально на днях писал подписку на событие ПередЗаписью, которое срет в журнал регистрации при пометке на удаление/снятие пометки
Многие, наверное, сталкивались с тем, что пользователь в форме списка помечает или снимает "пометку на удаление", а вам нужно отловить, подтвердил он или отказался от ее установки. И в связи с этим вам нужно выполнить некоторые действия, в моем случае снять или поставить пометку на подчиненые документы. Рассказываю, как этого добился я, может, кому пригодится.
Для реализации этого нужно проделать слдующее:
В любом из общих модулей вставляем процедуру:
Процедура глОбработкаОповещения ( Событие , Параметр , Источник ) Экспорт
Если Событие = "ПоставитьСнятьПометкуУдаления" Тогда
Если Источник <> Неопределено Тогда
ЕстьПодчиненныеДокументы = НайтиПодчиненныеДокументы ( Источник . Ссылка , ,НЕ Параметр );
Сообщить ( "Так же " + ?(НЕ Параметр , "сняты пометки удаления: " , "помечены на удаление: " ));
Для Каждого ТекСтрока Из ЕстьПодчиненныеДокументы Цикл
ДокументОбъект = ТекСтрока . Ключ . ПолучитьОбъект ();
ДокументОбъект . УстановитьПометкуУдаления (?( ТекСтрока . Ключ . ПометкаУдаления , Ложь, Истина));
Сообщить ( Строка ( ДокументОбъект ));
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
затем в форме списка документа создаем следующую процедуру:
Процедура ДокументСписокПередУстановкойПометкиУдаления ( Элемент , Отказ )
Если Не Отказ Тогда
ТекущаяСсылка = ЭлементыФормы . ДокументСписок . ТекущиеДанные . Ссылка ;
// отлавливаем установку пометки удаления на док. по ОУ из формы списка документа
// т.к. автоматически ставить пометку на удаление надо только для ОН, то соответственно ограничим вид документа.
//
Если ТекущаяСсылка . ВидОперации = Перечисления . ВидыОперацииОбъектов . ОбъектыУчета Тогда
ПодключитьОбработчикОповещения ( "глОбработкаОповещения" );
КонецЕсли;
и в заключении, в модуле документа:
Процедура ПередЗаписью ( Отказ , РежимЗаписи , РежимПроведения )
// отлавливаем установку пометки удаления на док. по ОУ из формы списка документа
//
// Как работает:
//
// В форме списка вызывается подключение "ПодключитьОбработчикОповещения("глОбработкаОповещения");",
// далее после при любом действии с документом не важно откуда он выполняется, из формы списка или из самого док. или из обработки
// мы всегда попадем сюда.
// Далее мы проверяем что происходит с док. и говорим что конфигурацию надо оповестить, тоесть в Общем модуле "ПараметрыОбъектов"
// вызывается "процедура глОбработкаОповещения(Событие, Параметр, Источник) Экспорт" в которой мы и обрабатываем нужные действия.
// . - Внимание . - После выполнения, необходимо обязательно "ОтключитьОбработчикОповещения("глОбработкаОповещения");" - чтобы он не выполнялся опять.
Если ЭтотОбъект . ВидОперации = Перечисления . ВидыОперацииОбъектов . ОбъектыУчета Тогда
Если РежимЗаписи = РежимЗаписиДокумента . Запись Тогда
// если док. просто перезаписывается, то сюда попадем в любом случае. Но это оповещение не сработает. т.к. он не подключено в форме списка.
// ЕСЛИ же оно сработало, значит кто-то накосячил, и после подключения "ПодключитьОбработчикОповещения("глОбработкаОповещения");" не отключил его.
Оповестить ( "ПоставитьСнятьПометкуУдаления" , ЭтотОбъект . ПометкаУдаления , ЭтотОбъект );
ОтключитьОбработчикОповещения ( "глОбработкаОповещения" );
КонецЕсли;
КонецЕсли;
Ну вот и все. Теперь если пользователь в форме списка на документе выбрал пункт контекстного меню "Установить пометку удаления" и на вопрос подтвеждения сказал "Да", то и у под чиненых док. тоже поставится пометка. Так же и с распроведением. Если на вопрос он сказал "Нет", то и подчиненые документы, обрабатываться не будут.
Не пойму, это для индексирования, или для понимания сотрудников, следующих программистов.
Почему нельзя было сделать ГДЕ НЕ ПометкаУдаления?
Для повышения читабельности так сделали?
(2) Думаю, что (1) прав. Не в делении на хороших и плохих, а в определении "правильности". Считаю, что если переменная уже типа "Булево", то сравнивать её с чем-либо не надо, т.к. это уже лишнее. Ну, вот смотри (пример):
Ты стоишь около автомата по приему мелочи. Автомат принимает только монеты номиналом 1 копейка (самая маленькая монета). Ты держишь в руках какую-нибудь монету и надо определить, это копейка или нет.
Вариант 1: Берем нашу монету, ложим её рядом с эталонной монетой (копейкой) и сравниваем. Если монеты одинаковые, то бросаем нашу монету в автомат.
Вариант 2: берем нашу монету и пытаемся скормить её автомату. Если автомат её захавал - то это была копейка.
Согласись, второй вариант проще. Ведь зачем нам сравнивать монету?
Здрастии Серафим, всё это не так булевская переменная имеет значнение ИСТИНА и при сравнении компилятор берет так
Учите матлогику.
(6) запрос 1с транслируется в SQL. И сколько будет операций сравнения в SQL для ГДЕ НЕ ПометкаУдаления
(6) А может всё-таки так:
1). ГДЕ ПометкаУдаления = Истина - 2 операции сравнения
.
ничего не так, а в скл по любому 1 операция потому что частичка НЕ возвращает ту же переменную только с обратным значением в нашем случае ЛОЖЬ, а передает ее 1с в язык скл уже в готовом виде.
где пометкаудаления=истина - 1 операция так как где пометкаудаления и пометкаудаления=истина - одно и тоже
для компилятора да, так как перед истина стоит еще оператор где, он вынужден его сравнивать в любом случае
он ведь берет переменную и в зависимости от ее значения ответвляет алгоритм, поэтому если даже чисто логически подумать ему приходится сравнивать
(13) А то что "Истина = Истина" это уже операция сама по себе, это ничего да?
По этой логике "1 = 1" и "1 = 2 + 3 - 4" одно и тоже и телодвижений в обоих случаях 1.
конечно это операция, операция сравнения, тоесть ты хочешь сказать что если не писать = истина, то компилятор тупо не сравнивает? если не сравнивает как машина будет производить дальнейшие действия по условию?
(17) В случае "ГДЕ ПометкаУдаления" компилятор сравнивает переменную со значением ИСТИНА - 1 операция.
В случае "ГДЕ ПометкаУдаления = ИСТИНА" компилятор сравнивает результат операции (которую тоже нужно вычислять) со значением ИСТИНА - 2 операции.
P.S. Что, так сложно писать номер поста, на который отвечаешь?
Прости Куб, я просто незнаю где ставить это чтоб помечалось.
Так какой операции? Присваивания тут нет, такое же сравнение. Это просто для удобочитаемости сделано.
(0) Никакой разницы нет как писать, оба варианта хорошие. Первый вариант нравится семеркоманам, второй семеркофобам. Зачем из мухи слона раздувать? Ничего плохого нет в том что программист так написал, просто ему так нравится.
Некоторые бывает пробелы не ставят вокруг арифметических знаков и скобок, их же за это никто не осуждает.
Ты еще такты проца посчитай.
пометкаудаления может null быть в случае если запрос так построен. Я не помню что будет если ГДЕ NULL. Может программист таким образом хотел сказать, что "левоприсоединяемый элемент справочника для данной строки и существует и не помечен на удаление"
Читайте также: