Заполняем или изменяем регистр без перепроведения документа

16.11.15

Разработка - Механизмы платформы 1С

При разработке дополнительного функционала может возникнуть необходимость добавить новый регистр в уже существующие документы. Или изменить принцип записи в регистр (например, изменился алгоритм расчета какого-либо показателя). Обычно после исправления мы запускаем перепроведение всех документов. Но это долго, попробуем рассмотреть другой вариант решения.

Задача:

Заказчик хочет добавить новый регистр накопления "ПродажиУслуг", который заполняется на основании табличной части "Услуги" документа "Реализация товаров и услуг". Но проблема в том, что база ведется уже давно и накопилось очень много документов. Полное перепроведение не желательно, так как может занять слишком длительное время.

Решение:

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

Подготовка:

1. Создадим новый регистр накопления "ПродажиУслуг" (измерение – Номенклатура, ресурс – Сумма).

2. В документе "Реализация товаров и услуг" добавим в "Движения" созданный регистр накопления.
Нужно, конечно, добавить в процедуру проведения документа запись в данный регистр, но для решения данной задачи это не принципиально.

3. Всё, на этом подготовка конфигурации выполнена, можно приступать к созданию обработки.

Обработка:

1. Создаем внешнюю обработку "ЗаполнениеРегистраПродажиУслуг".

2. Создаем форму и в ней новую команду – "ЗаполнитьРегистр",

3. Размещаем данную команду в командной панели формы и переходим к описанию процедуры.
Должно получится примерно так:

4. В процедуре находим все проведенные документы "Реализация товаров и услуг" и их табличные части с помощью запроса.

5. Создаем наборы записей для регистра накопления "ПродажиУслуг" с отбором по регистратору.
Данный отбор позволяет связать набор записей регистра накопления и выбранный документ.

6. Добавляем в набор записей необходимые данные из табличной части "Услуги".

7. Записываем набор записей регистра накопления "ПродажиУслуг".
В итоге должен получится примерно такой код:

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
| РеализацияТоваровУслуг.Ссылка,
| РеализацияТоваровУслуг.Дата,
| РеализацияТоваровУслуг.Услуги.(
| Номенклатура,
| Сумма
| )
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Проведен";

Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();

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

8. Готово.
После выполнения данной обработки у документов "Реализация товаров и услуг", у которых есть заполненная табличная часть "Услуги" появятся записи в регистре накопления "ПродажиУслуг". Эта операция будет выполнятся гораздо быстрее, чем если бы мы перепроводили все документы.

Примечание:

Этот механизм положен в основу типового Допроведения документов, например в конфигурации "Управление Производственным Предприятием". Допроведение документов выполняется когда не требуется оперативно выполнять какие-либо движения. Например, необязательно списывать партии в момент оперативного проведения документа, так как это занимает продолжительное время. Допроведение может запускается по регламентному заданию и записывать наборы записей регистров к документам, то есть все длительные проверки и операции записи выполнятся в удобное для пользователей время.

Перепроведение доработка новый регистр набор записей отложенное проведение

См. также

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

Обмен между базами 1C Администрирование СУБД Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    4420    dsdred    53    

69

Как готовить и есть массивы

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    5269    YA_418728146    25    

62

Планы обмена VS История данных

Обмен между базами 1C Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    6380    dsdred    36    

111

1С-ная магия

Механизмы платформы 1С Бесплатно (free)

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

06.10.2023    18458    SeiOkami    46    

118

Дефрагментация и реиндексация после перехода на платформу 8.3.22

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    12069    human_new    27    

74

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    8795    YA_418728146    6    

141

Внешние компоненты Native API на языке Rust - Просто!

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    6271    sebekerga    54    

94

Все скопируем и вставим! (Буфер обмена в 1С 8.3.24)

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    15945    SeiOkami    31    

103
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. rezerv 18.11.15 09:57 Сейчас в теме
Большое спасибо за информацию.
В верхней части статьи регистр называется ПродажиУслуг, а в коде ПродажиУслуги?
3. mrXoxot 2816 18.11.15 12:24 Сейчас в теме
(1) rezerv, (2) karapuzzzz,
Спасибо, Ваши замечания поправил.
2. karapuzzzz 63 18.11.15 12:19 Сейчас в теме
А почему вместо
НаборЗаписейПродажиУслуг.Отбор["Регистратор"].Использование = Истина;
    НаборЗаписейПродажиУслуг.Отбор["Регистратор"].Значение    = Выборка.Ссылка;
    НаборЗаписейПродажиУслуг.Отбор["Регистратор"].ВидСравнения  = ВидСравнения.Равно;

не использовать
НаборЗаписейПродажиУслуг.Отбор.Регистратор.Установить(Выборка.Ссылка);
olo_lo4; Prikum; vladisemen; Izumov; PhoenixAOD; Evgl2004; AneJIbcuH; +7 Ответить
4. IgorS 43 18.11.15 16:26 Сейчас в теме
Судя по количеству плюсовавших, читать жёлтые книжки начинающие спецы 1С не пробовали :(
PhoenixAOD; kot26rus; lx@; +3 4 Ответить
5. v.yaunzhekars@gmail.com 19.11.15 11:59 Сейчас в теме
(4) IgorS,
Какие книги порекомендуете?
6. DrAku1a 1679 24.11.15 02:42 Сейчас в теме
Берём отладчик запросов (для управляемых форм 8.3 - соответственно, консоль запросов с Инфостарта, в которой есть возможность обрабатывать результат) - пишем простой запрос, которым получаем все услуги с итогами по документам, что-то вроде:
"ВЫБРАТЬ Ссылка, Ссылка.Дата КАК Период, Номенклатура, Сумма ИЗ Документ.РеализацияТоваровУслуг.Услуги ГДЕ Ссылка.Проведен ИТОГИ ПО Ссылка"
кстати, также можно и упорядочить.
выполняем, запрос - переходим к обработке результата. Там пишем код:
НЗ=неопределено;
Для каждого Строчка из РезультатЗапросаТаблицей Цикл
	Если Строчка.Номенклатура<>Null Тогда
		ЗаполнитьЗначенияСвойств(НЗ.Добавить(), Строчка);
		Продолжить;
	ИначеЕсли НЗ<>неопределено Тогда
		НЗ.ОбменДанными.Загрузка = Истина; //отключаем встроенные обработчики событий
		НЗ.Записать(Истина);
	КонецЕсли;
	НЗ = РегистрыНакопления.ПродажиУслуг.СоздатьНаборЗаписей();
	НЗ.Отбор.Регистратор.Установить(Строчка.Ссылка);
КонецЦикла;
Если НЗ<>неопределено Тогда
	НЗ.ОбменДанными.Загрузка = Истина; //отключаем встроенные обработчики событий
	НЗ.Записать(Истина);
КонецЕсли;
Показать

Если документов много, то рекомендую для циклов реализовать счетчик, а сами документы в запросе упорядочивать:
//Код для "Обычного приложения" (неуправляемые формы)
КолВо = РезультатЗапросаТаблицей.Количество(); //+++
стрКолВо = " / "+КолВо+" ("; //+++
сч = 0; //+++
НЗ=неопределено;
Для каждого Строчка из РезультатЗапросаТаблицей Цикл
	сч = сч + 1; // +++
	Если Строчка.Номенклатура<>Null Тогда
		ЗаполнитьЗначенияСвойств(НЗ.Добавить(), Строчка);
		Продолжить;
	ИначеЕсли НЗ<>неопределено Тогда
		НЗ.ОбменДанными.Загрузка = Истина; //отключаем встроенные обработчики событий
		НЗ.Записать(Истина);
	КонецЕсли;
	НЗ = РегистрыНакопления.ПродажиУслуг.СоздатьНаборЗаписей();
	НЗ.Отбор.Регистратор.Установить(Строчка.Ссылка);
	Состояние(""+сч+стрКолВо+Окр(сч*100/КолВо, 1)+"%) "+Строчка.Ссылка); // +++
	ОбработкаПрерыванияПользователя(); // +++
КонецЦикла;
Если НЗ<>неопределено Тогда
	НЗ.ОбменДанными.Загрузка = Истина; //отключаем встроенные обработчики событий
	НЗ.Записать(Истина);
КонецЕсли;
Состояние(); // +++ 
Сообщить("Выполнение завершено."); // +++
Показать
7. q_i 577 25.11.15 12:59 Сейчас в теме
А потом если нужно будет поменять алгоритм формирования движения по новому регистру, то придётся изменять соответствующий код и в модуле документа, и в обработке. Возможно, для разового запуска это и не критично, но всё равно я бы сделал как-то так:
1. В модуле документа РеализацияТоваровУслуг создаем процедуру ОтразитьПродажиУслуг(...), которая заполняет наборы записей по новому регистру и добавляем её вызов в ОбработкаПроведения().
2. Объявляем процедуру ОтразитьПродажиУслуг(...) экспортной.
3. В обработке получаем список документов РеализацияТоваровУслуг, для которых нужно создать движения, и для каждого объекта вызываем ДокОбъект.ОтразитьПродажиУслуг(...), после чего записываем движения по этому регистру.
Programmer-1C; Amara; RustIG; mrXoxot; +4 Ответить
8. mrXoxot 2816 25.11.15 14:47 Сейчас в теме
(7) q_i,
Да, это достойное решение. Спасибо!
Но обычно в типовых сначала готовятся куча таблиц и движений, а в конце одним махом записывают все движения. Это позволяет сократить время на запись. Поэтому не всегда будет удобно делать отдельное проведение, иногда стоит вписываться в типовой механизм.
9. AneJIbcuH 37 28.11.15 15:41 Сейчас в теме
Большое спасибо за информацию, как раз необходимо было. А то есть у нас такая проблема в УПП, когда бухгалтер, например, в реализации вручную поправит проводки, а там ещё есть движения по Упр учету, то после перепроведения проводки восстанавливать приходится :)

Внесу свою лепту, я запрос всё же бы так построил:

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	РеализацияТоваровУслугТовары.Ссылка,
|	РеализацияТоваровУслугТовары.Ссылка.Дата КАК Период,
|	РеализацияТоваровУслугТовары.Номенклатура,
|	РеализацияТоваровУслугТовары.Сумма
|ИЗ
|	Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
|ГДЕ
|	РеализацияТоваровУслугТовары.Ссылка.Проведен
|
|УПОРЯДОЧИТЬ ПО
|	РеализацияТоваровУслугТовары.Ссылка.МоментВремени
|ИТОГИ ПО
|	РеализацияТоваровУслугТовары.Ссылка";

Результат = Запрос.Выполнить();
ВыборкаСсылка = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

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

10. AneJIbcuH 37 28.11.15 15:43 Сейчас в теме
Нечто подобное как раз озвучил уважаемый DrAku1a, но далее его алгоритм не совсем понятен.
11. RustIG 1351 05.09.17 10:36 Сейчас в теме
(0) спасибо за идею! актуально
12. devlog 29.01.20 22:38 Сейчас в теме
Респект таким людям!
Flextor74; +1 Ответить
13. Programmer-1C 142 05.02.22 12:22 Сейчас в теме
Спасибо, пригодилось!
Оставьте свое сообщение