Реклама на этом месте
Форум 1С
Форум 1С
Программистам. Бухгалтерам. Администраторам. Пользователям
Задай вопрос - получи решение проблемы. Без троллинга и флуда.
12 Дек 2017, 03:28
МультиВход
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?
 
collapse

Автор Тема: История изменения таб. части документов  (Прочитано 2737 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн KKnD

  • *
  • Сообщений: 1
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2014-10-23
  • Сайт: 
  • Профессия: Ученик 1С
Всем доброго дня.
Понадобилось фиксировать изменения табличной части документа ЗаказПокупателя.
Покопался в интернете и нашел простенький код, но никак не могу с ним справиться:

хочу, что бы у меня фиксировалась история изменений табличный части «Товары» документа «ЗаказПокупателя»
Создаем справочник “История изменений”
Для начала создал элементарный справочник “ИсторияИзменений”:
 
Справочник история изменений
Реквизиты:
Объект – ДокументСсылка, СправочникСсылка (По этому объекту в элементе справочника будет хранится история)
Табличная часть – изменения:
(тут тип значения ДокументСсылка.ЗаказПокупателя)
ДатаЗаписи – Дата (дата и время записи изменения)
(просто тип  дата состав  дата и время?)
НазваниеТабличнойЧасти – Строка (длина 50, Название табличной части по которой требуется фиксировать изменения)
(Тут тип строка и назвать ее Товары?)
ТаблицаИзменений – Строка (длина неограничена, тут будет хранится наша таблица значений)
(Тут тип строка и назвать ее ТаблицаИзменений?)
Автор – Пользователь (кто сделал изменения)
(тут тип значения СправочникиСсылка.Пользователи?)

Справочник готов, теперь необходимо поработать с его модулем, а именно:
И во всех модулях(которые ниже) вместо:
ТабличнаяЧасть – так и должна остаться? Не меняю?
НазваниеТабличнойЧасти – ставлю Товары?
1. Создать процедуру, которая будет фиксировать изменения в элементе справочника
2. Создать функции для получения предыдущего состояния табличной части, функцию для проверки изменилась ли табличная часть или нет, функцию для записи изменений
3. Создать интерфейсную часть, то есть форму списка и форму элемента справочника
Весь код модуля объекта справочника “ИсторияИзменений” приведен ниже с комментариями. Смысл обработки будет заключаться в следующем: При записи объекта мы будем фиксировать табличную часть, преобразовывать ее в таблицу значений, преобразовывать таблицу значений в строку и хранить в справочнике.

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

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

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

//Функция сравнивает две строки, которые являются предыдущим и текущим значением ТабличнойЧасти документа
Функция ЕстьИзмененияВТаблицах(СтараяТаблица, НоваяТаблица)
Если ЗначениеВСтрокуВнутр(СтараяТаблица)=ЗначениеВСтрокуВнутр(НоваяТаблица) Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции

Фиксируем изменения, а именно записываем новую табличную часть документа в элемент справочника "ИсторияИзменений"
Функция ЗафиксироватьТаблицу(ТаблицаИзменений, НазваниеТабличнойЧасти) Экспорт
НоваяСтрока = Изменения.Добавить();
НоваяСтрока.ДатаЗаписи = ТекущаяДата();
НоваяСтрока.НазваниеТабличнойЧасти = НазваниеТабличнойЧасти;
НоваяСтрока.ТаблицаИзменений = ЗначениеВСтрокуВнутр(ТаблицаИзменений);
НоваяСтрока.Автор = ПараметрыСеанса.Пользователь;
Записать();
КонецФункции


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

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

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

//Функция сравнивает две строки, которые являются предыдущим и текущим значением ТабличнойЧасти документа
Функция ЕстьИзмененияВТаблицах(СтараяТаблица, НоваяТаблица)
Если ЗначениеВСтрокуВнутр(СтараяТаблица)=ЗначениеВСтрокуВнутр(НоваяТаблица) Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции

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

Запрос.Текст = ТекстЗапроса;
Запрос.Параметры.Вставить("ОбъектСсылка", ОбъектСсылка);

ТЗ = Запрос.Выполнить().Выгрузить();
Если ТЗ.Количество()>0 Тогда
СправочникИзменений = ТЗ.Получить(0).Ссылка;
СправочникИзменений = СправочникИзменений.ПолучитьОбъект();
Иначе
СправочникИзменений = Справочники.ИсторияИзменений.СоздатьЭлемент();
СправочникИзменений.Объект = ОбъектСсылка;
СправочникИзменений.Записать();
КонецЕсли;

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



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

Запрос.Текст = ТекстЗапроса;
Запрос.Параметры.Вставить("ОбъектСсылка", ОбъектСсылка);

ТЗ = Запрос.Выполнить().Выгрузить();
Если ТЗ.Количество()>0 Тогда
СправочникИзменений = ТЗ.Получить(0).Ссылка;
СправочникИзменений = СправочникИзменений.ПолучитьОбъект();
Иначе
СправочникИзменений = Справочники.ИсторияИзменений.СоздатьЭлемент();
СправочникИзменений.Объект = ОбъектСсылка;
СправочникИзменений.Записать();
КонецЕсли;

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

Иначе
ТЗРезНовая = ТаблицаНовоеЗначение.Скопировать();
ТЗРезНовая.Очистить();
ТЗРезСтарая = ТЗРезНовая.Скопировать();
КоличествоКолонок = ТЗРезНовая.Колонки.Количество();

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

КонецЦикла;
н=н+1;
КонецЦикла;
КонецЕсли;
КонецПроцедуры

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

ТаблицаСтароеЗначение = Неопределено;

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

Если ТипЗнч(ТаблицаСтароеЗначение) = Тип("ТаблицаЗначений") Тогда
ЭлементыФормы.ТаблицаСтароеЗначение.СоздатьКолонки();
КонецЕсли;
КонецЕсли;

АнализироватьТаблицы();
КонецПроцедуры



Процедура АнализироватьТаблицы()
Если (ТаблицаСтароеЗначение.Количество() = 0) или (ТаблицаНовоеЗначение.Количество() = 0) Тогда

Иначе
ТЗРезНовая = ТаблицаНовоеЗначение.Скопировать();
ТЗРезНовая.Очистить();
ТЗРезСтарая = ТЗРезНовая.Скопировать();
КоличествоКолонок = ТЗРезНовая.Колонки.Количество();

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

КонецЦикла;
н=н+1;
КонецЦикла;
КонецЕсли;
КонецПроцедуры

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

ТаблицаСтароеЗначение = Неопределено;

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

Если ТипЗнч(ТаблицаСтароеЗначение) = Тип("ТаблицаЗначений") Тогда
ЭлементыФормы.ТаблицаСтароеЗначение.СоздатьКолонки();
КонецЕсли;
КонецЕсли;

АнализироватьТаблицы();
КонецПроцедуры

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

КонецПопытки;
КонецПроцедуры


У меня соответственно не получается вставить верные реквизиты для функции "ЗафиксироватьИзмененияТабличнойЧасти".
Если кто-то может - заполните пожалуйста код или поделитесь ссылкой...


Оффлайн Luzer1C

  • ****
  • Сообщений: 411
  • РЕПУТАЦИЯ: 41
  • КПД: 10%
  • Регистрация: 2014-02-17
  • Сайт: 
  • Профессия: Программист 1С
Знаю, что в УПП есть "Версионирование". В остальных базах - не знаю. Лучше здесь использовать стандартный механизм через регистр сведений, а не справочник.
Помочь мне очень сложно. Но можно.
Помогаю просто так...
Матёрый разработчик УПП + Бит Финанс


Теги:
 

Заполнение табличной части документа табличной частью из другого документа

Автор PeaceownerРаздел Пользователям "1С - Предприятие 8"

Ответов: 1
Просмотров: 2528
Последний ответ 30 Ноя 2011, 07:10
от has
Как создать нескольких документов "расчет при увольнении" на основании кадрового документа "увольнение" как Отпуска

Автор cozuРаздел Пользователям "1С - Предприятие 8"

Ответов: 3
Просмотров: 3175
Последний ответ 21 Мар 2015, 20:24
от дфтын
В строке номер "1" табличной части "Состав набора": Не заполнено значение реквиз

Автор ХеляРаздел Пользователям "1С - Предприятие 8"

Ответов: 0
Просмотров: 6823
Последний ответ 18 Сен 2011, 16:07
от Хеля
В строке "1" табличной части "Состав набора": Не заполнено значение реквизитов Цена

Автор rusalkaРаздел Пользователям "1С - Предприятие 8"

Ответов: 0
Просмотров: 2425
Последний ответ 11 Апр 2014, 16:52
от rusalka
Не работает структура подчиненности документов "Требование-накладная" и "Передач

Автор sv_stas_svРаздел Конфигурирование, программирование в "1С - Предприятие 8"

Ответов: 0
Просмотров: 4092
Последний ответ 10 Мар 2011, 07:36
от sv_stas_sv

* Живое общение

Не устроил ответ?

Зарегистрируйся и задай свой вопрос. Живое общение приносит результат намного быстрее.


Зарегистрироваться

* Реклама

* Поиск

* Последние задачи на разработку (фриланс)

* Реклама

* Последние вакансии

* Топ 10 авторов за месяц

Геннадий ОбьГЭС Геннадий ОбьГЭС
166 Сообщений
ilyay ilyay
75 Сообщений
oleg-x
55 Сообщений
alex0402
46 Сообщений
andron81_81
42 Сообщений
AIFrame
36 Сообщений
MuI_I_Ika MuI_I_Ika
31 Сообщений
BuhRust
28 Сообщений
Golickoff Golickoff
28 Сообщений
Dima Dddd Dima Dddd
26 Сообщений

* Кто онлайн

  • Точка Гостей: 178
  • Точка Скрытых: 0
  • Точка Пользователей: 0

Нет пользователей онлайн.

* Облако тэгов

* Форум 1С с мобильного

* Инструменты

* Дополнительно

Поиск

 
SimplePortal 2.3.5 © 2008-2012, SimplePortal