Структура справочников 1С crm

Ведение лога изменений документов: структура справочников   

 

Очень часто бывает необходимо вести логи изменения документов. Кто когда и что правил в документе? С какого компьютера и т.д. Я много раз сталкивался с такой необходимостью, и, в результате был создан почти универсальный алгоритм.

Принцип его работы предельно простой: при открытии документа в предопределенной процедуре организовывается вызов процедуры глобального модуля, в котором делается сохранение всех необходимых реквизитов документа в список значений. Необходимые реквизиты – это все реквизиты шапки и итоги по итоговым реквизитам табличной части. Я считаю, что этого достаточно.

После того, как документ был открыт – при записи или при проведении устанавливается флаг.

Далее в предопределенной процедуре при закрытии формы документа анализируется необходимость сравнения – и осуществляется вызов процедуры глобального модуля для сравнения документов. При наличии расхождений – пишется лог.

Лог представлен в виде трех справочников: Лог (в него заносятся документы), История (подчиненный справочник: в него заносится кто и когда правил), Запись (подчиненный справочник: хранит сами изменения).

Для просмотра лога предназначена специальная обработка, которая приводит лог в удобочитаемый вид: используются три таблицы значений на форме диалога.

Теперь рассмотрим непосредственно все вышеперечисленые моменты.

Для начала – структура справочников:

 

Структура справочников

 

А теперь я приведу кусок описания структуры метаданных, который касается этих справочников (для краткости ненужные свойства вырезаны):

	- Справочник
		- Идентификатор	"Лог"
		- Синоним
		- Комментарий	"Изменяемые документы"
		- Владелец
		- КоличествоУровней	"1"
		- ДлинаКода	"0"
		- ДлинаНаименования	"0"
		- СерииКодов	"ВПределахПодчинения"
		- ТипКода	"Текстовый"
		- ОсновноеПредставление	"ВВидеНаименования"
		- КонтрольУникальности	"0"
		- АвтоНумерация	"1"
		- ГруппыВпереди	"1"
		- Реквизит
			- Идентификатор	"Док"
			- Синоним
			- Комментарий	"Документ"
			- Тип	"Документ"
			- Вид
			- Длина	"0"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"1"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
		- Реквизит
			- Идентификатор	"НомерДок"
			- Синоним
			- Комментарий
			- Тип	"Число"
			- Вид
			- Длина	"6"
			- Точность	"0"
			- НеОтрицательный	"1"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
		- Реквизит
			- Идентификатор	"ДатаДок"
			- Синоним
			- Комментарий
			- Тип	"Дата"
			- Вид
			- Длина	"0"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
		- Реквизит
			- Идентификатор	"ВремяДок"
			- Синоним
			- Комментарий
			- Тип	"Строка"
			- Вид
			- Длина	"10"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
		- Реквизит
			- Идентификатор	"ВидДок"
			- Синоним
			- Комментарий
			- Тип	"Строка"
			- Вид
			- Длина	"30"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
		- Реквизит
			- Идентификатор	"Автор"
			- Синоним
			- Комментарий
			- Тип	"Справочник"
			- Вид	"Пользователи"
			- Длина	"0"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
		- Реквизит
			- Идентификатор	"Удален"
			- Синоним
			- Комментарий
			- Тип	"Число"
			- Вид
			- Длина	"1"
			- Точность	"0"
			- НеОтрицательный	"1"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
	- Справочник
		- Идентификатор	"История"
		- Синоним
		- Комментарий
		- Владелец	"Справочник.Лог"
		- КоличествоУровней	"1"
		- ДлинаКода	"6"
		- ДлинаНаименования	"0"
		- СерииКодов	"ВПределахПодчинения"
		- ТипКода	"Числовой"
		- ОсновноеПредставление	"ВВидеКода"
		- КонтрольУникальности	"1"
		- АвтоНумерация	"2"
		- ГруппыВпереди	"1"
		- Реквизит
			- Идентификатор	"ДатаПравки"
			- Синоним
			- Комментарий
			- Тип	"Дата"
			- Вид
			- Длина	"0"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
		- Реквизит
			- Идентификатор	"ВремяПравки"
			- Синоним
			- Комментарий
			- Тип	"Строка"
			- Вид
			- Длина	"10"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
		- Реквизит
			- Идентификатор	"АвторИзменений"
			- Синоним
			- Комментарий
			- Тип	"Справочник"
			- Вид	"Пользователи"
			- Длина	"0"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
		- Реквизит
			- Идентификатор	"ПК"
			- Синоним
			- Комментарий
			- Тип	"Строка"
			- Вид
			- Длина	"30"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
		- Реквизит
			- Идентификатор	"Права"
			- Синоним
			- Комментарий
			- Тип	"Строка"
			- Вид
			- Длина	"30"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
	- Справочник
		- Идентификатор	"Запись"
		- Синоним
		- Комментарий
		- Владелец	"Справочник.История"
		- КоличествоУровней	"1"
		- ДлинаКода	"0"
		- ДлинаНаименования	"0"
		- СерииКодов	"ВПределахПодчинения"
		- ТипКода	"Числовой"
		- ОсновноеПредставление	"ВВидеКода"
		- КонтрольУникальности	"1"
		- АвтоНумерация	"2"
		- ГруппыВпереди	"1"
		- Реквизит
			- Идентификатор	"Показатель"
			- Синоним
			- Комментарий
			- Тип	"Строка"
			- Вид
			- Длина	"30"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
		- Реквизит
			- Идентификатор	"Было"
			- Синоним
			- Комментарий
			- Тип	"Строка"
			- Вид
			- Длина	"30"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"
		- Реквизит
			- Идентификатор	"Стало"
			- Синоним
			- Комментарий
			- Тип	"Строка"
			- Вид
			- Длина	"30"
			- Точность	"0"
			- НеОтрицательный	"0"
			- РазделятьТриады	"0"
			- Периодический	"0"
			- Сортировка	"0"
			- Отбор	"0"
			- РучноеИзменение	"1"
			- ИзменяетсяДокументами	"0"
			- Использование	"ДляЭлемента"

Теперь – глобальный модуль:
//Переменные
Перем ПроведенСейчас Экспорт;
Перем ЗаписанСейчас Экспорт;


Функция глЗапомнитьДокумент(Конт) Экспорт
    Перем СЗ;
    ТекВид=Конт.Вид();
    СЗ=СоздатьОбъект("СписокЗначений");
    СЗ.ДобавитьЗначение(Конт.ДатаДок,"ДатаДок");
    СЗ.ДобавитьЗначение(Конт.ПолучитьВремя(),"ВремяДок");
    //Добавлено для сравнения общих реквизитов документа
    Для к=1 по Метаданные.ОбщийРеквизитДокумента() Цикл
        ТекИд=Метаданные.ОбщийРеквизитДокумента(к).Идентификатор;
        ТекЗнач=Конт.ПолучитьАтрибут(ТекИд);
        СЗ.ДобавитьЗначение(ТекЗнач,ТекИд);
    КонецЦикла;
    //Конец добавления
    Для к=1 по Метаданные.Документ(ТекВид).РеквизитШапки() Цикл
        ТекИд=Метаданные.Документ(ТекВид).РеквизитШапки(к).Идентификатор;
        ТекЗнач=Конт.ПолучитьАтрибут(ТекИд);
        СЗ.ДобавитьЗначение(ТекЗнач,ТекИд);
    КонецЦикла;
    Для к=1 по Метаданные.Документ(ТекВид).РеквизитТабличнойЧасти() Цикл
        Если Метаданные.Документ(ТекВид).РеквизитТабличнойЧасти(к).ИтогПоКолонке=1 Тогда
            ТекИд=Метаданные.Документ(ТекВид).РеквизитТабличнойЧасти(к).Идентификатор;
            ТекЗнач=Конт.Итог(ТекИд);
            СЗ.ДобавитьЗначение(ТекЗнач,ТекИд);
        КонецЕсли;
    КонецЦикла;
    Возврат СЗ;
КонецФункции

Эта функция запоминает реквизиты документа в списке значений, который возвращается в вызывающий документ и хранится там в переменной до закрытия документа. Через метаданные перебираются все реквизиты шапки и реквизиты табличной части с итогами по колонке.

Процедура глСравнитьДокумент(Конт,СЗ) Экспорт
    Перем ТаблИзм;
    Перем СпрЛог, СпрИстория, СпрЗапись;
    ТекВид=Конт.Вид();
    ТаблИзм=СоздатьОбъект("ТаблицаЗначений");
    ТаблИзм.НоваяКолонка("Показатель","Строка",30);
    ТаблИзм.НоваяКолонка("Было","Строка",30);
    ТаблИзм.НоваяКолонка("Стало","Строка",30);
    //________________________________________________________/
    ТекЗнач=Конт.ДатаДок;
    ПрошлЗнач=СЗ.Получить("ДатаДок");
    Если ТекЗнач<>ПрошлЗнач Тогда
        ТаблИзм.НоваяСтрока();
        ТаблИзм.Показатель="Дата";
        ТаблИзм.Было=СокрЛП(Строка(ПрошлЗнач));
        ТаблИзм.Стало=СокрЛП(Строка(ТекЗнач));
    КонецЕсли;
    ТекЗнач=Конт.ПолучитьВремя();
    ПрошлЗнач=СЗ.Получить("ВремяДок");
    Если ТекЗнач<>ПрошлЗнач Тогда
        ТаблИзм.НоваяСтрока();
        ТаблИзм.Показатель="Время";
        ТаблИзм.Было=СокрЛП(Строка(ПрошлЗнач));
        ТаблИзм.Стало=СокрЛП(Строка(ТекЗнач));
    КонецЕсли;
    //Добавлено для сравнения общих реквизитов документа
    Для к=1 по Метаданные.ОбщийРеквизитДокумента() Цикл
        ТекИд=Метаданные.ОбщийРеквизитДокумента(к).Идентификатор;
        ТекЗнач=Конт.ПолучитьАтрибут(ТекИд);
        ПрошлЗнач=СЗ.Получить(ТекИд);
        Если ТекЗнач<>ПрошлЗнач Тогда
            ТаблИзм.НоваяСтрока();
            ТаблИзм.Показатель=СокрЛП(ТекИд);
            ТаблИзм.Было=СокрЛП(Строка(ПрошлЗнач));
            ТаблИзм.Стало=СокрЛП(Строка(ТекЗнач));
        КонецЕсли;
    КонецЦикла;
    //Конец добавления
    Для к=1 по Метаданные.Документ(ТекВид).РеквизитШапки() Цикл
        ТекИд=Метаданные.Документ(ТекВид).РеквизитШапки(к).Идентификатор;
        ТекЗнач=Конт.ПолучитьАтрибут(ТекИд);
        ПрошлЗнач=СЗ.Получить(ТекИд);
        Если ТекЗнач<>ПрошлЗнач Тогда
            ТаблИзм.НоваяСтрока();
            ТаблИзм.Показатель=СокрЛП(ТекИд);
            ТаблИзм.Было=СокрЛП(Строка(ПрошлЗнач));
            ТаблИзм.Стало=СокрЛП(Строка(ТекЗнач));
        КонецЕсли;
    КонецЦикла;
    Для к=1 по Метаданные.Документ(ТекВид).РеквизитТабличнойЧасти() Цикл
        Если Метаданные.Документ(ТекВид).РеквизитТабличнойЧасти(к).ИтогПоКолонке=1 Тогда
            ТекИд=Метаданные.Документ(ТекВид).РеквизитТабличнойЧасти(к).Идентификатор;
            ТекЗнач=Конт.Итог(ТекИд);
            ПрошлЗнач=СЗ.Получить(ТекИд);
            Если ТекЗнач<>ПрошлЗнач Тогда
                ТаблИзм.НоваяСтрока();
                ТаблИзм.Показатель=СокрЛП(ТекИд);
                ТаблИзм.Было=СокрЛП(Строка(ПрошлЗнач));
                ТаблИзм.Стало=СокрЛП(Строка(ТекЗнач));
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    Если ТаблИзм.КоличествоСтрок()>0 Тогда
        //есть изменения - запоминаем документ
        СпрЛог=СоздатьОбъект("Справочник.Лог");
        СпрИстория=СоздатьОбъект("Справочник.История");
        СпрЗапись=СоздатьОбъект("Справочник.Запись");
        НачатьТранзакцию();
        Если СпрЛог.НайтиПоРеквизиту("Док",Конт.ТекущийДокумент(),1)=0 Тогда
            СпрЛог.Новый();
            СпрЛог.Док=Конт.ТекущийДокумент();
            СпрЛог.НомерДок=Конт.НомерДок;
            СпрЛог.ДатаДок=Конт.ДатаДок;
            СпрЛог.ВремяДок=Конт.ПолучитьВремя();
            СпрЛог.ВидДок=Конт.Вид();
            СпрЛог.Автор=Конт.Автор;
            СпрЛог.Удален=0;
            СпрЛог.Записать();
        КонецЕсли;
        СпрИстория.ИспользоватьВладельца(СпрЛог.ТекущийЭлемент());
        СпрИстория.Новый();
        СпрИстория.ДатаПравки=ТекущаяДата();
        СпрИстория.ВремяПравки=ТекущееВремя();
        СпрИстория.АвторИзменений=глПользователь;
        СпрИстория.ПК=ИмяКомпьютера();
        СпрИстория.Права=НазваниеНабораПрав(1);
        СпрИстория.Владелец=СпрЛог.ТекущийЭлемент();
        СпрИстория.Записать();
        ТаблИзм.ВыбратьСтроки();
        СпрЗапись.ИспользоватьВладельца(СпрИстория.ТекущийЭлемент());
        Пока ТаблИзм.ПолучитьСтроку()=1 Цикл
            СпрЗапись.Новый();
            СпрЗапись.Владелец=СпрИстория.ТекущийЭлемент();
            СпрЗапись.Показатель=ТаблИзм.Показатель;
            СпрЗапись.Было=ТаблИзм.Было;
            СпрЗапись.Стало=ТаблИзм.Стало;
            СпрЗапись.Записать();
        КонецЦикла;
        ЗафиксироватьТранзакцию();
    КонецЕсли;
КонецПроцедуры

В вышеописанной процедуре происходит сравнение значений сохраненных при открытии документа с конечными значениями. Если найдены расхождения, осуществляется запись в лог-справочники.

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

При отмене проведения документа тоже заполняется лог. Туда просто пишется запись об отмене проведения. Это нужно для того, чтобы можно было отличить новый только что созданный документ, от документа, который уже был проведен. Для ранее проведенного документа будет вестись лог, для нового не будет – пока он не будет проведен.

Процедура ПриУдаленииДокумента(Конт,Режим)
    СпрЛог=СоздатьОбъект("Справочник.Лог");
    СпрИстория=СоздатьОбъект("Справочник.История");
    СпрЗапись=СоздатьОбъект("Справочник.Запись");
    НачатьТранзакцию();
    Если СпрЛог.НайтиПоРеквизиту("Док",Конт.ТекущийДокумент(),1)=0 Тогда
        СпрЛог.Новый();
        СпрЛог.Док=Конт.ТекущийДокумент();
        СпрЛог.НомерДок=Конт.НомерДок;
        СпрЛог.ДатаДок=Конт.ДатаДок;
        СпрЛог.ВремяДок=Конт.ПолучитьВремя();
        СпрЛог.ВидДок=Конт.Вид();
        СпрЛог.Автор=Конт.Автор;
        СпрЛог.Удален=0;
        СпрЛог.Записать();
    КонецЕсли;
    СпрИстория.ИспользоватьВладельца(СпрЛог.ТекущийЭлемент());
    СпрИстория.Новый();
    СпрИстория.ДатаПравки=ТекущаяДата();
    СпрИстория.ВремяПравки=ТекущееВремя();
    СпрИстория.АвторИзменений=глПользователь;
    СпрИстория.ПК=ИмяКомпьютера();
    СпрИстория.Права=НазваниеНабораПрав(1);
    СпрИстория.Владелец=СпрЛог.ТекущийЭлемент();
    СпрИстория.Записать();
    СпрЗапись.ИспользоватьВладельца(СпрИстория.ТекущийЭлемент());
    СпрЗапись.Новый();
    СпрЗапись.Владелец=СпрИстория.ТекущийЭлемент();
    Если Режим=0 Тогда
        //Пометка
        СпрЛог.Удален=1;
        СпрЗапись.Показатель="Помечен";
    Иначе
        //полное удаление
        СпрЛог.Док=ПолучитьПустоеЗначение("Документ");
        СпрЛог.Удален=2;
        СпрЗапись.Показатель="Удален";
    КонецЕсли;
    СпрЛог.Записать();
    СпрЗапись.Записать();
    ЗафиксироватьТранзакцию();
КонецПроцедуры

При пометке на удаление – просто пишется лог, при полном удалении – очищается поле типа «Документ», чтобы не шокировать пользователя при просмотре лога надписями типа «объект не найден».

Функция глВестиЛог(Конт) Экспорт
    Перем СпрЛог;
    //Эта функция определяет, проведен ли документ
    //если проведен - ведется лог

    Если Конт.Проведен()=1 Тогда
        Возврат 1;
    КонецЕсли;
    //документ может быть сделанным непроведенным. при этом он должен попасть в справочник.
    //ищем по справочнику
    СпрЛог=СоздатьОбъект("Справочник.Лог");
    Если СпрЛог.ВыбратьЭлементыПоРеквизиту("Док",Конт.ТекущийДокумент(),,)=1 Тогда
        //Такой же документ найден
        Возврат 1;
    КонецЕсли;
    Возврат 0;
КонецФункции

Вышеописанная функция делает проверку необходимости ведения лога. Ищется документ по реквизиту. Если найден – лог ведется, нет – не ведется.

Теперь, для того, чтобы все работало – необходимо добавить в каждый документ следующий код:

В модуль документа в процедуру «ОбработкаПроведения»:

ПроведенСейчас=1;

В модуль формы документа необходимо добавить переменные:

Перем СравниватьДокумент, ТекСписок;

В модуль формы документа необходимо добавить или подкорректировать следующие процедуры:

Процедура ПриОткрытии()
    ПроведенСейчас=0;
    ЗаписанСейчас=0;
    Если глВестиЛог(Контекст)=1 Тогда
        СравниватьДокумент=1;
        ТекСписок=глЗапомнитьДокумент(Контекст);
    Иначе
        СравниватьДокумент=0;
    КонецЕсли;
КонецПроцедуры

Процедура приЗаписи()
    ЗаписанСейчас=1;
КонецПроцедуры


Процедура ПриЗакрытии()
    Если ((ПроведенСейчас=1) Или (ЗаписанСейчас=1)) И (СравниватьДокумент=1) Тогда
        глСравнитьДокумент(Контекст,ТекСписок);
    КонецЕсли;
КонецПроцедуры

После корректировки всех документов мы имеем полностью работающий механизм ведения лога. При добавлении нового документа правке подлежит лишь модуль документа (одна строчка) и три предопределенные процедуры модуля формы документа.

Обработка для просмотра результатов – на следующей странице.

Теперь – обработка для чтения лога. В форму вставлен реквизит типа «текст», содержащий вызов функции «ОбрДвижения()». К кнопке «Начать просмотр» привязана процедура «Выполнить()». Форма представлена ниже:

 

Форма обработки.

 

Модуль формы:

Перем СпрЛог;
Перем СпрИстория;
Перем СпрЗапись;
Перем Строчка1, Строчка2;
Процедура ДвижениеПоИстории()
    Запись.УдалитьСтроки();
    СпрЗапись.ИспользоватьВладельца(История.Тек);
    Если СпрЗапись.ВыбратьЭлементы()=0 Тогда
        Возврат;
    КонецЕсли;
    Пока СпрЗапись.ПолучитьЭлемент()=1 Цикл
        Запись.НоваяСтрока();
        Запись.Показатель=СпрЗапись.Показатель;
        Запись.Было=СпрЗапись.Было;
        Запись.Стало=СпрЗапись.Стало;
    КонецЦикла;
КонецПроцедуры

Процедура ДвижениеПоДокументам()
    История.УдалитьСтроки();
    СпрИстория.ИспользоватьВладельца(Документы.Тек);
    Если СпрИстория.ВыбратьЭлементы()=0 Тогда
        Возврат;
    КонецЕсли;
    Пока СпрИстория.ПолучитьЭлемент()=1 Цикл
        История.НоваяСтрока();
        История.N=СпрИстория.Код;
        История.Дата=СпрИстория.ДатаПравки;
        История.Время=СпрИстория.ВремяПравки;
        История.Автор=СпрИстория.АвторИзменений;
        История.ПК=СпрИстория.ПК;
        История.НаборПрав=СпрИстория.Права;
        История.Тек=СпрИстория.ТекущийЭлемент();
    КонецЦикла;
    Если История.КоличествоСтрок()=0 Тогда
        возврат;
    КонецЕсли;
    История.ПолучитьСтрокуПоНомеру(1);
    ДвижениеПоИстории();
КонецПроцедуры

Процедура ЗаполнитьВсе()
    Форма.Документы.Видимость(0);
    Документы.УдалитьСтроки();
    СпрЛог.ВыбратьЭлементы();
    Пока СпрЛог.ПолучитьЭлемент()=1 Цикл
        Документы.НоваяСтрока();
        Документы.Документ=СпрЛог.Док;
        Документы.Номер=СпрЛог.НомерДок;
        Документы.Дата=СпрЛог.ДатаДок;
        Документы.Время=СпрЛог.ВремяДок;
        Документы.Вид=СпрЛог.ВидДок;
        Документы.Автор=СпрЛог.Автор;
        Если СпрЛог.Удален=0 Тогда
            Документы.Статус="Норма";
        ИначеЕсли СпрЛог.Удален=1 Тогда
            Документы.Статус="Пометка";
        ИначеЕсли СпрЛог.Удален=2 Тогда
            Документы.Статус="Удален";
        КонецЕсли;
        Документы.Тек=СпрЛог.ТекущийЭлемент();
    КонецЦикла;
    Форма.Документы.Видимость(1);
    Если Документы.КоличествоСтрок()=0 Тогда
        Возврат;
    КонецЕсли;
    Документы.ПолучитьСтрокуПоНомеру(1);
    ДвижениеПоДокументам();
КонецПроцедуры

Процедура ПриОткрытии()
    Документы.Очистить();
    История.Очистить();
    Запись.Очистить();
    Документы.НоваяКолонка("Документ","Документ",,,,41,,);
    Документы.НоваяКолонка("Номер","Число",6,,,9,,);
    Документы.НоваяКолонка("Дата","Дата",,,,11,,);
    Документы.НоваяКолонка("Время",,,,,11,,);
    Документы.НоваяКолонка("Вид",,,,,21,,);
    Документы.НоваяКолонка("Автор");
    Документы.НоваяКолонка("Статус",,,,,7,,);
    Документы.НоваяКолонка("Тек","Справочник.Лог");
    Документы.ВидимостьКолонки("Тек",0,);
    История.НоваяКолонка("N",,,,,6,,);
    История.НоваяКолонка("Дата",,,,,12,,);
    История.НоваяКолонка("Время",,,,,8,,);
    История.НоваяКолонка("Автор");
    История.НоваяКолонка("ПК");
    История.НоваяКолонка("НаборПрав");
    История.НоваяКолонка("Тек","Справочник.История");
    История.ВидимостьКолонки("Тек",0,);
    Запись.НоваяКолонка("Показатель");
    Запись.НоваяКолонка("Было");
    Запись.НоваяКолонка("Стало");
    СпрЛог=СоздатьОбъект("Справочник.Лог");
    СпрИстория=СоздатьОбъект("Справочник.История");
    СпрЗапись=СоздатьОбъект("Справочник.Запись");
КонецПроцедуры

Процедура Выполнить()
    ЗаполнитьВсе();
КонецПроцедуры

Функция ОбрДвижения()
    Если НЕ(Строчка1=Документы.ТекущаяСтрока()) Тогда
        ДвижениеПоДокументам();
    КонецЕсли;
    Если НЕ(Строчка2=История.ТекущаяСтрока()) Тогда
        ДвижениеПоИстории();
    КонецЕсли;
    Строчка1=Документы.ТекущаяСтрока();
    Строчка2=История.ТекущаяСтрока();
    Возврат "";
КонецФункции

 

Да, чуть не забыл – эту обработку можно загрузить в разделе “Скачать”.

 

 

Автор статьи: Антон Гусев

Взято с http://softpoint.ru/article_id52.htm