Помогите, уважаемые программисты!
Обновила Конфигурацию КА 2.4 2_4_7_141 до 2_4_7_147. Вроде обновилась из конфы. Вспомнила, что забыла сделать копию базы. А когда запустила 1С обновление не прошло, выскочила ошибка: {ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(66)}: Ошибка при вызове метода контекста (Записать) Объект.Записать(); по причине: Значение "002087" поля "Код" не уникально. Откатить назад -невозможно. Как поправить програмно?
Я просто продвинутый пользователь. Эти вещи лечить не умею. Помогите плиз!
Обновила Конфигурацию КА 2.4 2_4_7_141 до 2_4_7_147. Вроде обновилась из конфы. Вспомнила, что забыла сделать копию базы. А когда запустила 1С обновление не прошло, выскочила ошибка: {ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(66)}: Ошибка при вызове метода контекста (Записать) Объект.Записать(); по причине: Значение "002087" поля "Код" не уникально. Откатить назад -невозможно. Как поправить програмно?
Я просто продвинутый пользователь. Эти вещи лечить не умею. Помогите плиз!
По теме из базы знаний
- Автоматическое заполнение реквизитов контрагентов по ИНН для ERP 2.4, ERP 2.2, УТ 11.5, УТ 11.4, УТ 11.3, УТ 11.2, КА 2.4, КА 2.2, КА 2.0 и БП 3.0 (расширение конфигурации)
- Выгрузка УПД из УТ 11.5, УТ 11.4, БП 3.0, УНФ 1.6, КА 2.4 и ERP 2.4 для OZON и Яндекс
- Заполнение трудовой функции в штатном расписании (ERP 2.4, ERP 2.5, КА 2.4, КА 2.5, ЗУП)
- [ED] Обмен для предыдущих версий - КА 2.2, КА 2.4, КА 2.5 с EnterpriseData (универсальный формат обмена), правила обмена
- Cкорость продаж и ABC-анализ. УТ 11.4, УТ 11.5, КА 2.4, КА 2.5 ERP 2.4, ERP 2.5
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1) В какой-то справочник пытается записаться новый элемент с кодом 002087
Чтобы точно знать - нужно узнать какого типа "Объект" . Можно узнать через отладчик. (Возможно это не ваш путь.)
Если есть предположение какой это справочник, тогда откройте его, найдите элемент с кодом "002087" и измените ему код.
Перезапустите программу.
Чтобы точно знать - нужно узнать какого типа "Объект" . Можно узнать через отладчик. (Возможно это не ваш путь.)
Если есть предположение какой это справочник, тогда откройте его, найдите элемент с кодом "002087" и измените ему код.
Перезапустите программу.
(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
| И &УсловиеПоДопИсточникамСсылкам
| И &УсловиеПоДопИсточникамРегистрам
| И &УсловиеПоСтраницам";
Если ЭтоДокумент Или ПараметрыПостроения.ПостраничнаяВыборка Тогда
ТекстЗапроса = ТекстЗапроса + "
|
|УПОРЯДОЧИТЬ ПО
| &ПорядокВыборки";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + "
|;
|УНИЧТОЖИТЬ
| #ВТЗаблокированоСсылка";
УстановитьПоляУпорядочиванияСсылок(ПараметрыПостроения, ЭтоДокумент);
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ВТЗаблокированоСсылка","ВТЗаблокировано" + ИмяОбъекта);
ТекстЗапроса = СтрЗаменить(ТекстЗапроса,"#ТаблицаОбъектаИзменения", ПолноеИмяОбъекта + ".Изменения");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса,"#ТаблицаОбъекта", ПолноеИмяОбъекта);
УстановитьРазмерВыборки(ТекстЗапроса, ДополнительныеПараметры);
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц();
СоздатьВременнуюТаблицуЗаблокированныхДляЧтенияИИзмененияДан ных(Очередь, ПолноеИмяОбъекта, МенеджерВременныхТаблиц);
ДобавитьПроверкуБлокировкиДополнительныхИсточников(Очередь, ТекстЗапроса, ПолноеИмяОбъекта, Неопределено, МенеджерВременныхТаблиц, Ложь, ДополнительныеПараметры);
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.УстановитьПараметр("ТекущаяОчередь", ОчередьСсылкой(Очередь));
УстановитьПоляПоСтраницам(Запрос, ПараметрыПостроения);
Если ЭтоДокумент Или ПараметрыПостроения.ПостраничнаяВыборка Тогда
УстановитьПорядокПоСтраницам(Запрос, ПараметрыПостроения);
КонецЕсли;
Возврат ВыбратьДанныеДляОбработки(Запрос, ПараметрыПостроения);
КонецФункции
// Создает временную таблицу ссылок, которые не обработаны в текущей очереди
// и не заблокированы меньшими очередями.
// Имя таблицы: ВТДляОбработки<ИмяОбъекта>, например ВТДляОбработкиНоменклатура.
// Колонки таблицы
// * Ссылка - ЛюбаяСсылка.
//
// Параметры:
// Очередь - Число - очередь обработки, в которой выполняется текущий обработчик.
// ПолноеИмяОбъекта - Строка - полное имя объекта, для которого выполняется проверка, например, Справочник.Номенклатура.
// МенеджерВременныхТаблиц - МенеджерВременныхТаблиц - менеджер, в котором будет создана временная таблица.
// ДополнительныеПараметры - Структура - см. ОбновлениеИнформационнойБазы.ДополнительныеПараметрыВыборкиДанныхДляОбработки.
//
// Возвращаемое значение:
// Структура - результат формирования временной таблицы:
// * ЕстьЗаписиВоВременнойТаблице - Булево - в создаваемой таблице есть хотя бы одна запись. Записей может не быть по
// двум причинам
// - все обработано или все, ч
////////////////////////////////////////////////////////////
// Процедуры и функции для использования в обработчиках обновления.
//
// Записывает изменения в переданном объекте.
// Для использования в обработчиках обновления.
//
// Параметры:
// Данные - Произвольный - объект, набор записей или менеджер константы, который
// необходимо записать.
// РегистрироватьНаУзлахПлановОбмена - Булево - включает регистрацию на узлах планов обмена при записи объекта.
// ВключитьБизнесЛогику - Булево - включает бизнес-логику при записи объекта.
//
Процедура ЗаписатьДанные(Знач Данные, Знач РегистрироватьНаУзлахПлановОбмена = Неопределено,
Знач ВключитьБизнесЛогику = Ложь) Экспорт
Данные.ОбменДанными.Загрузка = Не ВключитьБизнесЛогику;
Данные.ДополнительныеСвойства.Вставить("РегистрироватьНаУзлахПлановОбменаПриОбновленииИБ", РегистрироватьНаУзлахПлановОбмена);
Если РегистрироватьНаУзлахПлановОбмена = Неопределено
Или Не РегистрироватьНаУзлахПлановОбмена Тогда
Данные.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
КонецЕсли;
Данные.Записать();
ОтметитьВыполнениеОбработки(Данные);
КонецПроцедуры
// Записывает изменения в переданном объекте ссылочного типа.
// Для использования в обработчиках обновления.
//
// Параметры:
// Объект - Произвольный - записываемый объект ссылочного типа. Например, СправочникОбъект.
// РегистрироватьНаУзлахПлановОбмена - Булево - включает регистрацию на узлах планов обмена при записи объекта.
// ВключитьБизнесЛогику - Булево - включает бизнес-логику при записи объекта.
// ДокументРежимЗаписи - ДокументРежимЗаписи - имеет смысл только для данных типа ДокументОбъект - режим
// записи документа.
// Если параметр не передан, то документ записывается в режиме "Запись".
//
Процедура ЗаписатьОбъект(Знач Объект, Знач РегистрироватьНаУзлахПлановОбмена = Неопределено,
Знач ВключитьБизнесЛогику = Ложь, ДокументРежимЗаписи = Неопределено) Экспорт
Объект.ДополнительныеСвойства.Вставить("РегистрироватьНаУзлахПлановОбменаПриОбновленииИБ", РегистрироватьНаУзлахПлановОбмена);
Объект.ОбменДанными.Загрузка = Не ВключитьБизнесЛогику;
Если РегистрироватьНаУзлахПлановОбмена = Неопределено
Или Не РегистрироватьНаУзлахПлановОбмена
И Не Объект.ЭтоНовый() Тогда
Объект.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
КонецЕсли;
Если ДокументРежимЗаписи <> Неопределено Тогда
Если ТипЗнч(ДокументРежимЗаписи) <> Тип("РежимЗаписиДокумента") Тогда
ТекстИсключения = НСтр("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
| И &УсловиеПоДопИсточникамСсылкам
| И &УсловиеПоДопИсточникамРегистрам
| И &УсловиеПоСтраницам";
Если ЭтоДокумент Или ПараметрыПостроения.ПостраничнаяВыборка Тогда
ТекстЗапроса = ТекстЗапроса + "
|
|УПОРЯДОЧИТЬ ПО
| &ПорядокВыборки";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + "
|;
|УНИЧТОЖИТЬ
| #ВТЗаблокированоСсылка";
УстановитьПоляУпорядочиванияСсылок(ПараметрыПостроения, ЭтоДокумент);
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ВТЗаблокированоСсылка","ВТЗаблокировано" + ИмяОбъекта);
ТекстЗапроса = СтрЗаменить(ТекстЗапроса,"#ТаблицаОбъектаИзменения", ПолноеИмяОбъекта + ".Изменения");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса,"#ТаблицаОбъекта", ПолноеИмяОбъекта);
УстановитьРазмерВыборки(ТекстЗапроса, ДополнительныеПараметры);
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц();
СоздатьВременнуюТаблицуЗаблокированныхДляЧтенияИИзмененияДан
ДобавитьПроверкуБлокировкиДополнительныхИсточников(Очередь, ТекстЗапроса, ПолноеИмяОбъекта, Неопределено, МенеджерВременныхТаблиц, Ложь, ДополнительныеПараметры);
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.УстановитьПараметр("ТекущаяОчередь", ОчередьСсылкой(Очередь));
УстановитьПоляПоСтраницам(Запрос, ПараметрыПостроения);
Если ЭтоДокумент Или ПараметрыПостроения.ПостраничнаяВыборка Тогда
УстановитьПорядокПоСтраницам(Запрос, ПараметрыПостроения);
КонецЕсли;
Возврат ВыбратьДанныеДляОбработки(Запрос, ПараметрыПостроения);
КонецФункции
// Создает временную таблицу ссылок, которые не обработаны в текущей очереди
// и не заблокированы меньшими очередями.
// Имя таблицы: ВТДляОбработки<ИмяОбъекта>, например ВТДляОбработкиНоменклатура.
// Колонки таблицы
// * Ссылка - ЛюбаяСсылка.
//
// Параметры:
// Очередь - Число - очередь обработки, в которой выполняется текущий обработчик.
// ПолноеИмяОбъекта - Строка - полное имя объекта, для которого выполняется проверка, например, Справочник.Номенклатура.
// МенеджерВременныхТаблиц - МенеджерВременныхТаблиц - менеджер, в котором будет создана временная таблица.
// ДополнительныеПараметры - Структура - см. ОбновлениеИнформационнойБазы.ДополнительныеПараметрыВыборкиДанныхДляОбработки.
//
// Возвращаемое значение:
// Структура - результат формирования временной таблицы:
// * ЕстьЗаписиВоВременнойТаблице - Булево - в создаваемой таблице есть хотя бы одна запись. Записей может не быть по
// двум причинам
// - все обработано или все, ч
(11)
Найдите здесь 66 строку.
Попробуйте вместо нее написать так;
возможно у вас обновление пройдет.
Внизу в окне сообщений появятся сообщение об ошибке - Какой объект не изменился/не добавился
Найдите здесь 66 строку.
Попробуйте вместо нее написать так;
Попытка
Объект.Записать();
Исключение
Сообщить("Произошла ошибка в объекте - "+ТипЗнч(Объект));
КонецПопытки;
возможно у вас обновление пройдет.
Внизу в окне сообщений появятся сообщение об ошибке - Какой объект не изменился/не добавился
(16)
попробуйте этот код.
Возможно вы не потеряете новый объект
Попытка
Объект.Записать();
Исключение
Если СокрЛП(Объект.Код)="002087" Тогда
_НовыйКод="102087";
Объект.Код=_НовыйКод;
Попытка
Объект.Записать();
Исключение
Сообщить("Все-равно произошла ошибка в объекте - "+ТипЗнч(Объект));
КонецПопытки;
Иначе
Сообщить("Произошла ошибка в объекте - "+ТипЗнч(Объект));
КонецЕсли;
КонецПопытки;
Показатьпопробуйте этот код.
Возможно вы не потеряете новый объект
(17)При вызове обработчика обновления:
"Справочники.РегламентированныеОтчеты.ЗаполнитьСписокРегламентированныхОтчетов()"
произошла ошибка:
"{Обработка.ОбновлениеРегламентированнойОтчетности.МодульОбъекта(21)}: Ошибка при вызове метода контекста (НайтиПоРеквизиту)
НайденныйЭлемент = РегламОтчеты.НайтиПоРеквизиту("ИсточникОтчета", СокрЛП(Источник));
по причине:
В данной транзакции уже происходили ошибки!".
это новая ошибка...другая совершенно((((
"Справочники.РегламентированныеОтчеты.ЗаполнитьСписокРегламентированныхОтчетов()"
произошла ошибка:
"{Обработка.ОбновлениеРегламентированнойОтчетности.МодульОбъекта(21)}: Ошибка при вызове метода контекста (НайтиПоРеквизиту)
НайденныйЭлемент = РегламОтчеты.НайтиПоРеквизиту("ИсточникОтчета", СокрЛП(Источник));
по причине:
В данной транзакции уже происходили ошибки!".
это новая ошибка...другая совершенно((((
(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)}: Тип не определен (ТаблицаЗначений)
Условия = Новый <<?>>ТаблицаЗначений; (Проверка: Тонкий клиент)
ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(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)}: Тип не определен (ТаблицаЗначений)
Условия = Новый <<?>>ТаблицаЗначений; (Проверка: Тонкий клиент)
Не могу знать. Это ошибка происходит на этапе когда идет обновление у же при запуске из конфы 1С. Как посмотреть, может скажете?
Какая разница между тем, скажете ли вы это пользователю/заказчику или напишите здесь на форуме?
Вы потеряете этого клиента, если скажете что нужен программист?
По существу, возможно задвоились предопределенные элементы и достаточно будет исправить код элемента вручную.
Но надо найти какого именно.
Вы потеряете этого клиента, если скажете что нужен программист?
По существу, возможно задвоились предопределенные элементы и достаточно будет исправить код элемента вручную.
Но надо найти какого именно.
Суббота, вечер, код 1С - романтика!
"Вот и встретились два одиночества" - главбух и программист. Ну что же, вдруг у них что-то получится? ;-)
"Вот и встретились два одиночества" - главбух и программист. Ну что же, вдруг у них что-то получится? ;-)
(36)
Смешного тут только то, что на профильном форуме сами же 1Сники помогают убедиться, что эта экономия была правильной, что без них можно и нужно обходиться!
Как результат - 4 часа лечения по словесному описанию фотографии больного, с соответствующим результатом.
Хотя давно можно было договориться об оплате и предоставить удаленный доступ к базе профессионалу (свою кандидатуру не предлагаю по понятным причинам).
P.S. Если не зацикливаться на откате к исходному варианту (кстати, а что он даст? обновляться-то все равно надо), то предполагаю такой вариант исправления ситуации: Отладчиком выявляем проблемные элементы и пишем обработку, которая из другой базы подключится к проблемной через COM и программно внесет необходимые изменения в данные.
Работа, ясный пень, не для дилетанта.
Впрочем, дело хозяйское.
вообще не смешно...
Да уж, смешного мало: на программу 60 тысяч с хвостиком - нашли, на ИТС - нашли (или... сэкономили?), на главбуха - деньги есть, а на программиста - ни копейки не осталось?
Смешного тут только то, что на профильном форуме сами же 1Сники помогают убедиться, что эта экономия была правильной, что без них можно и нужно обходиться!
Как результат - 4 часа лечения по словесному описанию фотографии больного, с соответствующим результатом.
Хотя давно можно было договориться об оплате и предоставить удаленный доступ к базе профессионалу (свою кандидатуру не предлагаю по понятным причинам).
P.S. Если не зацикливаться на откате к исходному варианту (кстати, а что он даст? обновляться-то все равно надо), то предполагаю такой вариант исправления ситуации: Отладчиком выявляем проблемные элементы и пишем обработку, которая из другой базы подключится к проблемной через COM и программно внесет необходимые изменения в данные.
Работа, ясный пень, не для дилетанта.
Впрочем, дело хозяйское.
(37)
2 вариант
Также сделайте копию
создайте чистую конфигурацию КА 2.4 2_4_7_141
зайдите в конфигуратор (в чистую 141)
Открыть Конфигурацию
Конфигурация -> Сохранить конфигурацию в файл
Открываем вашу рабочую (147)
также заходим в конфигуратор
Открыть Конфигурацию
Конфигурация -> Загрузить конфигурацию из файла
указываем файл с конфигурацией (141)
Пробуйте
2 вариант
Также сделайте копию
создайте чистую конфигурацию КА 2.4 2_4_7_141
зайдите в конфигуратор (в чистую 141)
Открыть Конфигурацию
Конфигурация -> Сохранить конфигурацию в файл
Открываем вашу рабочую (147)
также заходим в конфигуратор
Открыть Конфигурацию
Конфигурация -> Загрузить конфигурацию из файла
указываем файл с конфигурацией (141)
Пробуйте
Если обновление проходило через стандартную обработку обновления конфигурации, то резервная копия базы до обновления лежит по адресу C:\users\UserName\AppData\Local\Temp, либо C:\users\UserName\AppData\Local\TMP
(50) Название каталога временных файлов зависит от того, что написано в Path. Я когда выносил темп в рамдиск для теста производительности 1С что-то запорол и теперь часть программ сохраняет данные в /Temp, а часть в /TMP.
Если вы ищете специалиста по исправлению ошибки обновления типовой конфигурации, то эту работу могут бойкотировать без объяснения причин.
Субботняя школа.
Субботняя школа.
В договоре поддержки Итс техно условия обновления и график работы обычно указан.
Бухгалтер же не будет в выходные делать отчеты для какого нибудь другого предприятия, у которого его штатный глав бух взял выходной, только потому что директор попросил срочно.
У бухгалтеров так не делается. Почему же вы не считаете нормальным обьявить тендер на начислить зарплату за февраль или по теме на форуме разнесите кассу и банк за недельку.
Бухгалтер же не будет в выходные делать отчеты для какого нибудь другого предприятия, у которого его штатный глав бух взял выходной, только потому что директор попросил срочно.
У бухгалтеров так не делается. Почему же вы не считаете нормальным обьявить тендер на начислить зарплату за февраль или по теме на форуме разнесите кассу и банк за недельку.
(62) Я имею ввиду, что у вас нет программиста.
Если у вас на предприятии нет глав.буха, это проблема владельца.
Главбух обычно пользуется услугами программиста, выбранного хозяином или приглашает лично собственного.
Вы отказались от услуг программиста, выбранного хозяином и ваш работодатель об этом извещен?
Если у вас на предприятии нет глав.буха, это проблема владельца.
Главбух обычно пользуется услугами программиста, выбранного хозяином или приглашает лично собственного.
Вы отказались от услуг программиста, выбранного хозяином и ваш работодатель об этом извещен?
Внимание! Тема сдана в архив
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот