Книга знаний

1С:Предприятие / v8 / Объекты конфигурации

v8: Проверка модифицированности объектов

Мои изыски по поводу "быстрого " способа докопаться до того , кто и когда менял документ.Автор статьи: Immortal | Редакторы: Гений 1С
Последняя редакция №3 от 27.04.07 | История
URL: http://kb.mista.ru/article.php?id=521

Некотрое время назад мне поставили задачу : пользователю нужно быстро узнать, кто редактировал документ(интерактивно, всякие плановые перепроведения и ночные обработчики не в счёт).
Мысли были следующие:
1.Конечно же журнал регистрации и соответственно, КонсольАнализаЖурналаРегистрации.epf -штука очень тормозная.
2. Ведение своего журнала изменений.
Вариантов было два(изначально)
1. Использовать свойство формы документа(справочника и т.д. ) Модифицированность  и метод самого объекта БД(речь опять же о документе либо элементе справочника) Модифицированность().
Этот способ не подошёл мне по некоторым причинам : свойство формы менятся во многих типовых документах в ПриОткрытии() ну и т.д.
Метод объекта не срабатывал во многих случаях потому что документ намеренно модифицировался.(это уже я сам постарался)
2. Итак, у меня остался ещё один вариант :
в ПередЗаписью() во всех  формах документов я поместил следующий код:
Если ЭтоНовый() тогда
       ЭтотОбъект.Автор = глТекущийПользователь;
ИначеЕсли ПроверитьМодифицированностьПередЗаписью(ЭтотОбъект) тогда
       ЭтотОбъект.Автор = глТекущийПользователь;        
КонецЕсли;    
//автор - естественно реквизит документа, есть у всех документов
сама функция ПроверитьМодифицированностьПередЗаписью(Объект) была размещена в одном из общих модулей :
Функция ПроверитьМодифицированностьПередЗаписью(ЭтотОбъект) Экспорт
    //проверка реквизитов
        Текст = "ВЫБРАТЬ
        | ";
        Для каждого Реквизит из ЭтотОбъект.Метаданные().Реквизиты    цикл
        Текст = Текст  + ЭтотОбъект.Метаданные().Имя + "." + Реквизит.Имя + ",
        | ";

        КонецЦикла;
        Текст = Текст + ЭтотОбъект.Метаданные().Имя + ".Номер,  
        | " + ЭтотОбъект.Метаданные().Имя + ".Дата
        | ";
        ////уберём запятую  
        //Текст = СтрЗаменить(Текст,Реквизит.Имя + ",",Реквизит.Имя);
        Текст =  Текст + " ИЗ  
        | Документ." +  ЭтотОбъект.Метаданные().Имя +  " КАК " +  ЭтотОбъект.Метаданные().Имя + "
        | ГДЕ " + ЭтотОбъект.Метаданные().Имя + ".Ссылка = &Ссылка";
        Запрос = Новый Запрос;
        Запрос.Текст = Текст;
        Запрос.УстановитьПараметр("Ссылка",ЭтотОбъект.Ссылка);
        ШапкаДокумента =   Запрос.Выполнить().Выгрузить();
        Для каждого РеквизитВКолонке из ШапкаДокумента.Колонки цикл
           Если ШапкаДокумента[0][РеквизитВКолонке.Имя] <> ЭтотОбъект[РеквизитВКолонке.Имя] тогда
           Возврат Истина;
           КонецЕсли;    
        КонецЦикла;
        //проверка табчастей
        Для каждого ТабЧасть из ЭтотОбъект.Метаданные().ТабличныеЧасти    цикл
           
        Запрос.Текст = "";
        Текст =  "ВЫБРАТЬ
        | ";
        Для каждого РеквизитТабЧасти из ТабЧасть.Реквизиты    цикл
        Текст = Текст  + ЭтотОбъект.Метаданные().Имя + "." + РеквизитТабЧасти.Имя + ",
        | ";
         КонецЦикла;
        //Текст = СтрЗаменить(Текст,РеквизитТабЧасти.Имя + ",",РеквизитТабЧасти.Имя);
        Текст =  Текст + ЭтотОбъект.Метаданные().Имя  + ".НомерСтроки
        | ИЗ  
        | Документ." +  ЭтотОбъект.Метаданные().Имя + "." + Табчасть.Имя +  " КАК " +  ЭтотОбъект.Метаданные().Имя + "
        | ГДЕ " + ЭтотОбъект.Метаданные().Имя + ".Ссылка = &Ссылка
        | УПОРЯДОЧИТЬ ПО
        | " + ЭтотОбъект.Метаданные().Имя + ".НомерСтроки";
        Запрос.Текст = Текст;
        Запрос.УстановитьПараметр("Ссылка",ЭтотОбъект.Ссылка);
         ТабЧастьДокумента = Запрос.Выполнить().Выбрать();
         КоличествоСтрокВБазе = Запрос.Выполнить().Выгрузить().Количество();
       Пока ТабЧастьДокумента.Следующий() цикл
            Если КоличествоСтрокВБазе <> ЭтотОбъект[ТабЧасть.Имя].Количество() тогда
           //проверим, иначе вернём сразу истина
           Возврат Истина;
       иначе
           
           Если ЭтотОбъект[ТабЧасть.Имя].Количество() > 0 тогда
           Для каждого РеквизитТабЧасти из ТабЧасть.Реквизиты цикл
               Если ТабЧастьДокумента[РеквизитТабЧасти.Имя] <> ЭтотОбъект[ТабЧасть.Имя][ТабЧастьДокумента.НомерСтроки-1][РеквизитТабЧасти.Имя] тогда
               Возврат Истина;
               КонецЕсли;    
           КонецЦикла;    
           Иначе
           Возврат Истина;    
           КонецЕсли;
       КонецЕсли;    
       КонецЦикла;      

       
       
        КонецЦикла; //по табчастям
       
   Возврат Ложь;
   
КонецФункции    

Вот собственно и всё. Конечно можно доработать эту функцию, чтобы она сохраняла внесённые изменения  куда-нибудь=)  
 


От Гения 1С: Ничто не ново под луной.
Более ранние вещи на эту тему здесь:
Книга знаний: v8: Парциальная регистрация изменений в базе данных
Книга знаний: v8: Функция сравнения двух объектов одного типа

Хотя следует отметить, что автор использует запрос вместо получить объект, хотя это не дает никаких преимуществ, т.к. все равно сравниваются все поля объекта + еще тратится время на компиляцию запроса по сравнению с ПолучитьОбъект().


Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика