Расширенные регистры

Публикация № 1729178 26.09.22

Пользовательские инструменты - Адаптация типовых решений

расширение регистров накопления

Продолжаем разговор о возможности функционального подхода при создании конфигураций.

В предыдущей статье //razrabotki.corpnova.ru/public/1721980/ был предложен т.н. функциональный подход при создании конфигураций. Суть его заключается в том, что результат проведения документа зависит только от самого документа, но не от окружения. Было показано, что простое расширение регистра накопления позволяет решать частную задачу резервирования в функциональном стиле. Еще одно расширение регистров накопления, которое я хочу предложить здесь, дает возможность решать в функциональном стиле уже очень широкий круг задач. Возможно, что вообще все или почти все.

Для начала вспомним, как устроен регистр накопления. Мы делаем записи в регистр. Записи могут быть двух видов: "приход" или "расход". На основании этих записей система предоставляет в наше распоряжение виртуальную таблицу остатков. Остатки вычисляются с помощью очевидных арифметических операций: "приход" это "+", "расход" это "-". При этом, нас совершенно не заботит порядок внесения записей в регистр. Если что-то вносится "задним числом", виртуальная таблица все равно выдаст нам верный остаток.

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

Заменим набор операций "приход-расход" на набор "накопить-распределить". Операция "накопить" является полным аналогом операции "приход". Изменено только имя. Операция "распределить" в частном случае может работать, как аналог операции "расход", но в общем случае ее поведение более сложное. Рассмотрим его на конкретном примере.

Есть два документа поступления товаров

 

 

 

Обработка проведения для документов поступления выглядит так:

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

Результат проведения этих двух документов

 

 

Есть один документ отгрузки

 

 

В обработке проведения

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

Результат проведения

 

 

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

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

 

    

 

На основе этих данных можно построить так любимый многими отчет типа такого

 

 

Реализацию эмуляции можно найти в приложении. Но здесь она не так уж и важна. Гораздо интереснее то, что нам удается применить функциональный принцип. А это в свою очередь дает нам простоту в модулях объектов. Например, обработка проведения документа "Отгрузка" у меня сейчас выглядит так:

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

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

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

И это при том, что здесь у нас и резервирование и партионный учет. Функциональный подход дает нам такую простоту и прозрачность, которые мы уже давно не видели в типовых конфигурациях.

В приложении демонстрационная выгрузка базы. Пример тестировался на версии платформы 8.3.19.1467.

Скачать файлы

Наименование Файл Версия Размер
Расширенные регистры:

.dt 123,51Kb
11
.dt 123,51Kb 11 Скачать бесплатно

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. RustIG 1571 26.09.22 07:52 Сейчас в теме
Представим, что наш расширенный регистр умеет обрабатывать операцию "распределить". Тогда, при обращении к виртуальной таблице оборотов, мы могли бы получать правильное распределение, в соответствии с тем или иным методом. Метод распределения можно было бы указывать в параметрах регистра.


Распределение должно быть прошито в платформе? Оно зависит не только от "метода", но и от аргументов-параметров - организации, складов, отдельно по каждой номенклатуре - одна так, другая по-другому методу, подразделение, характеристика, серия - в некоторых методах решается СЛАУ.

Но допустим, что можно самим прописать "распределение" - в какой момент времени это будет считаться и себестоимость Сумма (руб) будет проставляться в регистр "Себестоимость" ? Вот здесь :
Движения.Себестоимость.Записывать=истина;
	для каждого стр из Товары цикл
		дв=Движения.Себестоимость.Добавить();
		дв.ВидДвиженияРасширенный=Перечисления.ВидДвижения.Распределить;
		дв.Период=Дата;
		дв.Товар=стр.Товар;
		дв.Количество=стр.Количество;
	конеццикла;
2. mkalimulin 712 26.09.22 08:45 Сейчас в теме
(1) Да, в идеале мы должны иметь платформенную реализацию расширенного регистра. Детали реализации могут быть различными. Можно сделать регистр, у которого метод распределения будет задан как параметр регистра в целом. Можно сделать регистр, в котором метод распределения будет указываться, как параметр записи движения. Лично я на данный момент считаю, что первый вариант лучше. Алгоритмы методов распределения могут быть предопределенными, а могут быть описаны пользователем.
Но в любом случае, себестоимость не "проставляется" в регистр. Себестоимость считается в момент обращения к виртуальной таблице. В регистр "проставляются" промежуточные остатки для ускорения расчета себестоимости. Но так же, как и сейчас в регистре накопления, эти промежуточные остатки не видимы напрямую. Это служебные таблицы.
9. RustIG 1571 26.09.22 11:06 Сейчас в теме
(2)
Но в любом случае, себестоимость не "проставляется" в регистр. Себестоимость считается в момент обращения к виртуальной таблице. В регистр "проставляются" промежуточные остатки для ускорения расчета себестоимости. Но так же, как и сейчас в регистре накопления, эти промежуточные остатки не видимы напрямую. Это служебные таблицы.


Похожим образом можно все задачи мира засунуть в платформу - для создания платформой вирт. таблиц - то есть разработчики Си-шарп теперь начнут программировать предметные области.
10. mkalimulin 712 26.09.22 11:27 Сейчас в теме
(9) Все не надо. Достаточно только задачи распределения
14. RustIG 1571 26.09.22 12:58 Сейчас в теме
(10)
Все не надо. Достаточно только задачи распределения

Почему не надо все? Я не понял тогда вашу концепцию.
Почему только распределение?
В управленческом учете много задач распределения: распределение бонусов (баллов) при списании по товарам, распределение последней 1ой копейки при расчете НДС или других управленческих процентов, распределение материалов по заказам на производство и т.д.
О каких задачах вы говорите?
Есть еще задачи оптимизации - похожи на задачи распределения, только надо выбрать наилучшее распределение по определенному критерию.
3. user1466751 26.09.22 10:07 Сейчас в теме
А как посчитать оборачиваемость неделя к неделе за пару лет при таком подходе?
5. mkalimulin 712 26.09.22 10:22 Сейчас в теме
(3) Запросом к виртуальной таблице оборотов
8. user1466751 26.09.22 10:52 Сейчас в теме
(5)
Так нет движения по с/с в регистре в вашей реализации с "распределить". Что вернут обороты?
11. mkalimulin 712 26.09.22 11:29 Сейчас в теме
(8) В регистре нет, а в виртуальной таблице есть. Вот, например, в обычном регистре накопления нет остатков на 12:31:23 на 17/03/2022, а виртуальной таблице остатков они есть
13. user1466751 26.09.22 11:57 Сейчас в теме
(11)
Что, простите? Что вы понимаете под виртуальной таблицей остатков?
15. mkalimulin 712 26.09.22 13:21 Сейчас в теме
(13) Виртуальная таблица - это таблица, которая не хранится явно в БД, а формируется по запросу
17. user1466751 26.09.22 13:43 Сейчас в теме
(15)
Что делать, когда запрос упадет по превышению памяти серверного вызова? А если с течением времени один и тот же алгоритм изменится, до 1 сентября была одна логика, с 1 сентября другая? Все в запросе учитывать?
19. mkalimulin 712 26.09.22 14:26 Сейчас в теме
(17) Регистры накопления работают же, не падают. Если логика меняется, переходишь с одного регистра на другой
20. user1466751 26.09.22 14:30 Сейчас в теме
(19)
Регистры не рассчитывают суммы, они по ресурсу собирают агрегатную функцию. В вашем варианте в ресурсе нет суммы - ее для каждого документа нужно рассчитать.
В смысле перейти с одного регистра на другой? У меня до 1 января с/с списывалась по средней, а с 1 января по ФИФО - новый регистр городить?
22. mkalimulin 712 26.09.22 15:11 Сейчас в теме
(20) В контексте данного обсуждения, не вижу принципиальной разницы между агрегатной функцией и произвольной функцией. Какая разница - что считать?
Ну да, переходить на другой регистр. А сейчас разве есть более простые способы?
23. user1466751 26.09.22 15:26 Сейчас в теме
(22)
СуммаНачальныйОстаток (из таблицы итогов) + СУММА(СуммаОборот) (из самого регистра за месяц) - с одной стороны

КастомнаяФункция(СуммаОборот) (из самого регистра за все время записей регистра), которая должна учитывать все изменения логики с самого начала базы.

Точно нет разницы, как считать?

Ну да, переходить на другой регистр. А сейчас разве есть более простые способы?


Эм. Использовать регистры накопления остатков так, как задумывалось 1С? А сумму списания определять или при проведении документа, или отложенно, тут уж зависит от предпочтений, объемов данных и прочего.
24. mkalimulin 712 26.09.22 15:29 Сейчас в теме
(23) Зачем за все время? Промежуточные итоги никто не отменял. Расширенный регистр работает точно так же, как обычный регистр накопления, только "внутри" у него не +/- а что-то более содержательное
25. user1466751 26.09.22 16:03 Сейчас в теме
(24)
Еще и итоги поддерживать в актуальном состоянии самостоятельно средствами 1С?
26. mkalimulin 712 26.09.22 16:41 Сейчас в теме
(25) Я не вполне понимаю ваши вопросы. Регистры накопления поддерживают итоги в актуальном состоянии. В чем вы видите проблему?
27. user1466751 26.09.22 18:35 Сейчас в теме
(26)
Я сдаюсь. Извините за беспокойство.
4. user1559729 26.09.22 10:14 Сейчас в теме
(0) правильно я понял суть предложения - перенести обработку проведения из модуля документа в ?куда - регистр? общий модуль?
6. mkalimulin 712 26.09.22 10:24 Сейчас в теме
(4) Перенести в регистр. В идеале, в платформенную реализацию. В отсутствии платформенной реализации можно сделать эмуляцию через подписки на события
7. user1559729 26.09.22 10:52 Сейчас в теме
(6) В таком случае унификации не будет, т.к. распределение в различных документах может отличаться?
12. mkalimulin 712 26.09.22 11:31 Сейчас в теме
(7) Что вы имеете ввиду? Методы распределения могут отличаться? Тогда для разных методов можно использовать разные регистры, а метод распределения задавать как параметр регистра
16. mkalimulin 712 26.09.22 13:24 Сейчас в теме
(14) Потому что распределение закрывает почти все задачи, встречающиеся в учете. Кроме резервирования, но резервирование можно решить регистром с неотрицательными остатками
18. RustIG 1571 26.09.22 14:20 Сейчас в теме
(16)В управленческом учете много задач распределения, и все решаются по разному, но с применением различных таблиц - иначе где хранить входную информацию? не понятно почему именно регистры накопления, и как решить все задачи сразу?
21. mkalimulin 712 26.09.22 15:08 Сейчас в теме
(18) И все эти задачи очень схожи друг с другом. Что дает возможность перейти к рациональному обобщению
28. mixsture 04.10.22 01:20 Сейчас в теме
Убийственный для производительности подход. По сути вы предлагаете каждое чтение виртуальной таблицы заново рассчитывать распределение. Чтений в базе существенно больше записи, а еще для чтений обычно более жесткие требования по времени выполнения - поэтому вы в любом случае сильно проигрываете в нагрузке. Чем вы это покроете? Десятикратным удорожанием серверных мощностей?
Имхо, загнется эта штука при переходе от тестового стенда к реальным массивам данных.
29. mkalimulin 712 04.10.22 09:03 Сейчас в теме
(28) Сейчас, в обычном регистре накопления, при каждом чтении виртуальной таблицы остатков происходит их вычисление и ничего страшного.
30. mixsture 04.10.22 16:23 Сейчас в теме
(29) вычисление остатков != вычислению распределения. Это задачи различающиеся по сложности на порядки. И даже без различий в сложности между этими задач по смыслу - вычисление остатков происходит целиком на sql, а вы примеры пишете уже на ЯП. Даже если сделать сверхбыстрый компилируемый строго типизированный ЯП из 1с или заложить эти механизмы внутрь платформы, что будет С++, насколько я помню, это все равно проиграет по скорости вычисления на стороне СУБД.
31. mkalimulin 712 04.10.22 18:36 Сейчас в теме
(30) Что мешает делать вычисление распределения "целиком на sql"?
32. mixsture 04.10.22 21:25 Сейчас в теме
33. mkalimulin 712 04.10.22 21:32 Сейчас в теме
(32) Примеры для примера ))) В идеале это реализуется в платформе. В тех же случаях, когда объемы данных позволяют, можно пользоваться и эмуляцией платформенного решения. Пример такой эмуляции я и привел. Могу добавить, что это будет нормально работать где-то в 90% случаев
34. mixsture 04.10.22 21:55 Сейчас в теме
(33) в платформе - это расплывчатое понятие. Там внутри куча кода на C++, принцип хранения данных регистров накопления, трансляция запроса к виртуальной таблице в реальный запрос к таблице итогов и движений. Как это у вас будет работать? В sql или в ЯП распределение считается? какие таблицы будут? в комментах вы упоминаете про промежуточные результаты - что это и где хранится? когда пересчитывается?
35. mkalimulin 712 04.10.22 22:30 Сейчас в теме
(34) Промежуточные результаты - те же самые, что и сейчас в регистрах накопления
Оставьте свое сообщение

См. также

Неотрицательные остатки

Адаптация типовых решений Платформа 1С v8.3 Управленческий учет Бесплатно (free)

Это первая статья из серии статей, объединенных общим смыслом проверить возможность создания учетной системы более простой и прозрачной, чем имеющиеся сейчас.

12.09.2022    968    8    mkalimulin    5    

Остаток в табличной части документа

Обработка документов Логистика, склад и ТМЦ Адаптация типовых решений Платформа 1С v8.3 1С:Управление торговлей 11 Россия Управленческий учет Бесплатно (free)

Расширение, показывающее остаток номенклатуры на текущий момент времени по строчке в табличной части документов.

16.01.2022    3279    105    user720820720    2    

Исправление ошибки формирования КУДИР в части возврата от покупателя по безналу в отчете о розничных продажах. 1С:Бухгалтерия 8.3

Розничная торговля Адаптация типовых решений Учет доходов и расходов Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет ИП, ПБОЮЛ, КФХ Бесплатно (free)

При возврате денег покупателю по безналичному расчету в книгу доходов и расходов 1С: Бухгалтерии 3.0 ошибочно пишется запись с отрицательной суммой возврата. В книжке по итогу на эту сумму получается меньше на сумму этого возврата. Расширение конфигурации - костыль для отчета о розничных продажах по возврату безнала от розничного покупателя.

29.07.2021    3153    14    PS_    1    

Заполнение контрагентов по ИНН. Назад в будущее

Адаптация типовых решений Платформа 1С v8.3 Россия Бесплатно (free)

Что делать, если Ваш клиент не смог выйти из каменного века и вместо вменяемой часто модифицируемой под нужды современного мира конфигурации, у него неподъемный мамонт, который пережил несколько ледниковых эпох, такой неуклюжий, умирающий, но близкий к бизнесу и родной сердцу? Проблемы начинаются тогда, когда у этого мамонта отваливаются зубья, или его обладатель поглядывает на современные конфигурации и начинает желать новшеств в виде весоподъемности и скорости самолета. Да вообще и чтобы все, что должно работать, работало в конце концов, как, например, внезапно умерший сервис 1С:Контрагент! А у некоторых мамонтов, он, совершенно точно, провонял и усох. И вот как положить этот артефакт в микроволновку времени и вернуть к работоспособному состоянию.

12.05.2020    5780    0    G.Shatrov    8    

Подсистема хранения файлов

Адаптация типовых решений Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

Отличия от реализации в типовых: - версионирование - запрет одновременного редактирования файла несколькими пользователями - линковка файлов многие-ко-многим (т.е. один файл может быть прилинкован к нескольким объектам и наоборот) - создание коллекций файлов (например коллекций: типовые договора или унифицированных формы) - возможность типизации файлов (например, факсы могут подсвечиваться при работе синим, а договора зеленым) - одновременный просмотр прилинкованных файлов к нескольким объектам (например, просмотр файлов привязанных к клиенту и к его договорам) - просмотр прилинкованных файлов из форм списка

23.03.2010    8848    768    koreav    32    

Механизм блокирования "некорректных" (запрещенных) проводок

Адаптация типовых решений Платформа 1С v8.3 1С:Бухгалтерия 2.0 Россия Бухгалтерский учет Бесплатно (free)

Механизм позволяет настроить правила, по которым будут блокироваться указанные НЕКОРРЕКТНЫЕ (запрещенные) корреспонденции... Полезно при вводе информации для "выпрямления рук" у некоторых бухгалтеров после перехода с других бухгалтерских программ :)

14.11.2009    16175    59    KukA.5    50    

Подсистема "Учет по доп. аналитике" (8.1)

Адаптация типовых решений Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

Подсистема "Учет по доп.аналитике" - это дополнение к любой конфигурации на 8.1 решает основную задачу: не ломая конфигурации добавить к нужным документам учет по дополнительной аналитике (аналитикой может выступать как в данном примере Агент по продаже и его вознаграждение или Проект и его руководитель как в файле описания). Данная подсистема является продуктом, готовым к использованию, как дополнение к типовой конфигурации (или к любой конфигурации). Подсистема снова БЕСПЛАТНО (то есть даром) :)

07.09.2009    15411    405    KukA.5    41