На днях прилетела интересная задачка от клиента. Как то так произошло (намеренно или случайно), что некоторые документы стали распроведенными. И теперь для того, чтобы их вычислить нужно сравнить 2 версии документа. Последнюю и предпоследнюю. Текущую и предыдущую. Кому как нравиться 🙂
Начнем с того, что в БСП есть механизм версионирования объектов. Который хранит версии документов в регистре «ВерсииОбъектов». Но сравнить простым запросом данные мы не можем, так как разработчики этой подсистемы решили хранить данные в хранилище значений в формате XML. Что в общем то логично, так как структура данных может поменяться.
Ну ок. Должны же быть какие то готовые методы, чтобы получить реквизиты документа по номеру версии.
В БСП версии 3.1.3.561 мы можем обратиться к функции ВерсионированиеОбъектов.РазборВерсии(Ссылка, НомерВерсии) и получить значения реквизитов и другую служебную информацию.
Ну например:
ИнформацияОВерсии = ВерсионированиеОбъектов.РазборВерсии(ДокументСсылка, НомерВерсииЧисло);
Контрагент = ИнформацияОВерсии.Реквизиты.Найти("Контрагент", "НаименованиеРеквизита").ЗначениеРеквизита;
Передав ссылку и номер версии, мы уже получили контрагента. Но давайте вернемся к задаче сравнения двух последних версий документа.
Маленький дисклеймер. Качество кода фуфло, оптимальностью даже и не пахнет, делал на для решения одноразовой проблемы клиента.
&НаКлиенте
Процедура Сделать(Команда)
ТабДок = СделатьНаСервере();
ТабДок.ТолькоПросмотр = Истина;
ТабДок.Показать();
КонецПроцедуры
&НаСервере
Функция ПолучитьМакетНаСервере()
ОтчетОбъект = РеквизитФормыВЗначение("Объект");
Макет = ОтчетОбъект.ПолучитьМакет("Макет");
Возврат Макет;
КонецФункции
&НаСервере
Функция СделатьНаСервере()
ТабДок = Новый ТабличныйДокумент;
МассивПодозрительныхДокументов = ПолучитьПодозрительныеДокументыНаСервере();
Если МассивПодозрительныхДокументов.Количество() = 0 Тогда
Возврат ТабДок;
КонецЕсли;
Макет = ПолучитьМакетНаСервере();
ОбластьСтроки = Макет.ПолучитьОбласть("Строка");
Для каждого Документ Из МассивПодозрительныхДокументов Цикл
ОбластьСтроки.Параметры.Документ = Документ;
ОбластьСтроки.Параметры.ДокументСсылка = Документ;
ТабДок.Вывести(ОбластьСтроки);
КонецЦикла;
Возврат ТабДок;
КонецФункции
&НаСервере
Функция ПолучитьПодозрительныеДокументыНаСервере()
// Получили все непроведённые документы и непомеченные документы и соединили с
// версиями объектов
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровУслуг.Ссылка КАК Ссылка
|ПОМЕСТИТЬ ВТ_Реализации
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
| И РеализацияТоваровУслуг.Проведен = ЛОЖЬ
| И РеализацияТоваровУслуг.ПометкаУдаления = ЛОЖЬ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВерсииОбъектов.Объект КАК Объект,
| ВерсииОбъектов.НомерВерсии КАК НомерВерсии
|ИЗ
| РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов
|ГДЕ
| ВерсииОбъектов.Объект В
| (ВЫБРАТЬ
| ВТ_Реализации.Ссылка КАК Ссылка
| ИЗ
| ВТ_Реализации КАК ВТ_Реализации)
|
|УПОРЯДОЧИТЬ ПО
| НомерВерсии УБЫВ
|ИТОГИ ПО
| Объект";
Запрос.УстановитьПараметр("ДатаНачала", Период.ДатаНачала);
Запрос.УстановитьПараметр("ДатаОкончания", Период.ДатаОкончания);
МассивПодозрительныхОбъектов = Новый Массив;
Выборка = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выборка.Следующий() Цикл
ВыборкаДетальныеЗаписи = Выборка.Выбрать();
МассивРеквизитовВерсийОбъекта = Новый Массив;
Счетчик = 0;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Если Счетчик = 2 Тогда
Прервать;
КонецЕсли;
МассивРеквизитовВерсийОбъекта.Добавить(ВерсионированиеОбъектов.РазборВерсии(ВыборкаДетальныеЗаписи.Объект, ВыборкаДетальныеЗаписи.НомерВерсии).Реквизиты);
Счетчик = Счетчик + 1;
КонецЦикла;
Если МассивРеквизитовВерсийОбъекта.Количество() > 1 Тогда
ЗначениеПоследнее = МассивРеквизитовВерсийОбъекта[0].Найти("Posted", "НаименованиеРеквизита").ЗначениеРеквизита;
ЗначениеПредПоследнее = МассивРеквизитовВерсийОбъекта[1].Найти("Posted", "НаименованиеРеквизита").ЗначениеРеквизита;
Если ЗначениеПоследнее <> ЗначениеПредПоследнее Тогда
МассивПодозрительныхОбъектов.Добавить(Выборка.Объект);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат МассивПодозрительныхОбъектов;
КонецФункции
Posted — английский вариант слова Проведен.
Ну вот и всё. Получили значения реквизитов, сравнили между собой и вывели в табличный документ. Если нужно модифицировать, то за основу можете взять мою обработку.
