Ошибка при обновлении КА 2.4

1. Эвелина 20.04.19 15:14 Сейчас в теме
Помогите, уважаемые программисты!
Обновила Конфигурацию КА 2.4 2_4_7_141 до 2_4_7_147. Вроде обновилась из конфы. Вспомнила, что забыла сделать копию базы. А когда запустила 1С обновление не прошло, выскочила ошибка: {ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(66)}: Ошибка при вызове метода контекста (Записать) Объект.Записать(); по причине: Значение "002087" поля "Код" не уникально. Откатить назад -невозможно. Как поправить програмно?
Я просто продвинутый пользователь. Эти вещи лечить не умею. Помогите плиз!
По теме из базы знаний
Ответы
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
2. VladimirB 16 20.04.19 15:36 Сейчас в теме
(1) В какой-то справочник пытается записаться новый элемент с кодом 002087
Чтобы точно знать - нужно узнать какого типа "Объект" . Можно узнать через отладчик. (Возможно это не ваш путь.)
Если есть предположение какой это справочник, тогда откройте его, найдите элемент с кодом "002087" и измените ему код.
Перезапустите программу.
5. ishelper 20.04.19 15:53 Сейчас в теме
(1)
Я просто продвинутый пользователь. Эти вещи лечить не умею. Помогите плиз!
Помогаю: позовите программиста, хотя бы непродвинутого, лишь бы Отладчиком пользоваться умел.
7. Эвелина 20.04.19 16:03 Сейчас в теме
(5) если сама не смогу - придется.. опустив голову признаться, что я лузер...и раскаяться))))
9. VladimirB 16 20.04.19 16:09 Сейчас в теме
(7) Войдите в конфигуратор
Найдите общие модули
Найдите модуль
ОбновлениеИнформационнойБазы
Покажите его здесь.
Просто такой конфы у меня нет.
11. Эвелина 20.04.19 16:19 Сейчас в теме
(9) [1C-CODE]#Область ПрограммныйИнтерфейс

////////////////////////////////////////////////////////////­////////////////////
// Процедуры и функции для использования в обработчиках обновления.
//

// Записывает изменения в переданном объекте.
// Для использования в обработчиках обновления.
//
// Параметры:
// Данные - Произвольный - объект, набор записей или менеджер константы, который
// необходимо записать.
// РегистрироватьНаУзлахПлановОбмена - Булево - включает регистрацию на узлах планов обмена при записи объекта.
// ВключитьБизнесЛогику - Булево - включает бизнес-логику при записи объекта.
//
Процедура ЗаписатьДанные(Знач Данные, Знач РегистрироватьНаУзлахПлановОбмена = Неопределено,
Знач ВключитьБизнесЛогику = Ложь) Экспорт

Данные.ОбменДанными.Загрузка = Не ВключитьБизнесЛогику;
Данные.ДополнительныеСвойства.Вставить("РегистрироватьНаУзлахПлановОбменаПриОбновленииИБ", РегистрироватьНаУзлахПлановОбмена);

Если РегистрироватьНаУзлахПлановОбмена = Неопределено
Или Не РегистрироватьНаУзлахПлановОбмена Тогда
Данные.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
КонецЕсли;

Данные.Записать();

ОтметитьВыполнениеОбработки(Данные);

КонецПроцедуры

// Записывает изменения в переданном объекте ссылочного типа.
// Для использования в обработчиках обновления.
//
// Параметры:
// Объект - Произвольный - записываемый объект ссылочного типа. Например, СправочникОбъект.
// РегистрироватьНаУзлахПлановОбмена - Булево - включает регистрацию на узлах планов обмена при записи объекта.
// ВключитьБизнесЛогику - Булево - включает бизнес-логику при записи объекта.
// ДокументРежимЗаписи - ДокументРежимЗаписи - имеет смысл только для данных типа ДокументОбъект - режим
// записи документа.
// Если параметр не передан, то документ записывается в режиме "Запись".
//
Процедура ЗаписатьОбъект(Знач Объект, Знач РегистрироватьНаУзлахПлановОбмена = Неопределено,
Знач ВключитьБизнесЛогику = Ложь, ДокументРежимЗаписи = Неопределено) Экспорт

Объект.ДополнительныеСвойства.Вставить("РегистрироватьНаУзлахПлановОбменаПриОбновленииИБ", РегистрироватьНаУзлахПлановОбмена);
Объект.ОбменДанными.Загрузка = Не ВключитьБизнесЛогику;

Если РегистрироватьНаУзлахПлановОбмена = Неопределено
Или Не РегистрироватьНаУзлахПлановОбмена
И Не Объект.ЭтоНовый() Тогда
Объект.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
КонецЕсли;

Если ДокументРежимЗаписи <> Неопределено Тогда
Если ТипЗнч(ДокументРежимЗаписи) <> Тип("РежимЗаписиДокумента") Тогда
ТекстИсключения = НСтр("ru = 'Неправильный тип параметра ДокументРежимЗаписи'");
ВызватьИсключение ТекстИсключения;
КонецЕсли;
Объект.ОбменДанными.Загрузка = Объект.ОбменДанными.Загрузка
И Не ДокументРежимЗаписи = РежимЗаписиДокумента.Проведение
И Не ДокументРежимЗаписи = РежимЗаписиДокумента.ОтменаПроведения;
Объект.Записать(ДокументРежимЗаписи);
Иначе
Объект.Записать();
КонецЕсли;

ОтметитьВыполнениеОбработки(Объект);

КонецПроцедуры

// Записывает изменения в переданном наборе записей.
// Для использования в обработчиках обновления.
//
// Параметры:
// НаборЗаписей - РегистрСведенийНаборЗаписей,
// РегистрНакопленияНаборЗаписей,
// РегистрБухгалтерииНаборЗаписей,
// РегистрРасчетаНаборЗаписей - набор записей, который необходимо записать.
// Замещать - Булево - Определяет режим замещения существующей записи в соответствии с
// текущими установками отбора. Истина - перед записью существующие записи будут удалены. Ложь - записи будут
// дописаны к уже существующим в информационной базе записям.
// РегистрироватьНаУзлахПлановОбмена - Булево - включает регистрацию на узлах планов обмена при записи объекта.
// ВключитьБизнесЛогику - Булево - включает бизнес-логику при записи объекта.
//
Процедура ЗаписатьНаборЗаписей(Знач НаборЗаписей, Замещать = Истина, Знач РегистрироватьНаУзлахПлановОбмена = Неопределено,
Знач ВключитьБизнесЛогику = Ложь) Экспорт

НаборЗаписей.ДополнительныеСвойства.Вставить("РегистрироватьНаУзлахПлановОбменаПриОбновленииИБ", РегистрироватьНаУзлахПлановОбмена);
НаборЗаписей.ОбменДанными.Загрузка = Не ВключитьБизнесЛогику;

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

НаборЗаписей.Записать(Замещать);

ОтметитьВыполнениеОбработки(НаборЗаписей);

КонецПроцедуры

// Удаляет переданный объект.
// Для использования в обработчиках обновления.
//
// Параметры:
// Данные - Произвольный - объект, который необходимо удалить.
// РегистрироватьНаУзлахПлановОбмена - Булево - включает регистрацию на узлах планов обмена при записи объекта.
// ВключитьБизнесЛогику - Булево - включает бизнес-логику при записи объекта.
//
Процедура УдалитьДанные(Знач Данные, Знач РегистрироватьНаУзлахПлановОбмена = Неопределено,
Знач ВключитьБизнесЛогику = Ложь) Экспорт

Данные.ДополнительныеСвойства.Вставить("РегистрироватьНаУзлахПлановОбменаПриОбновленииИБ", РегистрироватьНаУзлахПлановОбмена);

Данные.ОбменДанными.Загрузка = Не ВключитьБизнесЛогику;
Если РегистрироватьНаУзлахПлановОбмена = Неопределено
Или Не РегистрироватьНаУзлахПлановОбмена Тогда
Данные.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
КонецЕсли;

Данные.Удалить();

КонецПроцедуры

// Возвращает строковую константу для формирования сообщений журнала регистрации.
//
// Возвращаемое значение:
// Строка - текст события журнала регистрации.
//
Функция СобытиеЖурналаРегистрации() Экспорт

Возврат ОбновлениеИнформационнойБазыСлужебный.СобытиеЖурналаРегистрации();

КонецФункции

////////////////////////////////////////////////////////////­////////////////////
// Процедуры и функции для проверки доступности объекта при выполнении отложенного обновления.
//

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

Если Не ЭтоВызовИзОбработчикаОбновления() Тогда
Результат = ОбъектОбработан(Данные);
Если Результат.Обработан Тогда
Возврат;
КонецЕсли;

Если Форма = Неопределено Тогда
ВызватьИсключение Результат.ТекстИсключения;
КонецЕсли;

Форма.ТолькоПросмотр = Истина;
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Результат.ТекстИсключения);
Возврат;
КонецЕсли;

Если Не ЗначениеЗаполнено(ИмяОтложенногоОбработчика) Тогда
Возврат;
КонецЕсли;

Если ИмяОтложенногоОбработчика = ПараметрыСеанса.ПараметрыОбработчикаОбновления.ИмяОбработчика Тогда
Возврат;
КонецЕсли;

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

ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Недопустимо вызывать %1
|из обработчика обновления
|%2
|так как его номер очереди меньше или равен номеру очереди обработчика обновления
|%3'"),
ИмяПроцедурыПрограммногоИнтерфейса,
ПараметрыСеанса.ПараметрыОбработчикаОбновления.ИмяОбработчика,
ИмяОтложенногоОбработчика);

КонецПроцедуры

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

Результат = Новый Структура;
Результат.Вставить("Обработан", Истина);
Результат.Вставить("ТекстИсключения", "");
Результат.Вставить("НевыполненныеОбработчикиСтрокой", "");

Если Данные = Неопределено Тогда
Возврат Результат;
КонецЕсли;

Если ПолучитьФункциональнуюОпцию("ОтложенноеОбновлениеЗавершеноУспешно") Тогда

ЭтоПодчиненныйУзелРИБ = ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ();
Если Не ЭтоПодчиненныйУзелРИБ Тогда
Возврат Результат;
ИначеЕсли ПолучитьФункциональнуюОпцию("ОтложенноеОбновлениеВГлавномУзлеЗавершеноУспешно") Тогда
Возврат Результат;
КонецЕсли;

КонецЕсли;

СведенияОБлокируемыхОбъектах = ОбновлениеИнформационнойБазыСлужебный.СведенияОБлокируемыхОбъектах();

Если ТипЗнч(Данные) = Тип("Строка") Тогда
ПолноеИмя = Данные;
Иначе
МетаданныеИОтбор = МетаданныеИОтборПоДанным(Данные);
ПолноеИмя = МетаданныеИОтбор.Метаданные.ПолноеИмя();
КонецЕсли;

ПроверяемыйОбъект = СтрЗаменить(ПолноеИмя, ".", "");

ОбработчикиОбъекта = СведенияОБлокируемыхОбъектах.БлокируемыеОбъекты[ПроверяемыйОбъект];
Если ОбработчикиОбъекта = Неопределено Тогда
Возврат Результат;
КонецЕсли;

Обработан = Истина;
НезавершенныеОбработчики = Новый Массив;
Для Каждого Обработчик Из ОбработчикиОбъекта Цикл
СвойстваОбработчика = СведенияОБлокируемыхОбъектах.Обработчики[Обработчик];
Если СвойстваОбработчика.Выполнен Тогда
Обработан = Истина;
ИначеЕсли ТипЗнч(Данные) = Тип("Строка") Тогда
Обработан = Ложь;
Иначе
Обработан = ОбщегоНазначения.ВычислитьВБезопасномРежиме(
СвойстваОбработчика.ПроцедураПроверки + "(Параметры)", МетаданныеИОтбор);
КонецЕсли;

Результат.Обработан = Обработан И Результат.Обработан;

Если Не Обработан Тогда
НезавершенныеОбработчики.Добавить(Обработчик);
КонецЕсли;
КонецЦикла;

Если НезавершенныеОбработчики.Количество() > 0 Тогда
ТекстИсключения = НСтр("ru = 'Действия с объектом временно запрещены, так как не завершен переход на новую версию программы.
|Это плановый процесс, который скоро завершится.
|Остались следующие процедуры обработки данных:'");

НевыполненныеОбработчикиСтрокой = "";
Для Каждого НезавершенныйОбработчик Из НезавершенныеОбработчики Цикл
НевыполненныеОбработчикиСтрокой = НевыполненныеОбработчикиСтрокой + Символы.ПС + НезавершенныйОбработчик;
КонецЦикла;
Результат.ТекстИсключения = ТекстИсключения + НевыполненныеОбработчикиСтрокой;
Результат.НевыполненныеОбработчикиСтрокой = НевыполненныеОбработчикиСтрокой;
КонецЕсли;

Возврат Результат;

КонецФункции

////////////////////////////////////////////////////////////­////////////////////
// Процедуры и функции для использования в отложенных обработчиках обновления
// с режимом выполнения "Параллельно".
//

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

Если Не ПараметрыСеанса.ПараметрыОбработчикаОбновления.ЕстьОбработанныеОбъекты Тогда
НовыеПараметрыСеанса = ОбновлениеИнформационнойБазыСлужебный.НовыеПараметрыОбработчикаОбновления();

ЗаполнитьЗначенияСвойств(НовыеПараметрыСеанса, ПараметрыСеанса.ПараметрыОбработчикаОбновления);
НовыеПараметрыСеанса.ЕстьОбработанныеОбъекты = Истина;

ПараметрыСеанса.ПараметрыОбработчикаОбновления = Новый ФиксированнаяСтруктура(НовыеПараметрыСеанса);
КонецЕсли;

КопияДанных = Данные;
Если ДополнительныеПараметры = Неопределено Тогда
ДополнительныеПараметры = ДополнительныеПараметрыОтметкиОбработки();
КонецЕсли;

Если (ТипЗнч(Данные) = Тип("Массив")
Или ТипЗнч(Данные) = Тип("ТаблицаЗначений"))
И Данные.Количество() = 0 Тогда

ТекстИсключения = НСтр("ru = 'В процедуру ОбновлениеИнформационнойБазы.ОтметитьВыполнениеОбработки передан пустой массив. Не возможно отметить выполнение обработки.'");
ВызватьИсключение ТекстИсключения;

КонецЕсли;

Узел = ОчередьСсылкой(Очередь);

Если ДополнительныеПараметры.ЭтоДвижения Тогда

Набор = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ДополнительныеПараметры.ПолноеИмяРегистра).СоздатьНаборЗаписей();

Если ТипЗнч(Данные) = Тип("Массив") Тогда
Для Каждого СтрокаМассива Из Данные Цикл
Набор.Отбор.Регистратор.Установить(СтрокаМассива);
ПланыОбмена.УдалитьРегистрациюИзменений(Узел, Набор);
КонецЦикла;
Иначе
Набор.Отбор.Регистратор.Установить(Данные);
ПланыОбмена.УдалитьРегистрациюИзменений(Узел, Набор);
КонецЕсли;

ИначеЕсли ДополнительныеПараметры.ЭтоНезависимыйРегистрСведений Тогда

Набор = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ДополнительныеПараметры.ПолноеИмяРегистра).СоздатьНаборЗаписей();
МетаданныеОбъекта = Метаданные.НайтиПоПолномуИмени(ДополнительныеПараметры.ПолноеИмяРегистра);

УстановитьНедостающиеОтборыВНаборе(Набор, МетаданныеОбъекта, Данные);

Для каждого СтрокаТаблицы Из Данные Цикл
Для Каждого Колонка Из Данные.Колонки Цикл
Набор.Отбор[Колонка.Имя].Значение = СтрокаТаблицы[Колонка.Имя];
Набор.Отбор[Колонка.Имя].Использование = Истина;
КонецЦикла;

ПланыОбмена.УдалитьРегистрациюИзменений(Узел, Набор);
КонецЦикла;

Иначе
Если ТипЗнч(Данные) = Тип("ОбъектМетаданных") Тогда
ТекстИсключения = НСтр("ru = 'Не поддерживается отметка выполнения обработки обновления целиком объекта метаданных. Нужно отмечать обработку конкретных данных.'");
ВызватьИсключение ТекстИсключения;
КонецЕсли;

Если ТипЗнч(Данные) <> Тип("Массив") Тогда

ТипЗначенияОбъекта = ТипЗнч(Данные);
МетаданныеОбъекта = Метаданные.НайтиПоТипу(ТипЗначенияОбъекта);

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

Возврат;
Иначе
Набор = Данные;
КонецЕсли;

ПланыОбмена.УдалитьРегистрациюИзменений(Узел, Набор);
КопияДанных = Набор;
Иначе
Для Каждого ЭлементМассива Из Данные Цикл
ПланыОбмена.УдалитьРегистрациюИзменений(Узел, ЭлементМассива);
КонецЦикла;
КонецЕсли;

КонецЕсли;

Если Не ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Тогда
РегистрыСведений.ДанныеОбработанныеВЦентральномУзлеРИБ.ОтметитьВыполнениеОбработки(Очередь, КопияДанных, ДополнительныеПараметры);
КонецЕсли;

КонецПроцедуры

// Дополнительные параметры функций ОтметитьКОбработке и ОтметитьВыполнениеОбработки.
//
// Возвращаемое значение:
// Структура - структура со свойствами:
// * ЭтоДвижения - Булево - в параметре Данные функции переданы ссылки на регистраторы, по которым нужно обновить движения,
// Значение по умолчанию - ЛОЖЬ.
// * ПолноеИмяРегистра - Строка - полное имя регистра, по которому нужно обновить данные. Например, РегистрНакопления.ТоварыНаСкладах.
// * ОтметитьВсеРегистраторы - Булево - необходимо отметить к обработке все проведенные документы переданного во
// втором параметре типа.
// В этом случае в параметре Данные процедуры можно передавать
// ОбъектМетаданных:Документ или ДокументСсылка.
// * ЭтоНезависимыйРегистрСведений - Булево - в параметре Данные функции передана таблица со значениями измерений,
// по которым нужно обновлять данные, Значение по умолчанию - ЛОЖЬ.
//
Функция ДополнительныеПараметрыОтметкиОбработки() Экспорт

ДополнительныеПараметры = Новый Структура;
ДополнительныеПараметры.Вставить("ЭтоДвижения", Ложь);
ДополнительныеПараметры.Вставить("ОтметитьВсеРегистраторы", Ложь);
ДополнительныеПараметры.Вставить("ЭтоНезависимыйРегистрСведений", Ложь);
ДополнительныеПараметры.Вставить("ПолноеИмяРегистра", "");

Возврат ДополнительныеПараметры;

КонецФункции

// Основные параметры процедуры ОбновлениеИнформационнойБазы.ОтметитьКОбработке,
// которые инициализируются механизмом регистрации изменений
// и не должны переопределяться в коде процедур отметки к обработке обработчиков обновления.
//
// Возвращаемое значение:
// Структура - со свойствами:
// * Очередь - Число - очередь обработки, в которой выполняется текущий обработчик.
// * ЗаписьИзмененийДляПодчиненногоУзлаРИБСФильтрами - ЗаписьFastInfoset - параметр
// существует, только если внедрена подсистема ОбменДанными.
// * ПараметрыВыборки - Структура - см. ДополнительныеПараметрыВыборкиДанныхДляМногопоточнойОбработк­и().
//
Функция ОсновныеПараметрыОтметкиКОбработке() Экспорт

Параметры = Новый Структура;
Параметры.Вставить("Очередь", 0);
Параметры.Вставить("ПовторнаяРегистрация", Ложь);
Параметры.Вставить("ПараметрыВыборки");

Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными") Тогда

Параметры.Вставить("ИмяФайлаСИзменениями", Неопределено);
Параметры.Вставить("ЗаписьИзмененийДляПодчиненногоУзлаРИБСФильтрами", Неопределено);

КонецЕсли;

Возврат Параметры;

КонецФункции

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

Если ДополнительныеПараметры = Неопределено Тогда
ДополнительныеПараметры = ДополнительныеПараметрыОтметкиОбработки();
КонецЕсли;

Если ДополнительныеПараметры.ЭтоДвижения Тогда
МетаданныеОбъекта = Метаданные.НайтиПоПолномуИмени(ДополнительныеПараметры.ПолноеИмяРегистра);
Иначе
МетаданныеОбъекта = Неопределено;
КонецЕсли;

Отбор = Неопределено;
ТипДанных = ТипЗнч(Данные);
ЭтоНовый = Ложь;

Если ТипЗнч(Данные) = Тип("Строка") Тогда
МетаданныеОбъекта = Метаданные.НайтиПоПолномуИмени(Данные);
ИначеЕсли ТипДанных = Тип("ДанныеФормыСтруктура") Тогда

Если ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(Данные, "Ссылка") Тогда

Если МетаданныеОбъекта = Неопределено Тогда
МетаданныеОбъекта = Данные.Ссылка.Метаданные();
КонецЕсли;

Отбор = Данные.Ссылка;

Если Не ЗначениеЗаполнено(Отбор) Тогда
ЭтоНовый = Истина;
КонецЕсли;

ИначеЕсли ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(Данные, "ИсходныйКлючЗаписи") Тогда

Если МетаданныеОбъекта = Неопределено Тогда
МетаданныеОбъекта = Метаданные.НайтиПоТипу(ТипЗнч(Данные.ИсходныйКлючЗаписи));
КонецЕсли;
Отбор = Новый Структура;
Для Каждого Измерение Из МетаданныеОбъекта.Измерения Цикл
Отбор.Вставить(Измерение.Имя, Данные[Измерение.Имя]);
КонецЦикла;

Иначе
ТекстИсключения = НСтр("ru = 'Процедура ОбновлениеИнформационнойБазы.МетаданныеИОтборПоДанным не может быть использована для этой формы.'");
КонецЕсли;

Иначе

Если МетаданныеОбъекта = Неопределено Тогда
МетаданныеОбъекта = Данные.Метаданные();
КонецЕсли;

Если ОбщегоНазначения.ЭтоОбъектСсылочногоТипа(МетаданныеОбъекта) Тогда

Если ОбщегоНазначения.ЭтоСсылка(ТипДанных) Тогда
Отбор = Данные;
Иначе
Отбор = Данные.Ссылка;

Если Данные.ЭтоНовый() Тогда
ЭтоНовый = Истина;
КонецЕсли;

КонецЕсли;

ИначеЕсли ОбщегоНазначения.ЭтоРегистрСведений(МетаданныеОбъекта)
И МетаданныеОбъекта.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.Независимый Тогда

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

ИначеЕсли ОбщегоНазначения.ЭтоРегистр(МетаданныеОбъекта) Тогда
Если ДополнительныеПараметры.ЭтоДвижения Тогда
Отбор = Данные;
Иначе
Отбор = Данные.Отбор.Регистратор.Значение;
КонецЕсли;
Иначе
ТекстИсключения = НСтр("ru = 'Для этого типа метаданных не поддерживается анализ в функции ОбновлениеИнформационнойБазы.МетаданныеИОтборПоДанным.'");
ВызватьИсключение ТекстИсключения;
КонецЕсли;

КонецЕсли;

Результат = Новый Структура;
Результат.Вставить("Данные", Данные);
Результат.Вставить("Метаданные", МетаданныеОбъекта);
Результат.Вставить("ПолноеИмя", МетаданныеОбъекта.ПолноеИмя());
Результат.Вставить("Отбор", Отбор);
Результат.Вставить("ЭтоНовый", ЭтоНовый);

Возврат Результат;
КонецФункции

// Отмечает, что переданные данные необходимо обновить.
// Важно: не рекомендуется передавать в параметр Данные сразу все данные, которые
// необходимо зарегистрировать к обработке, т.к. большие коллекции типа Массив
// или ТаблицаЗначений могут занять существенный объем памяти сервера и привести
// к сильному снижению производительности системы. Рекомендуется получать и передавать
// данные небольшими порциями, например, по 1000 объектов.
//
// Параметры:
// ОсновныеПараметры - Структура - см. ОбновлениеИнформационнойБазы.ОсновныеПараметрыОтметкиКОбработке.
// Данные - Ссылка, Массив, НаборЗаписей - данные, по которым нужно зарегистрировать изменения.
// - ТаблицаЗначений - значения измерений независимого регистра сведений. Требования:
// - нет измерений с именем "Узел".
// - все измерения регистра должны входить в основной отбор
// - в таблице должны быть только колонки, соответствующие по именам измерениям регистра,
// по которым нужно регистрировать необходимость обработки
// - запись наборов в процессе обновления должна проходить с тем же отбором,
// что и регистрация необходимости обработки
// - в ДополнительныеПараметры нужно передать соответствующий признак и полное имя регистра.
// ДополнительныеПараметры - Структура - см. ОбновлениеИнформационнойБазы.ДополнительныеПараметрыОтметкиОбработки.
//
Процедура ОтметитьКОбработке(ОсновныеПараметры, Данные, ДополнительныеПараметры = Неопределено) Экспорт

Если ДополнительныеПараметры = Неопределено Тогда
ДополнительныеПараметры = ДополнительныеПараметрыОтметкиОбработки();
КонецЕсли;

Если (ТипЗнч(Данные) = Тип("Массив")
Или ТипЗнч(Данные) = Тип("ТаблицаЗначений"))
И Данные.Количество() = 0 Тогда
Возврат;
КонецЕсли;

Узел = ОчередьСсылкой(ОсновныеПараметры.Очередь);

Если ДополнительныеПараметры.ЭтоДвижения Тогда

Набор = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ДополнительныеПараметры.ПолноеИмяРегистра).СоздатьНаборЗаписей();

Если ДополнительныеПараметры.ОтметитьВсеРегистраторы Тогда

Если ТипЗнч(Данные) = Тип("ОбъектМетаданных") Тогда
МетаданныеДокумента = Данные;
ИначеЕсли ОбщегоНазначения.ЭтоСсылка(ТипЗнч(Данные)) Тогда
МетаданныеДокумента = Данные.Метаданные();
Иначе
ТекстИсключения = НСтр("ru = 'Для регистрации всех регистраторов регистра необходимо в параметре ""Данные"" передать ОбъектМетаданных:Документ или ДокументСсылка.'");
ВызватьИсключение ТекстИсключения;
КонецЕсли;
ПолноеИмяДокумента = МетаданныеДокумента.ПолноеИмя();

ТекстЗапроса =
"ВЫБРАТЬ
| ТаблицаДокумента.Ссылка КАК Ссылка
|ИЗ
| #ТаблицаДокумента КАК ТаблицаДокумента
|ГДЕ
| ТаблицаДокумента.Проведен";

ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ТаблицаДокумента", ПолноеИмяДокумента);
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;

МассивСсылок = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");

Для Каждого ЭлементМассива Из МассивСсылок Цикл
Набор.Отбор.Регистратор.Установить(ЭлементМассива);
ЗарегистрироватьИзменения(ОсновныеПараметры, Узел, Набор, "ПодчиненныйРегистр", ДополнительныеПараметры.ПолноеИмяРегистра);
КонецЦикла;

Иначе

Если ТипЗнч(Данные) = Тип("Массив") Тогда
Итератор = 0;
Попытка
Для Каждого ЭлементМассива Из Данные Цикл
Если Итератор = 0 Тогда
НачатьТранзакцию();
КонецЕсли;
Набор.Отбор.Регистратор.Установить(ЭлементМассива);
ЗарегистрироватьИзменения(ОсновныеПараметры, Узел, Набор, "ПодчиненныйРегистр", ДополнительныеПараметры.ПолноеИмяРегистра);
Итератор = Итератор + 1;
Если Итератор = 1000 Тогда
Итератор = 0;
ЗафиксироватьТранзакцию();
КонецЕсли;
КонецЦикла;

Если Итератор <> 0 Тогда
ЗафиксироватьТранзакцию();
КонецЕсли;
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки
Иначе

Набор.Отбор.Регистратор.Установить(Данные);
ЗарегистрироватьИзменения(ОсновныеПараметры, Узел, Набор, "ПодчиненныйРегистр", ДополнительныеПараметры.ПолноеИмяРегистра);

КонецЕсли;

КонецЕсли;
ИначеЕсли ДополнительныеПараметры.ЭтоНезависимыйРегистрСведений Тогда

Набор = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ДополнительныеПараметры.ПолноеИмяРегистра).СоздатьНаборЗаписей();
МетаданныеОбъекта = Метаданные.НайтиПоПолномуИмени(ДополнительныеПараметры.ПолноеИмяРегистра);
УстановитьНедостающиеОтборыВНаборе(Набор, МетаданныеОбъекта, Данные);

Для Каждого СтрокаТаблицы Из Данные Цикл

Для Каждого Колонка Из Данные.Колонки Цикл
Набор.Отбор[Колонка.Имя].Значение = СтрокаТаблицы[Колонка.Имя];
Набор.Отбор[Колонка.Имя].Использование = Истина;
КонецЦикла;

ЗарегистрироватьИзменения(ОсновныеПараметры, Узел, Набор, "НезависимыйРегистр", ДополнительныеПараметры.ПолноеИмяРегистра);

КонецЦикла;
Иначе
Если ТипЗнч(Данные) = Тип("Массив") Тогда
Итератор = 0;
Попытка
Для Каждого ЭлементМассива Из Данные Цикл
Если Итератор = 0 Тогда
НачатьТранзакцию();
КонецЕсли;
ЗарегистрироватьИзменения(ОсновныеПараметры, Узел, ЭлементМассива, "Ссылка");
Итератор = Итератор + 1;
Если Итератор = 1000 Тогда
Итератор = 0;
ЗафиксироватьТранзакцию();
КонецЕсли;
КонецЦикла;

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

МетаданныеОбъекта = Метаданные.НайтиПоТипу(ТипЗнч(Данные));

Если ОбщегоНазначения.ЭтоРегистрСведений(МетаданныеОбъекта)
И МетаданныеОбъекта.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.Независимый Тогда

УстановитьНедостающиеОтборыВНаборе(Данные, МетаданныеОбъекта, Данные.Отбор);

КонецЕсли;
ЗарегистрироватьИзменения(ОсновныеПараметры, Узел, Данные, "НезависимыйРегистр", МетаданныеОбъекта.ПолноеИмя());
КонецЕсли;
КонецЕсли;

КонецПроцедуры

// Отмечает, что по переданным регистраторам нужно переформировать движения.
//
// Параметры:
// Параметры - Структура - см. ОбновлениеИнформационнойБазы.ОсновныеПараметрыОтметкиКОбработке.
// Регистраторы - Массив - массив ссылок регистраторов.
// ПолноеИмяРегистра - Строка - полное имя регистра, для которого необходимо обновить движения.
//
Процедура ОтметитьРегистраторыКОбработке(Параметры, Регистраторы, ПолноеИмяРегистра) Экспорт

ДополнительныеПараметры = ДополнительныеПараметрыОтметкиОбработки();
ДополнительныеПараметры.ЭтоДвижения = Истина;
ДополнительныеПараметры.ПолноеИмяРегистра = ПолноеИмяРегистра;
ОтметитьКОбработке(Параметры, Регистраторы, ДополнительныеПараметры);

КонецПроцедуры

// Дополнительные параметры выборки данных для обработки.
//
// Возвращаемое значение:
// Структура - поля структуры:
// * ВыбиратьПорциями - Булево - выбирать данные для обработки порциями.
// Если выбираются документы, то порция определяется с учетом упорядочивания по убыванию
// по дате документа. Если выбираются регистраторы регистра, то порция определяется с
// учетом упорядочивания по убыванию по дате регистратора, если передано полное имя документа.
// Если полное имя документа не передано - упорядочивание происходит по периоду регистра:
// - берется максимальная дата по каждому регистратору
// - если по регистратору нет записей - он в топе.
// * ИмяВременнойТаблицы - Строка - параметр актуален для методов, создающих временные таблицы. Если имя не задано
// (поведение по умолчанию), то временная таблица будет создана с именем, указанным
// в описании каждого метода.
// * ДополнительныеИсточникиДанных - Соответствие - параметр актуален для методов, выбирающих регистраторы и ссылки
// для обработки. В ключах соответствия может быть только один из следующих
// видов данных:
// 1. Пути к реквизитам шапки документа или реквизитам табличных частей, которые
// участвуют в соединениях с другими таблицами (в т.ч. неявных соединениях при
// обращении "через точку").
// 2. Имена ссылочных объектов метаданных (Строка), в значениях которых находится
// соответствие, в котором ключ - это имя регистра (Строка), а в значении
// соответствие в ключах которого тоже, что и в п. 1, т.е.
// иерархия соответствий "Объект" -> "Регистр" -> "Источники".
// Процедуры проверяют блокировку данных этих таблиц обработчиками меньших
// очередей. Формат имен источников <ИмяРеквизита> или
// <ИмяТабличной>.<ИмяРеквизитаТабличнойЧасти>. Для удобства заполнения
// см. УстановитьИсточникДанных() и см. ПолучитьИсточникДанных().
// * ПоляУпорядочивания - Массив - имена полей независимого регистра сведений, используется для упорядочивания
// результата запроса.
// * МаксимумВыборки - Число - максимальное количество выбираемых записей.
//
Функция ДополнительныеПараметрыВыборкиДанныхДляОбработки() Экспорт

ДополнительныеПараметры = Новый Структура;
ДополнительныеПараметры.Вставить("ВыбиратьПорциями", Истина);
ДополнительныеПараметры.Вставить("ИмяВременнойТаблицы", "");
ДополнительныеПараметры.Вставить("ДополнительныеИсточникиДанных", Новый Соответствие);
ДополнительныеПараметры.Вставить("ПоляУпорядочивания", Новый Массив);
ДополнительныеПараметры.Вставить("МаксимумВыборки", МаксимальноеКоличествоЗаписейВВыборке());

Возврат ДополнительныеПараметры;

КонецФункции

// Дополнительные параметры выборки данных для многопоточной обработки.
//
// Возвращаемое значение:
// Структура - поля из ДополнительныеПараметрыВыборкиДанныхДляОбработки() дополненные следующими полями:
// * ПолныеИменаОбъектов - Строка - полные имена обновляемых объектов (например, документов), разделенных запятыми.
// * ПолныеИменаРегистров - Строка - полные имена регистров, разделенных запятыми.
// * ПоляУпорядочиванияПриРаботеПользователей - Массив - поля упорядочивания, используемые при обновлении
// с приоритетом работы пользователей.
// * ПоляУпорядочиванияПриОбработкеДанных - Массив - поля упорядочивания, используемые при обновлении
// с приоритетом обработки данных.
// * СпособВыборки - Строка - один из способов выборки:
// ОбновлениеИнформационнойБазы.СпособВыборкиИзмеренияНезависимогоРегистраСведений(),
// ОбновлениеИнформационнойБазы.СпособВыборкиРегистраторыРегистра(),
// ОбновлениеИнформационнойБазы.СпособВыборкиСсылки().
// * ПоследняяВыбраннаяЗапись - СписокЗначений - конец предыдущей выборки (служебное поле).
// * ПерваяЗапись - СписокЗначений - начало выборки (служебное поле).
// * ПоследняяЗапись - СписокЗначений - конец выборки (служебное поле).
// * ОптимизироватьВыборкуПоСтраницам - Булево - если Истина, то выборка выполняется без ИЛИ, значение Ложь может
// быть полезно, если исходный запрос не оптимален, тогда с ИЛИ будет быстрее.
//
Функция ДополнительныеПараметрыВыборкиДанныхДляМногопоточнойОбработк­и() Экспорт

ДополнительныеПараметры = ДополнительныеПараметрыВыборкиДанныхДляОбработки();
ДополнительныеПараметры.Вставить("ПолныеИменаОбъектов");
ДополнительныеПараметры.Вставить("ПолныеИменаРегистров");
ДополнительныеПараметры.Вставить("ПоляУпорядочиванияПриРаботеПользователей", Новый Массив);
ДополнительныеПараметры.Вставить("ПоляУпорядочиванияПриОбработкеДанных", Новый Массив);
ДополнительныеПараметры.Вставить("СпособВыборки");
ДополнительныеПараметры.Вставить("ПоследняяВыбраннаяЗапись");
ДополнительныеПараметры.Вставить("ПерваяЗапись");
ДополнительныеПараметры.Вставить("ПоследняяЗапись");
ДополнительныеПараметры.Вставить("ОптимизироватьВыборкуПоСтраницам", Истина);

Возврат ДополнительныеПараметры;

КонецФункции

// Установить параметр ДополнительныеИсточникиДанных в структуре, возвращаемой функцией
// ДополнительныеПараметрыВыборкиДанныхДляОбработки().
//
// Используется, когда источники данных нужно установить в разрезе документов и регистров.
// Применяется при многопоточном обновлении.
//
// Параметры:
// ДополнительныеИсточникиДанных - Соответствие - тоже, что и ДополнительныеИсточникиДанных
// (см. ДополнительныеПараметрыВыборкиДанныхДляОбработки()).
// Источник - Строка - источники данных (см. ДополнительныеПараметрыВыборкиДанныхДляОбработки()).
// Объект - Строка - имя документа (полное или короткое).
// Регистр - Строка - имя регистра (полное или короткое).
//
Процедура УстановитьИсточникДанных(ДополнительныеИсточникиДанных, Источник, Объект = "", Регистр = "") Экспорт

ИмяОбъекта = ИмяОбъектаМетаданных(Объект);
ИмяРегистра = ИмяОбъектаМетаданных(Регистр);

Если ПустаяСтрока(ИмяОбъекта) И ПустаяСтрока(ИмяРегистра) Тогда
ДополнительныеИсточникиДанных.Вставить(Источник);
Иначе
РегистрыОбъекта = ДополнительныеИсточникиДанных[ИмяОбъекта];

Если РегистрыОбъекта = Неопределено Тогда
РегистрыОбъекта = Новый Соответствие;
ДополнительныеИсточникиДанных[ИмяОбъекта] = РегистрыОбъекта;
КонецЕсли;

ИсточникиДанных = РегистрыОбъекта[ИмяРегистра];

Если ИсточникиДанных = Неопределено Тогда
ИсточникиДанных = Новый Соответствие;
РегистрыОбъекта[ИмяРегистра] = ИсточникиДанных;
КонецЕсли;

ИсточникиДанных.Вставить(Источник);
КонецЕсли;

КонецПроцедуры

// Получить значение параметра ДополнительныеИсточникиДанных из структуры, возвращаемой
// функцией ДополнительныеПараметрыВыборкиДанныхДляОбработки().
//
// Можно использовать, когда источники данных нужно получить в разрезе документов и регистров.
// Применяется при многопоточном обновлении.
//
// Параметры:
// ДополнительныеИсточникиДанных - Соответствие - тоже, что и ДополнительныеИсточникиДанных
// (см. ДополнительныеПараметрыВыборкиДанныхДляОбработки()).
// Объект - Строка - имя документа (полное или короткое).
// Регистр - Строка - имя регистра (полное или короткое).
//
// Возвращаемое значение:
// Соответствие - источники данных для указанного документа и регистра.
//
Функция ПолучитьИсточникиДанных(ДополнительныеИсточникиДанных, Объект = "", Регистр = "") Экспорт

Если ЭтоПростойИсточникДанных(ДополнительныеИсточникиДанных) Тогда
Возврат ДополнительныеИсточникиДанных;
Иначе
ИмяОбъекта = ИмяОбъектаМетаданных(Объект);
ИмяРегистра = ИмяОбъектаМетаданных(Регистр);
РегистрыОбъекта = ДополнительныеИсточникиДанных[ИмяОбъекта];
ТипСоответствие = Тип("Соответствие");

Если ТипЗнч(РегистрыОбъекта) = ТипСоответствие Тогда
ИсточникиДанных = РегистрыОбъекта[ИмяРегистра];

Если ТипЗнч(ИсточникиДанных) = ТипСоответствие Тогда
Возврат ИсточникиДанных;
КонецЕсли;
КонецЕсли;

Возврат Новый Соответствие;
КонецЕсли;

КонецФункции

// Создает временную таблицу ссылок, которые не обработаны в текущей очереди
// и не заблокированы меньшими очередями.
// Имя таблицы: ВТДляОбработки<ИмяРегистра>, например ВТДляОбработкиТоварыНаСкладах.
// Колонки таблицы
// * Регистратор - ДокументСсылка.
//
// Параметры:
// Очередь - Число - очередь обработки, в которой выполняется текущий обработчик.
// ПолноеИмяДокумента - Строка - имя документа, движения по которому нужно переформировать. Если движения формируются не по данным
// документа, то нужно передать Неопределено - тогда не будет проверяться блокировка таблицы документа.
// Например, Документ.ПриходныйОрдерНаТовары
// ПолноеИмяРегистра - Строка - имя регистра, движения по которому нужно переформировать.
// Например, РегистрНакопления.ТоварыНаСкладах
// МенеджерВременныхТаблиц - МенеджерВременныхТаблиц - менеджер, в котором будет создана временная таблица.
// ДополнительныеПараметры - Структура - см. ОбновлениеИнформационнойБазы.ДополнительныеПараметрыВыборкиДанныхДляОбработки.
//
// Возвращаемое значение:
// Структура - результат формирования временной таблицы:
// * ЕстьЗаписиВоВременнойТаблице - Булево - в создаваемой таблице есть хотя бы одна запись. Записей может не быть по
// двум причинам
// - все обработано или все, что нужно обработать, еще заблокировано обработчиками с меньшей очередью.
// * ЕстьДанныеДляОбработки - Булево - в очереди есть ссылки для обработки, т.е. еще не все обработано.
// * ИмяВременнойТаблицы - Строка - имя созданной временной таблицы.
//
Функция СоздатьВременнуюТаблицуРегистраторовРегистраДляОбработки(Очередь, ПолноеИмяДокумента, ПолноеИмяРегистра, МенеджерВременныхТаблиц, ДополнительныеПараметры = Неопределено) Экспорт

Если ДополнительныеПараметры = Неопределено Тогда
ДополнительныеПараметры = ДополнительныеПараметрыВыборкиДанныхДляОбработки();
КонецЕсли;

ИмяРегистра = СтрРазделить(ПолноеИмяРегистра,".",Ложь)[1];

ТекущаяОчередь = ОчередьСсылкой(Очередь);

Если ПолноеИмяДокумента = Неопределено Тогда
Если ДополнительныеПараметры.ВыбиратьПорциями Тогда
ТекстЗапроса =
"ВЫБРАТЬ
| ТаблицаРегистраИзменения.Регистратор КАК Регистратор,
| МАКСИМУМ(ЕСТЬNULL(ТаблицаРегистра.Период, ДАТАВРЕМЯ(3000, 1, 1))) КАК Период
|ПОМЕСТИТЬ ВТДляОбработкиРегистраторПолная
|ИЗ
| #ТаблицаРегистраИзменения КАК ТаблицаРегистраИзменения
| ЛЕВОЕ СОЕДИНЕНИЕ ВТЗаблокированоРегистратор КАК ВТЗаблокированоРегистратор
| ПО ТаблицаРегистраИзменения.Регистратор = ВТЗаблокированоРегистратор.Регистратор
| ЛЕВОЕ СОЕДИНЕНИЕ #ТаблицаДвиженийРегистра КАК ТаблицаРегистра
| ПО ТаблицаРегистраИзменения.Регистратор = ТаблицаРегистра.Регистратор
| #ТекстЗапросаСоединениеСДопИсточникамиРегистрами
|ГДЕ
| ТаблицаРегистраИзменения.Узел = &ТекущаяОчередь
| И ВТЗаблокированоРегистратор.Регистратор ЕСТЬ NULL
| И &УсловиеПоДопИсточникамРегистрам
|
|СГРУППИРОВАТЬ ПО
| ТаблицаРегистраИзменения.Регистратор
|
|ИНДЕКСИРОВАТЬ ПО
| Регистратор
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|ВЫБРАТЬ
| ВТДляОбработкиРегистраторПолная.Регистратор КАК Регистратор
|ПОМЕСТИТЬ #ВТДляОбработкиРегистратор
|ИЗ
| ВТДляОбработкиРегистраторПолная КАК ВТДляОбработкиРегистраторПолная
|ГДЕ
| ВТДляОбработкиРегистраторПолная.Регистратор В
| (ВЫБРАТЬ ПЕРВЫЕ 10000
| ВТДляОбработкиРегистраторПолная.Регистратор КАК Регистратор
| ИЗ
| ВТДляОбработкиРегистраторПолная КАК ВТДляОбработкиРегистраторПолная
| УПОРЯДОЧИТЬ ПО
| ВТДляОбработкиРегистраторПолная.Период УБЫВ)
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|УНИЧТОЖИТЬ ВТЗаблокированоРегистратор
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|УНИЧТОЖИТЬ ВТДляОбработкиРегистраторПолная";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса,"#ТаблицаДвиженийРегистра", ПолноеИмяРегистра);
Иначе
ТекстЗапроса =
"ВЫБРАТЬ
| ТаблицаРегистраИзменения.Регистратор КАК Регистратор
|ПОМЕСТИТЬ #ВТДляОбработкиРегистратор
|ИЗ
| #ТаблицаРегистраИзменения КАК ТаблицаРегистраИзменения
| ЛЕВОЕ СОЕДИНЕНИЕ ВТЗаблокированоРегистратор КАК ВТЗаблокированоРегистратор
| ПО ТаблицаРегистраИзменения.Регистратор = ВТЗаблокированоРегистратор.Регистратор
| #ТекстЗапросаСоединениеСДопИсточникамиРегистрами
|ГДЕ
| ТаблицаРегистраИзменения.Узел = &ТекущаяОчередь
| И ВТЗаблокированоРегистратор.Регистратор ЕСТЬ NULL
| И &УсловиеПоДопИсточникамРегистрам
|
|ИНДЕКСИРОВАТЬ ПО
| Регистратор
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|УНИЧТОЖИТЬ ВТЗаблокированоРегистратор";
КонецЕсли;
Иначе
ИмяДокумента = СтрРазделить(ПолноеИмяДокумента,".",Ложь)[1];
Если ДополнительныеПараметры.ВыбиратьПорциями Тогда
ТекстЗапроса =
"ВЫБРАТЬ
| ТаблицаРегистраИзменения.Регистратор КАК Регистратор
|ПОМЕСТИТЬ ВТДляОбработкиРегистраторПолная
|ИЗ
| #ТаблицаРегистраИзменения КАК ТаблицаРегистраИзменения
| ЛЕВОЕ СОЕДИНЕНИЕ ВТЗаблокированоРегистратор КАК ВТЗаблокированоРегистратор
| ПО ТаблицаРегистраИзменения.Регистратор = ВТЗаблокированоРегистратор.Регистратор
| ЛЕВОЕ СОЕДИНЕНИЕ ВТЗаблокированоСсылка КАК ВТЗаблокированоСсылка
| ПО ТаблицаРегистраИзменения.Регистратор = ВТЗаблокированоСсылка.Ссылка
| #ТекстЗапросаСоединениеСДопИсточникамиПоШапке
| #ТекстЗапросаСоединениеСДопИсточникамиПоТЧ
| #ТекстЗапросаСоединениеСДопИсточникамиРегистрами
|ГДЕ
| ТаблицаРегистраИзменения.Узел = &ТекущаяОчередь
| И ТаблицаРегистраИзменения.Регистратор ССЫЛКА #ПолноеИмяДокумента
| И ВТЗаблокированоРегистратор.Регистратор ЕСТЬ NULL
| И ВТЗаблокированоСсылка.Ссылка ЕСТЬ NULL
| И &УсловиеПоДопИсточникамСсылкам
| И &УсловиеПоДопИсточникамРегистрам
|
|ИНДЕКСИРОВАТЬ ПО
| Регистратор
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|ВЫБРАТЬ
| ВТДляОбработкиРегистраторПолная.Регистратор КАК Регистратор
|ПОМЕСТИТЬ #ВТДляОбработкиРегистратор
|ИЗ
| ВТДляОбработкиРегистраторПолная КАК ВТДляОбработкиРегистраторПолная
|ГДЕ
| ВТДляОбработкиРегистраторПолная.Регистратор В
| (ВЫБРАТЬ ПЕРВЫЕ 10000
| ВТДляОбработкиРегистраторПолная.Регистратор КАК Регистратор
| ИЗ
| ВТДляОбработкиРегистраторПолная КАК ВТДляОбработкиРегистраторПолная
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ #ПолноеИмяДокумента КАК ТаблицаДокумента
| ПО
| ВТДляОбработкиРегистраторПолная.Регистратор = ТаблицаДокумента.Ссылка
| УПОРЯДОЧИТЬ ПО
| ТаблицаДокумента.Дата УБЫВ)
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|УНИЧТОЖИТЬ ВТЗаблокированоРегистратор
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|УНИЧТОЖИТЬ ВТЗаблокированоСсылка
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|УНИЧТОЖИТЬ ВТДляОбработкиРегистраторПолная";

Иначе
ТекстЗапроса =
"ВЫБРАТЬ
| ТаблицаРегистраИзменения.Регистратор КАК Регистратор
|ПОМЕСТИТЬ #ВТДляОбработкиРегистратор
|ИЗ
| #ТаблицаРегистраИзменения КАК ТаблицаРегистраИзменения
| ЛЕВОЕ СОЕДИНЕНИЕ ВТЗаблокированоРегистратор КАК ВТЗаблокированоРегистратор
| ПО ТаблицаРегистраИзменения.Регистратор = ВТЗаблокированоРегистратор.Регистратор
| ЛЕВОЕ СОЕДИНЕНИЕ ВТЗаблокированоСсылка КАК ВТЗаблокированоСсылка
| ПО ТаблицаРегистраИзменения.Регистратор = ВТЗаблокированоСсылка.Ссылка
| #ТекстЗапросаСоединениеСДопИсточникамиПоШапке
| #ТекстЗапросаСоединениеСДопИсточникамиПоТЧ
| #ТекстЗапросаСоединениеСДопИсточникамиРегистрами
|ГДЕ
| ТаблицаРегистраИзменения.Узел = &ТекущаяОчередь
| И ТаблицаРегистраИзменения.Регистратор ССЫЛКА #ПолноеИмяДокумента
| И ВТЗаблокированоРегистратор.Регистратор ЕСТЬ NULL
| И ВТЗаблокированоСсылка.Ссылка ЕСТЬ NULL
| И &УсловиеПоДопИсточникамСсылкам
| И &УсловиеПоДопИсточникамРегистрам
|
|ИНДЕКСИРОВАТЬ ПО
| Регистратор
|;
|УНИЧТОЖИТЬ
| ВТЗаблокированоРегистратор
|;
|УНИЧТОЖИТЬ
| ВТЗаблокированоСсылка";
КонецЕсли;

ДополнительныеПараметрыСозданияВТ = ДополнительныеПараметрыВыборкиДанныхДляОбработки();
ДополнительныеПараметрыСозданияВТ.ИмяВременнойТаблицы = "ВТЗаблокированоСсылка";
СоздатьВременнуюТаблицуЗаблокированныхДляЧтенияИИзмененияДан­ных(Очередь, ПолноеИмяДокумента, МенеджерВременныхТаблиц, ДополнительныеПараметрыСозданияВТ);
КонецЕсли;

Если ПустаяСтрока(ДополнительныеПараметры.ИмяВременнойТаблицы) Тогда
ИмяВременнойТаблицы = "ВТДляОбработки" + ИмяРегистра;
Иначе
ИмяВременнойТаблицы = ДополнительныеПараметры.ИмяВременнойТаблицы;
КонецЕсли;

ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ТаблицаРегистраИзменения", ПолноеИмяРегистра + ".Изменения");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ВТДляОбработкиРегистратор", ИмяВременнойТаблицы);

ДополнительныеПараметрыСозданияВТ = ДополнительныеПараметрыВыборкиДанныхДляОбработки();
ДополнительныеПараметрыСозданияВТ.ИмяВременнойТаблицы = "ВТЗаблокированоРегистратор";
СоздатьВременнуюТаблицуЗаблокированныхДляЧтенияИИзмененияДан­ных(Очередь, ПолноеИмяРегистра, МенеджерВременныхТаблиц, ДополнительныеПараметрыСозданияВТ);

ДобавитьПроверкуБлокировкиДополнительныхИсточников(Очередь, ТекстЗапроса, ПолноеИмяДокумента, ПолноеИмяРегистра, МенеджерВременныхТаблиц, Истина, ДополнительныеПараметры);

ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ПолноеИмяДокумента", ПолноеИмяДокумента);

Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.УстановитьПараметр("ТекущаяОчередь", ТекущаяОчередь);
РезультатЗапроса = Запрос.ВыполнитьПакет();

Результат = Новый Структура("ЕстьЗаписиВоВременнойТаблице,ЕстьДанныеДляОбработки,ИмяВременнойТаблицы", Ложь, Ложь, "");
Результат.ИмяВременнойТаблицы = ИмяВременнойТаблицы;
Результат.ЕстьЗаписиВоВременнойТаблице = РезультатЗапроса[0].Выгрузить()[0].Количество <> 0;

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

Возврат Результат;

КонецФункции

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

Если ДополнительныеПараметры = Неопределено Тогда
ДополнительныеПараметры = ДополнительныеПараметрыВыборкиДанныхДляОбработки();
КонецЕсли;

МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц();
ПроверитьПараметрыВыборки(ДополнительныеПараметры);
ПараметрыПостроения = ПараметрыПостроенияВыборки(ДополнительныеПараметры);

Если ПолноеИмяДокумента = Неопределено Тогда
ТекстЗапроса =
"ВЫБРАТЬ ПЕРВЫЕ 10000
| &ВыбираемыеПоля
|ИЗ
| #ТаблицаРегистраИзменения КАК ТаблицаРегистраИзменения
| ЛЕВОЕ СОЕДИНЕНИЕ #ТаблицаДвиженийРегистра КАК ТаблицаРегистра
| ПО ТаблицаРегистраИзменения.Регистратор = ТаблицаРегистра.Регистратор
| ЛЕВОЕ СОЕДИНЕНИЕ ВТЗаблокированоРегистратор КАК ВТЗаблокированоРегистратор
| ПО ТаблицаРегистраИзменения.Регистратор = ВТЗаблокированоРегистратор.Регистратор
| #ТекстЗапросаСоединениеСДопИсточникамиРегистрами
|ГДЕ
| ТаблицаРегистраИзменения.Узел = &ТекущаяОчередь
| И ВТЗаблокированоРегистратор.Регистратор ЕСТЬ NULL
| И &УсловиеПоДопИсточникамРегистрам
|
|СГРУППИРОВАТЬ ПО
| ТаблицаРегистраИзменения.Регистратор";

Если ПараметрыПостроения.ПостраничнаяВыборка Тогда
ТекстЗапроса = ТекстЗапроса + "
|
|ИМЕЮЩИЕ
| &УсловиеПоСтраницам"
КонецЕсли;

ТекстЗапроса = ТекстЗапроса + "
|
|УПОРЯДОЧИТЬ ПО
| &ПорядокВыборки";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ТаблицаДвиженийРегистра", ПолноеИмяРегистра);
УстановитьПоляУпорядочиванияРегистра(ПараметрыПостроения);
Иначе
ТекстЗапроса =
"ВЫБРАТЬ ПЕРВЫЕ 10000
| &ВыбираемыеПоля
|ИЗ
| #ТаблицаРегистраИзменения КАК ТаблицаРегистраИзменения
| ЛЕВОЕ СОЕДИНЕНИЕ ВТЗаблокированоРегистратор КАК ВТЗаблокированоРегистратор
| ПО ТаблицаРегистраИзменения.Регистратор = ВТЗаблокированоРегистратор.Регистратор
| ЛЕВОЕ СОЕДИНЕНИЕ ВТЗаблокированоСсылка КАК ВТЗаблокированоСсылка
| ПО ТаблицаРегистраИзменения.Регистратор = ВТЗаблокированоСсылка.Ссылка
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ #ПолноеИмяДокумента КАК ТаблицаДокумента
| #ТекстЗапросаСоединениеСДопИсточникамиПоШапке
| ПО ТаблицаРегистраИзменения.Регистратор = ТаблицаДокумента.Ссылка
| #ТекстЗапросаСоединениеСДопИсточникамиПоТЧ
| #ТекстЗапросаСоединениеСДопИсточникамиРегистрами
|
|ГДЕ
| ТаблицаРегистраИзменения.Узел = &ТекущаяОчередь
| И ТаблицаРегистраИзменения.Регистратор ССЫЛКА #ПолноеИмяДокумента
| И ВТЗаблокированоРегистратор.Регистратор ЕСТЬ NULL
| И ВТЗаблокированоСсылка.Ссылка ЕСТЬ NULL
| И &УсловиеПоДопИсточникамСсылкам
| И &УсловиеПоДопИсточникамРегистрам
| И &УсловиеПоСтраницам
|
|УПОРЯДОЧИТЬ ПО
| &ПорядокВыборки";
ДополнительныеПараметрыСозданияВТ = ДополнительныеПараметрыВыборкиДанныхДляОбработки();
ДополнительныеПараметрыСозданияВТ.ИмяВременнойТаблицы = "ВТЗаблокированоСсылка";
СоздатьВременнуюТаблицуЗаблокированныхДляЧтенияИИзмененияДан­ных(Очередь, ПолноеИмяДокумента, МенеджерВременныхТаблиц, ДополнительныеПараметрыСозданияВТ);
УстановитьПоляУпорядочиванияРегистраПоДокументу(ПараметрыПостроения);
КонецЕсли;

ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ТаблицаРегистраИзменения", ПолноеИмяРегистра + ".Изменения");

ДополнительныеПараметрыСозданияВТ = ДополнительныеПараметрыВыборкиДанныхДляОбработки();
ДополнительныеПараметрыСозданияВТ.ИмяВременнойТаблицы = "ВТЗаблокированоРегистратор";
СоздатьВременнуюТаблицуЗаблокированныхДляЧтенияИИзмененияДан­ных(Очередь, ПолноеИмяРегистра, МенеджерВременныхТаблиц, ДополнительныеПараметрыСозданияВТ);
УстановитьРазмерВыборки(ТекстЗапроса, ДополнительныеПараметры);
ДобавитьПроверкуБлокировкиДополнительныхИсточников(Очередь, ТекстЗапроса, ПолноеИмяДокумента, ПолноеИмяРегистра, МенеджерВременныхТаблиц, Ложь, ДополнительныеПараметры);

ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ПолноеИмяДокумента", ПолноеИмяДокумента);

Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.УстановитьПараметр("ТекущаяОчередь", ОчередьСсылкой(Очередь));

УстановитьПоляПоСтраницам(Запрос, ПараметрыПостроения);
УстановитьПорядокПоСтраницам(Запрос, ПараметрыПостроения);

Возврат ВыбратьДанныеДляОбработки(Запрос, ПараметрыПостроения);

КонецФункции

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

ИмяОбъекта = СтрРазделить(ПолноеИмяОбъекта,".",Ложь)[1];
МетаданныеОбъекта = Метаданные.НайтиПоПолномуИмени(ПолноеИмяОбъекта);
ЭтоДокумент = ОбщегоНазначения.ЭтоДокумент(МетаданныеОбъекта)
Или ОбщегоНазначения.ЭтоЗадача(МетаданныеОбъекта);

ПроверитьПараметрыВыборки(ДополнительныеПараметры);
ПараметрыПостроения = ПараметрыПостроенияВыборки(ДополнительныеПараметры);

ТекстЗапроса =
"ВЫБРАТЬ ПЕРВЫЕ 10000
| &ВыбираемыеПоля
|ИЗ
| #ТаблицаОбъектаИзменения КАК ТаблицаИзменений
| ЛЕВОЕ СОЕДИНЕНИЕ #ВТЗаблокированоСсылка КАК ВТЗаблокированоСсылка
| ПО ТаблицаИзменений.Ссылка = ВТЗаблокированоСсылка.Ссылка
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ #ТаблицаОбъекта КАК ТаблицаОбъекта
| #ТекстЗапросаСоединениеСДопИсточникамиПоШапке
| ПО ТаблицаИзменений.Ссылка = ТаблицаОбъекта.Ссылка
| #ТекстЗапросаСоединениеСДопИсточникамиПоТЧ
| #ТекстЗапросаСоединениеСДопИсточникамиРегистрами
|ГДЕ
| ТаблицаИзменений.Узел = &ТекущаяОчередь
| И ВТЗаблокированоСсылка.Ссылка ЕСТЬ NULL
| И &УсловиеПоДопИсточникамСсылкам
| И &УсловиеПоДопИсточникамРегистрам
| И &УсловиеПоСтраницам";
Если ЭтоДокумент Или ПараметрыПостроения.ПостраничнаяВыборка Тогда
ТекстЗапроса = ТекстЗапроса + "
|
|УПОРЯДОЧИТЬ ПО
| &ПорядокВыборки";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + "
|;
|УНИЧТОЖИТЬ
| #ВТЗаблокированоСсылка";
УстановитьПоляУпорядочиванияСсылок(ПараметрыПостроения, ЭтоДокумент);
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ВТЗаблокированоСсылка","ВТЗаблокировано" + ИмяОбъекта);
ТекстЗапроса = СтрЗаменить(ТекстЗапроса,"#ТаблицаОбъектаИзменения", ПолноеИмяОбъекта + ".Изменения");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса,"#ТаблицаОбъекта", ПолноеИмяОбъекта);
УстановитьРазмерВыборки(ТекстЗапроса, ДополнительныеПараметры);
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц();
СоздатьВременнуюТаблицуЗаблокированныхДляЧтенияИИзмененияДан­ных(Очередь, ПолноеИмяОбъекта, МенеджерВременныхТаблиц);

ДобавитьПроверкуБлокировкиДополнительныхИсточников(Очередь, ТекстЗапроса, ПолноеИмяОбъекта, Неопределено, МенеджерВременныхТаблиц, Ложь, ДополнительныеПараметры);

Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.УстановитьПараметр("ТекущаяОчередь", ОчередьСсылкой(Очередь));

УстановитьПоляПоСтраницам(Запрос, ПараметрыПостроения);
Если ЭтоДокумент Или ПараметрыПостроения.ПостраничнаяВыборка Тогда
УстановитьПорядокПоСтраницам(Запрос, ПараметрыПостроения);
КонецЕсли;

Возврат ВыбратьДанныеДляОбработки(Запрос, ПараметрыПостроения);

КонецФункции

// Создает временную таблицу ссылок, которые не обработаны в текущей очереди
// и не заблокированы меньшими очередями.
// Имя таблицы: ВТДляОбработки<ИмяОбъекта>, например ВТДляОбработкиНоменклатура.
// Колонки таблицы
// * Ссылка - ЛюбаяСсылка.
//
// Параметры:
// Очередь - Число - очередь обработки, в которой выполняется текущий обработчик.
// ПолноеИмяОбъекта - Строка - полное имя объекта, для которого выполняется проверка, например, Справочник.Номенклатура.
// МенеджерВременныхТаблиц - МенеджерВременныхТаблиц - менеджер, в котором будет создана временная таблица.
// ДополнительныеПараметры - Структура - см. ОбновлениеИнформационнойБазы.ДополнительныеПараметрыВыборкиДанныхДляОбработки.
//
// Возвращаемое значение:
// Структура - результат формирования временной таблицы:
// * ЕстьЗаписиВоВременнойТаблице - Булево - в создаваемой таблице есть хотя бы одна запись. Записей может не быть по
// двум причинам
// - все обработано или все, ч
12. VladimirB 16 20.04.19 16:29 Сейчас в теме
(11)
Найдите здесь 66 строку.
Попробуйте вместо нее написать так;
	Попытка
		Объект.Записать(); 
	Исключение
		Сообщить("Произошла ошибка в объекте - "+ТипЗнч(Объект));
	КонецПопытки;


возможно у вас обновление пройдет.
Внизу в окне сообщений появятся сообщение об ошибке - Какой объект не изменился/не добавился
13. Эвелина 20.04.19 16:35 Сейчас в теме
(12) я так понимаю конфу надо сначала для правки установить на "сохранить поддержку с возможностью редактирования"?
14. VladimirB 16 20.04.19 16:36 Сейчас в теме
15. VladimirB 16 20.04.19 16:37 Сейчас в теме
(13) Копию базы только еще сделайте. Мало ли чего
16. Эвелина 20.04.19 16:53 Сейчас в теме
(15)не помогло, то же самое
18. VladimirB 16 20.04.19 16:55 Сейчас в теме
(16) А внизу в окне сообщений что-нибудь написалось?
19. Эвелина 20.04.19 16:57 Сейчас в теме
(18)нет, тоже сообщение об ошибке
17. VladimirB 16 20.04.19 16:53 Сейчас в теме
(16)
  Попытка
        Объект.Записать(); 
    Исключение
        Если СокрЛП(Объект.Код)="002087" Тогда
                _НовыйКод="102087";
                Объект.Код=_НовыйКод;
                Попытка
                        Объект.Записать(); 
                Исключение
                         Сообщить("Все-равно произошла ошибка в объекте - "+ТипЗнч(Объект));
                КонецПопытки;
        Иначе
                 Сообщить("Произошла ошибка в объекте - "+ТипЗнч(Объект));
        КонецЕсли;
    КонецПопытки;
Показать


попробуйте этот код.
Возможно вы не потеряете новый объект
20. Эвелина 20.04.19 17:01 Сейчас в теме
(17)При вызове обработчика обновления:
"Справочники.РегламентированныеОтчеты.ЗаполнитьСписокРегламентированныхОтчетов()"
произошла ошибка:
"{Обработка.ОбновлениеРегламентированнойОтчетности.МодульОбъекта(21)}: Ошибка при вызове метода контекста (НайтиПоРеквизиту)
НайденныйЭлемент = РегламОтчеты.НайтиПоРеквизиту("ИсточникОтчета", СокрЛП(Источник));
по причине:
В данной транзакции уже происходили ошибки!".

это новая ошибка...другая совершенно((((
21. VladimirB 16 20.04.19 17:03 Сейчас в теме
(20) Вы остались в программе? или снова выкинуло?
22. Эвелина 20.04.19 17:05 Сейчас в теме
23. VladimirB 16 20.04.19 17:07 Сейчас в теме
(22)

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

Если СокрЛП(Объект.Код)="002087" Тогда
                Объект.Код="102087";
         КонецЕсли;
        Объект.Записать();

 
24. Эвелина 20.04.19 17:14 Сейчас в теме
(23) а может это как раз тот справочник "Справочники.РегламентированныеОтчеты.ЗаполнитьСписокРегламентированныхОтчетов()" с кодом неправильным?
25. VladimirB 16 20.04.19 17:14 Сейчас в теме
29. Эвелина 20.04.19 17:22 Сейчас в теме
(25) да, написала же что первичная ошибка вылезла - смотри (27)
26. VladimirB 16 20.04.19 17:15 Сейчас в теме
(24) Все возможно. Но все-равно ведь выкидывает.
27. Эвелина 20.04.19 17:16 Сейчас в теме
(23){ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(69)}: Ошибка при вызове метода контекста (Записать)
Объект.Записать();
по причине:
Значение "002087" поля "Код" не уникально
28. VladimirB 16 20.04.19 17:20 Сейчас в теме
(27)
Попробуйте так:

Если СокрЛП(Объект.Код)="002087" Тогда
           Предупреждение("Ошибка в объекте "+ТипЗнч(Объект));   
 КонецЕсли;
 Объект.Записать();


Должно выйти окно предупреждения с названием объекта
30. Эвелина 20.04.19 17:24 Сейчас в теме
(28) в конфе: {ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(67,12)}: Процедура или функция с указанным именем не определена (Предупреждение)
<<?>>Предупреждение("Ошибка в объекте "+ТипЗнч(Объект)); (Проверка: Сервер)
31. VladimirB 16 20.04.19 17:33 Сейчас в теме
(30) В свойствах общего модуля ОбновлениеИнформационнойБазы
поставьте еще галочку "Клиент"
32. VladimirB 16 20.04.19 17:35 Сейчас в теме
(31) У вас обычные формы или управляемые?
35. Эвелина 20.04.19 17:39 Сейчас в теме
(32)Управляемые, эта конфа не работает на обычных..
33. Эвелина 20.04.19 17:38 Сейчас в теме
(31)тогда вообще капец что....
ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(67,12)}: Процедура или функция с указанным именем не определена (Предупреждение)
<<?>>Предупреждение("Ошибка в объекте "+ТипЗнч(Объект)); (Проверка: Сервер)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(683,19)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(1180,17)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(1231,34)}: Тип не определен (МенеджерВременныхТаблиц)
МенеджерВременныхТаблиц = Новый <<?>>МенеджерВременныхТаблиц(); (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(1310,17)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(1383,34)}: Тип не определен (МенеджерВременныхТаблиц)
МенеджерВременныхТаблиц = Новый <<?>>МенеджерВременныхТаблиц(); (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(1388,17)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(1540,17)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(1586,17)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(1646,34)}: Тип не определен (МенеджерВременныхТаблиц)
МенеджерВременныхТаблиц = Новый <<?>>МенеджерВременныхТаблиц(); (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(1697,17)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(1867,17)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(2138,17)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(2315,17)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(2490,17)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(2786,22)}: Тип не определен (ТаблицаЗначений)
Обработчики = Новый <<?>>ТаблицаЗначений; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(2838,21)}: Тип не определен (ТаблицаЗначений)
Приоритеты = Новый <<?>>ТаблицаЗначений; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(2913,17)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(2998,17)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(3081,17)}: Тип не определен (ТаблицаЗначений)
Возврат Новый <<?>>ТаблицаЗначений; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(3348,20)}: Тип не определен (Запрос)
Запрос = Новый <<?>>Запрос; (Проверка: Тонкий клиент)
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(4230,18)}: Тип не определен (ТаблицаЗначений)
Условия = Новый <<?>>ТаблицаЗначений; (Проверка: Тонкий клиент)
38. VladimirB 16 20.04.19 18:09 Сейчас в теме
(33) Верните все как было изначально
Попробуйте пройтись по всем справочникам в конфигурации
Открывайте Прочее -> Предопределенные
может в каком-нибудь встретите этот код
3. Эвелина 20.04.19 15:42 Сейчас в теме
Не могу знать. Это ошибка происходит на этапе когда идет обновление у же при запуске из конфы 1С. Как посмотреть, может скажете?
4. VladimirB 16 20.04.19 15:53 Сейчас в теме
(3) Вас из программы не выкидывает?
6. Эвелина 20.04.19 16:02 Сейчас в теме
(4) как ошибка выскакивает-предлагает или закрыть или перезагрузить
8. acanta 20.04.19 16:07 Сейчас в теме
Какая разница между тем, скажете ли вы это пользователю/заказчику или напишите здесь на форуме?
Вы потеряете этого клиента, если скажете что нужен программист?
По существу, возможно задвоились предопределенные элементы и достаточно будет исправить код элемента вручную.
Но надо найти какого именно.
10. Эвелина 20.04.19 16:14 Сейчас в теме
(8) нет, я главный бухгалтер.)))
34. ishelper 20.04.19 17:39 Сейчас в теме
Суббота, вечер, код 1С - романтика!

"Вот и встретились два одиночества" - главбух и программист. Ну что же, вдруг у них что-то получится? ;-)
36. Эвелина 20.04.19 17:41 Сейчас в теме
(34)вообще не смешно...знаете ка мне щас хреново, у меня отчетный период, я такую тупость натворила...
53. ishelper 20.04.19 21:12 Сейчас в теме
(36)
вообще не смешно...
Да уж, смешного мало: на программу 60 тысяч с хвостиком - нашли, на ИТС - нашли (или... сэкономили?), на главбуха - деньги есть, а на программиста - ни копейки не осталось?

Смешного тут только то, что на профильном форуме сами же 1Сники помогают убедиться, что эта экономия была правильной, что без них можно и нужно обходиться!

Как результат - 4 часа лечения по словесному описанию фотографии больного, с соответствующим результатом.

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

P.S. Если не зацикливаться на откате к исходному варианту (кстати, а что он даст? обновляться-то все равно надо), то предполагаю такой вариант исправления ситуации: Отладчиком выявляем проблемные элементы и пишем обработку, которая из другой базы подключится к проблемной через COM и программно внесет необходимые изменения в данные.

Работа, ясный пень, не для дилетанта.

Впрочем, дело хозяйское.
55. Эвелина 20.04.19 21:34 Сейчас в теме
(53) Я не обидчивая...сколько стоить будет то что вы сказали?
39. VladimirB 16 20.04.19 18:13 Сейчас в теме
37. Эвелина 20.04.19 18:07 Сейчас в теме
Вариантов нет по откату обновления? кроме как из копии?
40. VladimirB 16 20.04.19 18:28 Сейчас в теме
(37)
Можно попробовать если у вас есть полная конфигурация
КА 2.4 2_4_7_141 (не обновление)
42. Эвелина 20.04.19 18:30 Сейчас в теме
41. VladimirB 16 20.04.19 18:29 Сейчас в теме
43. Эвелина 20.04.19 18:31 Сейчас в теме
(41) коды все пустые, ну те что смотрю
44. VladimirB 16 20.04.19 18:31 Сейчас в теме
Все справочники просмотрели?
45. Эвелина 20.04.19 18:35 Сейчас в теме
46. Эвелина 20.04.19 18:43 Сейчас в теме
47. VladimirB 16 20.04.19 18:48 Сейчас в теме
(37)
Сделайте сначала копию

Конфигурация
Конфигурация базы данных
Вернуться к конфигурации БД


Никогда этого не делал. Результат не знаю
Но копия если что у вас будет
48. VladimirB 16 20.04.19 18:56 Сейчас в теме
(37)
2 вариант
Также сделайте копию
создайте чистую конфигурацию КА 2.4 2_4_7_141
зайдите в конфигуратор (в чистую 141)

Открыть Конфигурацию
Конфигурация -> Сохранить конфигурацию в файл

Открываем вашу рабочую (147)
также заходим в конфигуратор
Открыть Конфигурацию
Конфигурация -> Загрузить конфигурацию из файла
указываем файл с конфигурацией (141)

Пробуйте
49. GeraltSnow 171 20.04.19 18:58 Сейчас в теме
Если обновление проходило через стандартную обработку обновления конфигурации, то резервная копия базы до обновления лежит по адресу C:\users\UserName\AppData\Local\Temp, либо C:\users\UserName\AppData\Local\TMP
50. VladimirB 16 20.04.19 19:02 Сейчас в теме
(49) или темр?
нет каталога tmp (хотя случалось обновлял)
не знал про это
51. GeraltSnow 171 20.04.19 19:05 Сейчас в теме
(50) Название каталога временных файлов зависит от того, что написано в Path. Я когда выносил темп в рамдиск для теста производительности 1С что-то запорол и теперь часть программ сохраняет данные в /Temp, а часть в /TMP.
52. Эвелина 20.04.19 19:14 Сейчас в теме
(49) Обновление делала через Конфигуратор
54. acanta 20.04.19 21:23 Сейчас в теме
Если вы ищете специалиста по исправлению ошибки обновления типовой конфигурации, то эту работу могут бойкотировать без объяснения причин.
Субботняя школа.
56. Эвелина 20.04.19 21:35 Сейчас в теме
(54)все типовое, кроме того Итс Техно выписывается - просто я сама все делала...
57. ishelper 20.04.19 21:37 Сейчас в теме
(54)
эту работу могут бойкотировать без объяснения причин.
А что, существует работа, которую нельзя игнорировать "без объяснения причин"? ;)

(55)
сколько стоить будет то что вы сказали?
Это надо спрашивать не у меня, а у того, кто возьмется.
58. Эвелина 20.04.19 21:49 Сейчас в теме
(57) вот так и появляются недопонимания между бухгалтерами и 1С никами: у нас горят отчеты и мы в выходные сидим работаем, что бы успеть - а у 1Сников выходные.....поэтому и приходится самим пытаться сделать!
60. acanta 20.04.19 22:00 Сейчас в теме
В договоре поддержки Итс техно условия обновления и график работы обычно указан.
Бухгалтер же не будет в выходные делать отчеты для какого нибудь другого предприятия, у которого его штатный глав бух взял выходной, только потому что директор попросил срочно.
У бухгалтеров так не делается. Почему же вы не считаете нормальным обьявить тендер на начислить зарплату за февраль или по теме на форуме разнесите кассу и банк за недельку.
61. ishelper 20.04.19 22:03 Сейчас в теме
(60)
В договоре поддержки Итс техно условия обновления и график работы обычно указан.
Не обнадеживайте автора понапрасну: ИТС Техно не включает в себя работу по обновлению, это только доступ к обновлениям.
62. Эвелина 20.04.19 22:05 Сейчас в теме
(60) это вы себе или мне - глав.бухгалтеру написали? если надо -каждый бухгалтер сидит и работает в выходной!
63. acanta 20.04.19 22:12 Сейчас в теме
(62) Я имею ввиду, что у вас нет программиста.
Если у вас на предприятии нет глав.буха, это проблема владельца.
Главбух обычно пользуется услугами программиста, выбранного хозяином или приглашает лично собственного.
Вы отказались от услуг программиста, выбранного хозяином и ваш работодатель об этом извещен?
59. Эвелина 20.04.19 21:50 Сейчас в теме
Всем хороших выходных)))) и спасибо, всем кто хотел мне помочь!
64. coder108 21.04.19 11:02 Сейчас в теме
База файловая или клиент-серверная?
65. Эвелина 21.04.19 16:34 Сейчас в теме
(64)База была серверная, и всем спасибо, знакомый таки помог программно исправить ошибку...спасибо за помощь
Оставьте свое сообщение
Вакансии
Руководитель направления 1С
Москва
зарплата от 350 000 руб.
Полный день

1С Программист
Москва
зарплата от 180 000 руб.
Полный день

Программист 1С
Москва
зарплата от 180 000 руб. до 220 000 руб.
Полный день

Аналитик 1С / Бизнес-аналитик
Нижний Новгород
зарплата от 100 000 руб. до 250 000 руб.
Временный (на проект)

Программист 1С
Москва
зарплата от 250 000 руб.
Полный день