|
Довольно часто возникают ситуации, когда необходимо записывать или проводить изменения в документе в 1С не полностью, а частично. Это необходимо, например, при изменениях задним числом когда изменяется небольшая относительная часть документа 1С. Также, подобные операции необходимы, когда требуется немедленно произвести изменения в базе по строке документа. Например резервирование товара. Конечно, подобные проблемы решаются и другими вариантами, но все они будут менее эффективными и надежными - т.к. для подобных операций требуется наличие открытой транзакции и внутри этой транзакции возможность использования удобных методов объекта «Регистр». Как мы знаем контролировать транзакцию можно с помощью методов «НачатьТранзакцию» (естественно транзакция обязательно используется внутри процедуры ОбработкаПроведения) и т.п., а вот с движениями по регистрам дело обстоит сложнее. Конечно, заставить 1С использовать подобные методы вне модуля документа, например в модуле формы, можно.
А чем же нас не устраивает стандартный механизм? Самое главное – не существует стандартного механизма по выборочной записи и проведению документа 1С. Если у нас добавилась одна строка в документе, то мы не можем только ее записать. Каждый раз при вызове метода Записать() будут перезаписываться заново все строки документа. Этот недостаток не самый критичный – что гораздо хуже так это отсутствие метода выборочной очистки движений по регистру документа. Подобная операция гораздо более ресурсоемкая.
Рассмотрим вкратце реализацию перепроведения документа 1С по оперативному учету в контексте интересующей нас проблемы (часть алгоритма внутренней реализации перепроведения будет пропущена).
После запуска операции перепроведения документа 1С в первую очередь открывается транзакция. После чего в зависимости от опций установленных в документе 1С (смотрите конфигуратор), а именно автоматическое удаление движений вызывается процедура T-SQL _1sp_RAХХХ_ClearRecalcDocActs. Полное название ее определятся внутренним идентификатором регистра.
Если такая опция не стоит то вышеописанная процедура будет инициализирована после вызова метода 1С - ОчиститьДвижения(<ВидыДвижений>). Эта процедура отвечает за очистку движений по конкретному регистру. Как мы видим, в нее в качестве параметра передается ВидДвижения. В зависимости от этого параметра вызывается процедура _1sp_RAХХХ_ClearRecalcDocActs соответствующая конкретному регистру.
Для того, что бы произвести выборочную очистку движений необходимо рассмотреть эту процедуру немного подробнее.
Краткая концепция очистки движения по регистрам такова:
- Выбираются движения по регистру по текущему документу
(Пример из процедуры конкретного регистра: SELECT DEBKRED, SP1403, SP1405, SP1406, SP1407, SP1408 FROM RA1402 WHERE IDDOC=@IdDoc)
- Производится пересчет по каждой очищенной записи движения регистра по всем агрегационным записям (т.е. остатки хранящиеся в таблицах RGХХХ )
(Пример из процедуры конкретного регистра: EXECUTE _1sp_RG1402_Change @Period, @p0, @p1, @p2, @f0, @f1)
- Производится очистка всех движений из таблица RAХХХ.
Как мы видим такой вариант нас не устраивает, так как удаляются все движения.
Изменить стандартную процедуру очистки 1С _1sp_RAХХХ_ClearRecalcDocActs мы тоже не можем, так как такой механизм будет работать некорректно. Дело в том что удаление движений из таблицы RAХХХ производится напрямую из 1С без промежуточного вызова процедур на T-SQL.
Единственный выход, который остается это реализовать свою процедуру очистки и использовать ее. К счастью это совсем не сложно. Можно взять стандартные процедуры 1С и только в реализации выборки движений по документу добавить фильтр по конкретным позициям. Фактически это будет дополнительный фильтр по измененным полям.
Стандартная реализация. (Пример из процедуры конкретного регистра: SELECT DEBKRED, SP1403, SP1405, SP1406, SP1407, SP1408 FROM RA1402 WHERE IDDOC=@IdDoc)
Построчное удаление. (Пример из процедуры конкретного регистра: SELECT DEBKRED, SP1403, SP1405, SP1406, SP1407, SP1408 FROM RA1402 WHERE IDDOC=@IdDoc and (SP1403=….. ))
Чтобы не зависеть от конфигурации, это желательно сделать с помощью внешней компоненты. Такую компоненту можно реализовать полностью прозрачной для 1С программиста не искушенного в T-SQL программировании. Фактически это будет вызов процедуры в 1С -ОчиститьДвиженияПоИзмерениям(ВидыДвижений…,СписокИзмерений…)
Кроме этого, естественно нужно будет убрать все опции автоматического удаления движений в тех документах 1С, где потребуется использование вышеописанной технологии.
Подобная конструкция позволит сделать использование механизма проведения документов в 1С более гибким и эффективным. Использовать его нужно не с большей осторожностью чем, например использование стандартного метода ОчиститьДвижения.
Компания "СофтПоинт" представляет компоненту для использования вышеописанного механизма.
Статьи по этой теме:
Построчное перепроведение документов 1с
Перепечатка, воспроизведение в любой форме, распространение, в том числе в переводе, любых материалов с сайта www.softpoint.ru возможны только с письменного разрешения компании "СофтПоинт". Это правило действует для всех без исключения случаев, кроме тех, когда в материале прямо указано разрешение на копирование (основание: Закон Российской Федерации "Об авторском праве и смежных правах").
|