Карта сайта
Обслуживание компьютеров, ремонт компьютеров, 1С предприятие, обслуживание серверов,создание сайтов, продвижение сайтов, доработка 1С предприятие
О компании | Статьи | 1C Предприятие | История изменнений справочника 1С

« Назад « На главную

История изменнений справочника 1С

Пост будет интересен, тем 1С специалистам, которые хотят знать кто и когда изменял документ, а именно его табличную часть. В один прекрасный день мне понадобилось сделать так, чтобы изменения в указанной табличной части фиксировались. Поэтому на скорую руку был написан универсальный механизм, позволяющий фиксировать изменения в табличной части любых документов.


В сети существует интересный продукт, предназначеный для фиксации изменений в программе «Бизнес-Плюс:Журнал изменений», который стоит на момент написания статьи 12 000 рублей. Любой уважающий себя 1С-ник должен для начала самостоятельно попробовать написать что то подобное 


Вы можете сказать, а чем меня не устраивает встроенный журнал регистрации, который по одному документу формируется 5 минут Этим и не устраивает. регистрация изменений в шапке документов, думаю, понятна каждому, а вот регистрация изменений в табличных частях различных документов немного сложнее. задача состояла в том, чтобы зафиксировать всю историю изменений в произвольной табличной части произвольного документа или справочника 1С версии 8.


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


Создаем справочник «История изменений»


Для начала создал элементарный справочник «ИсторияИзменений»:



Справочник история изменений

Справочник история изменений




Реквизиты:
Объект — ДокументСсылка, СправочникСсылка (По этому объекту в элементе справочника будет хранится история)


Табличная часть — изменения:
ДатаЗаписи — Дата (дата и время записи изменения)
НазваниеТабличнойЧасти — Строка (длина 50, Название табличной части по которой требуется фиксировать изменения)
ТаблицаИзменений — Строка (длина неограничена, тут будет хранится наша таблица значений)
Автор — Пользователь (кто сделал изменения)


Справочник готов, теперь необходимо поработать с его модулем, а именно:
1. Создать процедуру, которая будет фиксировать изменения в элементе справочника
2. Создать функции для получения предыдущего состояния табличной части, функцию для проверки изменилась ли табличная часть или нет, функцию для записи изменений
3. Создать интерфейсную часть, то есть форму списка и форму элемента справочника


Весь код модуля объекта справочника «ИсторияИзменений» приведен ниже с комментариями. Смысл обработки будет заключаться в следующем: При записи объекта мы будем фиксировать табличную часть, преобразовывать ее в таблицу значений, преобразовывать таблицу значений в строку и хранить в справочнике.




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



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


Код функции указанной ниже размещаем в любом общем модуле. именно эта функция будет вызываться из модуля формы любого документа или справочника, из процедуры «ПослеЗаписи» с требуемыми параметрами.




Процедура ЗафиксироватьИзмененияТабличнойЧасти(ТабличнаяЧасть, НазваниеТабличнойЧасти, ОбъектСсылка) Экспорт;
Если ТабличнаяЧасть.Количество()>0 Тогда
Запрос = Новый Запрос();
ТекстЗапроса = "ВЫБРАТЬ | ИсторияИзменений.Ссылка |ИЗ | Справочник.ИсторияИзменений КАК ИсторияИзменений |ГДЕ | ИсторияИзменений.Объект = &ОбъектСсылка";
 
Запрос.Текст = ТекстЗапроса;
Запрос.Параметры.Вставить("ОбъектСсылка", ОбъектСсылка);
 
ТЗ = Запрос.Выполнить().Выгрузить();
Если ТЗ.Количество()>0 Тогда
СправочникИзменений = ТЗ.Получить(0).Ссылка;
СправочникИзменений = СправочникИзменений.ПолучитьОбъект();
Иначе
СправочникИзменений = Справочники.ИсторияИзменений.СоздатьЭлемент();
СправочникИзменений.Объект = ОбъектСсылка;
СправочникИзменений.Записать();
КонецЕсли;
 
СправочникИзменений.ЗафиксироватьИзменения(ТабличнаяЧасть, НазваниеТабличнойЧасти, ОбъектСсылка);
КонецЕсли;
КонецПроцедуры



Создаем форму элемента справочника «История изменений»


Рисуем форму элемента:



История изменений 1С

История изменений 1С




Форма элемента справочника история изменений выглядит в начальном виде именно так. В поле старые значения будут показываться предыдущие значения, а в поле новые значения… ну вы догадались. В эти поля являются табличным полями с названиями соответственно «ТаблицаСтароеЗначение» и «ТаблицаНовоеЗначение».


А теперь код формы:




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



Вот и все. Теперь для фиксации изменений любой табличной части, любого документа или элемента справочника достаточно вставить функцию «ЗафиксироватьИзмененияТабличнойЧасти» с необходимыми параметрами.


Пример фиксации изменений табличной части для любого документа в котором есть табличная часть «Работы»:




Процедура ПослеЗаписи()
 
//тут какой-то код
 
Попытка
ЗафиксироватьИзмененияТабличнойЧасти(Работы, "Работы", ЭтотОбъект.Ссылка);
Исключение
 
КонецПопытки;
КонецПроцедуры



Этот код вставляется в процедуру модуля формы «ПослеЗаписи()» документа или элемента справочника как показано выше.
Для просмотра изменений в табличных частях документа — этого достаточно. На каждый объект будет создаваться один отдельный элемент справочника, в котором и хранятся изменения.

14 Сентябрь 2012 г.



метки:



Вверх

Подписаться на RSS

  • Новости
  • Статьи
  • Разделы статей

    Наши контакты

    +7 922 292-00-34

    +7(343)361-52-00

    Напишите нам через форму!!!

    Быстрая форма связи с нами

     
    Ваше имя?*
    Как с Вами связаться?*
    Опишите вопрос или сообщение*
    Введите код *


    Знаком (*) выделены обязательные поля.
    Каталог интернет ресурсов - ИнфоПитер
    1С Предприятие
    1С Предприятие

    Антивирусная защита, FireWall
    Антивирусная защита, FireWall

    Заправка Samsung/Xerox
    Заправка Samsung/Xerox

    Заправка картриджей Brother
    Заправка картриджей Brother

    Заправка картриджей Epson/Konica Minolta
    Заправка картриджей Epson/Konica Minolta

    Заправка картриджей HP/Canon black
    Заправка картриджей HP/Canon black

    Заправка картриджей HP/Canon color
    Заправка картриджей HP/Canon color

    Заправка картриджей Lexmark
    Заправка картриджей Lexmark

    Информационные услуги
    Информационные услуги

    Монтаж локальной сети
    Монтаж локальной сети

    Монтирование кабель каналов
    Монтирование кабель каналов

    Настройка внутреннего оборудования
    Настройка внутреннего оборудования

    Настройка работоспособности переферийного оборудования
    Настройка работоспособности переферийного оборудования

    Обслуживание компьютеров
    Обслуживание компьютеров

    Обслуживание серверов
    Обслуживание серверов

    Оптимизация веб сайтов
    Оптимизация веб сайтов

    Разовые услуги
    Разовые услуги

    Ремонт
    Ремонт

    Ремонт оргтехники
    Ремонт оргтехники

    Создание веб (WEB) сайтов
    Создание веб (WEB) сайтов


    упвап

    Юридические услуги
    Юридические услуги

    Наверх

    ООО "Бизнес Технологии"© 2010 г.

    Написать автору

    Карта сайта