Произвольное закрытие 20,25,26 счетов
Каждый программист сталкивался с тем, что штатными средствами распределение затрат происходит не так как требует главный бухгалтер. В этом случае приходится изменять стандартный механизм: изменять модули, создавать собственные документы, или использовать специальные обработки перед выполнением закрытия месяца, что создает сложность в обновлении. Но есть и другой подход…
- Описание
- Подробнее
Описание
В данной статье приводится пример на конфигурации «1С: Комплексная автоматизация 1.1» по созданию универсального механизма распределения затрат по 20ым счетам.
Не вдаваясь в подробности «что, как и почему?», начну с описания своих действий. Сразу замечу, что нам также необходимо добавить свои объекты в конфигруцию, но наши изменения никак не будут влиять на сложность последующего обновления конфигурации.
Первое действие: Открываем конфигуратор 
В конфигураторе добавляем общий модуль с специфичным названием «Алгоритм_ОбработкаПроведения». Обязательно выставляем: «Сервер» и «Привилегированный». «Сервер» — необходимо чтобы вызов нашего модуля происходил в последнюю очередь.

В модуле прописываем следующий код:
/////----------------- Расчет себестоимости +++
Процедура Алгоритм_ОбработкаПроведения_РасчетСебестоимостиВыпускаОбработкаПроведения(Источник, Отказ, РежимПроведения) Экспорт
ВыбратьИВыполнитьАлгоритмыОчистки(Источник);
ВыбратьИВыполнитьАлгоритмыРасчета(Источник);
КонецПроцедуры
Процедура ВыбратьИВыполнитьАлгоритмыОчистки(Источник)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Алгоритм_СпособыЗакрытияСебестоимостиСрезПоследних.ХарактерЗатрат,
| Алгоритм_СпособыЗакрытияСебестоимостиСрезПоследних.АлгоритмБУ,
| Алгоритм_СпособыЗакрытияСебестоимостиСрезПоследних.АлгоритмНУ,
| Алгоритм_СпособыЗакрытияСебестоимостиСрезПоследних.АлгоритмБУРАУЗ
|ИЗ
| РегистрСведений.Алгоритм_СпособыЗакрытияСебестоимости.СрезПоследних(&Период, ОчисткаДанных) КАК Алгоритм_СпособыЗакрытияСебестоимостиСрезПоследних";
Запрос.УстановитьПараметр("Период", КонецМесяца(Источник.Дата));
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
////+++ Очищаем регистр бухгалтерии
АлгоритмОчистки_СКД = ВыборкаДетальныеЗаписи.АлгоритмБУ.Получить();
Для каждого АлгоритмОчистки_НаборДанных из АлгоритмОчистки_СКД.НаборыДанных Цикл
АлгоритмОчистки_Запрос = Новый Запрос(АлгоритмОчистки_НаборДанных.Запрос);
Для каждого АлгоритмОчистки_Праметры из АлгоритмОчистки_СКД.Параметры Цикл
АлгоритмОчистки_Запрос.УстановитьПараметр(АлгоритмОчистки_Праметры.Имя, АлгоритмОчистки_Праметры.Значение);
КонецЦикла;
АлгоритмОчистки_Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(Источник.Дата));
АлгоритмОчистки_Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(Источник.Дата));
АлгоритмОчистки_Запрос.УстановитьПараметр("НачалоПериодаГраница", Новый Граница(НачалоМесяца(Источник.Дата), ВидГраницы.Включая));
АлгоритмОчистки_Запрос.УстановитьПараметр("КонецПериодаГраница", Новый Граница(КонецМесяца(Источник.Дата), ВидГраницы.Включая));
АлгоритмОчистки_Запрос.УстановитьПараметр("Регистратор", Источник.Ссылка);
АлгоритмОчистки_Хозрасчетный = Источник.Движения.Хозрасчетный;
АлгоритмОчистки_Хозрасчетный.Прочитать();
АлгоритмОчистки_Выборка = АлгоритмОчистки_Запрос.Выполнить().Выбрать();
Пока АлгоритмОчистки_Выборка.Следующий() Цикл
НомерСтроки = АлгоритмОчистки_Выборка.НомерСтроки - 1;
АлгоритмОчистки_Хозрасчетный.Удалить(НомерСтроки);
КонецЦикла;
Попытка АлгоритмОчистки_Хозрасчетный.Записать(); Исключение
Сообщить("Ошибки в алгоритме очистки регистра",СтатусСообщения.ОченьВажное);
КонецПопытки;
КонецЦикла;
////--- Очищаем регистр бухгалтерии
////+++ Очищаем регистр налоговый
АлгоритмОчистки_СКД = ВыборкаДетальныеЗаписи.АлгоритмНУ.Получить();
Для каждого АлгоритмОчистки_НаборДанных из АлгоритмОчистки_СКД.НаборыДанных Цикл
АлгоритмОчистки_Запрос = Новый Запрос(АлгоритмОчистки_НаборДанных.Запрос);
Для каждого АлгоритмОчистки_Праметры из АлгоритмОчистки_СКД.Параметры Цикл
АлгоритмОчистки_Запрос.УстановитьПараметр(АлгоритмОчистки_Праметры.Имя, АлгоритмОчистки_Праметры.Значение);
КонецЦикла;
АлгоритмОчистки_Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(Источник.Дата));
АлгоритмОчистки_Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(Источник.Дата));
АлгоритмОчистки_Запрос.УстановитьПараметр("НачалоПериодаГраница", Новый Граница(НачалоМесяца(Источник.Дата), ВидГраницы.Включая));
АлгоритмОчистки_Запрос.УстановитьПараметр("КонецПериодаГраница", Новый Граница(КонецМесяца(Источник.Дата), ВидГраницы.Включая));
АлгоритмОчистки_Запрос.УстановитьПараметр("Регистратор", Источник.Ссылка);
АлгоритмОчистки_Налоговый = Источник.Движения.Налоговый;
АлгоритмОчистки_Налоговый.Прочитать();
АлгоритмОчистки_Выборка = АлгоритмОчистки_Запрос.Выполнить().Выбрать();
Пока АлгоритмОчистки_Выборка.Следующий() Цикл
НомерСтроки = АлгоритмОчистки_Выборка.НомерСтроки - 1;
АлгоритмОчистки_Налоговый.Удалить(НомерСтроки);
КонецЦикла;
АлгоритмОчистки_Налоговый.Записать();
КонецЦикла;
////--- Очищаем регистр налоговый
////+++ Очищаем регистр РАУЗРегл
АлгоритмОчистки_СКД = ВыборкаДетальныеЗаписи.АлгоритмБУРАУЗ.Получить();
Для каждого АлгоритмОчистки_НаборДанных из АлгоритмОчистки_СКД.НаборыДанных Цикл
АлгоритмОчистки_Запрос = Новый Запрос(АлгоритмОчистки_НаборДанных.Запрос);
Для каждого АлгоритмОчистки_Праметры из АлгоритмОчистки_СКД.Параметры Цикл
АлгоритмОчистки_Запрос.УстановитьПараметр(АлгоритмОчистки_Праметры.Имя, АлгоритмОчистки_Праметры.Значение);
КонецЦикла;
АлгоритмОчистки_Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(Источник.Дата));
АлгоритмОчистки_Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(Источник.Дата));
АлгоритмОчистки_Запрос.УстановитьПараметр("НачалоПериодаГраница", Новый Граница(НачалоМесяца(Источник.Дата), ВидГраницы.Включая));
АлгоритмОчистки_Запрос.УстановитьПараметр("КонецПериодаГраница", Новый Граница(КонецМесяца(Источник.Дата), ВидГраницы.Включая));
АлгоритмОчистки_Запрос.УстановитьПараметр("Регистратор", Источник.Ссылка);
АлгоритмОчистки_УчетЗатратРегл = Источник.Движения.УчетЗатратРегл;
АлгоритмОчистки_УчетЗатратРегл.Прочитать();
АлгоритмОчистки_Выборка = АлгоритмОчистки_Запрос.Выполнить().Выбрать();
Пока АлгоритмОчистки_Выборка.Следующий() Цикл
НомерСтроки = АлгоритмОчистки_Выборка.НомерСтроки - 1;
АлгоритмОчистки_УчетЗатратРегл.Удалить(НомерСтроки);
КонецЦикла;
АлгоритмОчистки_УчетЗатратРегл.Записать();
КонецЦикла;
////--- Очищаем регистр РАУЗРегл
КонецЦикла;
КонецПроцедуры
Процедура ВыбратьИВыполнитьАлгоритмыРасчета(Источник)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Алгоритм_СпособыЗакрытияСебестоимостиСрезПоследних.ХарактерЗатрат,
| Алгоритм_СпособыЗакрытияСебестоимостиСрезПоследних.АлгоритмБУ,
| Алгоритм_СпособыЗакрытияСебестоимостиСрезПоследних.АлгоритмНУ,
| Алгоритм_СпособыЗакрытияСебестоимостиСрезПоследних.АлгоритмБУРАУЗ
|ИЗ
| РегистрСведений.Алгоритм_СпособыЗакрытияСебестоимости.СрезПоследних(&Период, (НЕ ОчисткаДанных)) КАК Алгоритм_СпособыЗакрытияСебестоимостиСрезПоследних";
Запрос.УстановитьПараметр("Период", КонецМесяца(Источник.Дата));
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
////+++ Пишем регистр бухгалтерии
АлгоритмЗаполнения_СКД = ВыборкаДетальныеЗаписи.АлгоритмБУ.Получить();
Для каждого АлгоритмЗаполнения_НаборДанных из АлгоритмЗаполнения_СКД.НаборыДанных Цикл
АлгоритмЗаполнения_Запрос = Новый Запрос(АлгоритмЗаполнения_НаборДанных.Запрос);
Для каждого АлгоритмЗаполнения_Праметры из АлгоритмЗаполнения_СКД.Параметры Цикл
АлгоритмЗаполнения_Запрос.УстановитьПараметр(АлгоритмЗаполнения_Праметры.Имя, АлгоритмЗаполнения_Праметры.Значение);
КонецЦикла;
АлгоритмЗаполнения_Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(Источник.Дата));
АлгоритмЗаполнения_Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(Источник.Дата));
АлгоритмЗаполнения_Запрос.УстановитьПараметр("НачалоПериодаГраница", Новый Граница(НачалоМесяца(Источник.Дата), ВидГраницы.Включая));
АлгоритмЗаполнения_Запрос.УстановитьПараметр("КонецПериодаГраница", Новый Граница(КонецМесяца(Источник.Дата), ВидГраницы.Включая));
АлгоритмЗаполнения_Запрос.УстановитьПараметр("Регистратор", Источник.Ссылка);
АлгоритмЗаполнения_Хозрасчетный = Источник.Движения.Хозрасчетный;
АлгоритмЗаполнения_Хозрасчетный.Прочитать();
АлгоритмЗаполнения_Выборка = АлгоритмЗаполнения_Запрос.Выполнить().Выбрать();
Пока АлгоритмЗаполнения_Выборка.Следующий() Цикл
АлгоритмЗаполнения_Запись = АлгоритмЗаполнения_Хозрасчетный.Добавить();
ЗаполнитьЗначенияСвойств(АлгоритмЗаполнения_Запись, АлгоритмЗаполнения_Выборка);
Для и1 = 1 по 3 Цикл
Попытка
Знач_Субк = АлгоритмЗаполнения_Выборка["СубконтоДт"+и1];
СчетДт = АлгоритмЗаполнения_Выборка["СчетДт"];
ВидСубконто = ОпределитьВидСубконто(СчетДт, Знач_Субк);
Если не ВидСубконто = неопределено Тогда
АлгоритмЗаполнения_Запись.СубконтоДт.Вставить(ВидСубконто, Знач_Субк);
КонецЕсли;
Исключение КонецПопытки;
Попытка
Знач_Субк = АлгоритмЗаполнения_Выборка["СубконтоКт"+и1];
СчетКт = АлгоритмЗаполнения_Выборка["СчетКт"];
ВидСубконто = ОпределитьВидСубконто(СчетКт, Знач_Субк);
Если не ВидСубконто = неопределено Тогда
АлгоритмЗаполнения_Запись.СубконтоКт.Вставить(ВидСубконто, Знач_Субк);
КонецЕсли;
Исключение КонецПопытки;
КонецЦикла;
КонецЦикла;
АлгоритмЗаполнения_Хозрасчетный.Записать();
КонецЦикла;
////--- Пишем регистр бухгалтерии
////+++ Пишем регистр налоговый
АлгоритмЗаполнения_СКД = ВыборкаДетальныеЗаписи.АлгоритмНУ.Получить();
Для каждого АлгоритмЗаполнения_НаборДанных из АлгоритмЗаполнения_СКД.НаборыДанных Цикл
АлгоритмЗаполнения_Запрос = Новый Запрос(АлгоритмЗаполнения_НаборДанных.Запрос);
Для каждого АлгоритмЗаполнения_Праметры из АлгоритмЗаполнения_СКД.Параметры Цикл
АлгоритмЗаполнения_Запрос.УстановитьПараметр(АлгоритмЗаполнения_Праметры.Имя, АлгоритмЗаполнения_Праметры.Значение);
КонецЦикла;
АлгоритмЗаполнения_Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(Источник.Дата));
АлгоритмЗаполнения_Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(Источник.Дата));
АлгоритмЗаполнения_Запрос.УстановитьПараметр("НачалоПериодаГраница", Новый Граница(НачалоМесяца(Источник.Дата), ВидГраницы.Включая));
АлгоритмЗаполнения_Запрос.УстановитьПараметр("КонецПериодаГраница", Новый Граница(КонецМесяца(Источник.Дата), ВидГраницы.Включая));
АлгоритмЗаполнения_Запрос.УстановитьПараметр("Регистратор", Источник.Ссылка);
АлгоритмЗаполнения_Налоговый = Источник.Движения.Налоговый;
АлгоритмЗаполнения_Налоговый.Прочитать();
АлгоритмЗаполнения_Выборка = АлгоритмЗаполнения_Запрос.Выполнить().Выбрать();
Пока АлгоритмЗаполнения_Выборка.Следующий() Цикл
АлгоритмЗаполнения_Запись = АлгоритмЗаполнения_Налоговый.Добавить();
ЗаполнитьЗначенияСвойств(АлгоритмЗаполнения_Запись, АлгоритмЗаполнения_Выборка);
Для и1 = 1 по 3 Цикл
Попытка
Знач_Субк = АлгоритмЗаполнения_Выборка["СубконтоДт"+и1];
СчетДт = АлгоритмЗаполнения_Выборка["СчетДт"];
ВидСубконто = ОпределитьВидСубконто(СчетДт, Знач_Субк);
Если не ВидСубконто = неопределено Тогда
АлгоритмЗаполнения_Запись.СубконтоДт.Вставить(ВидСубконто, Знач_Субк);
КонецЕсли;
Исключение КонецПопытки;
Попытка
Знач_Субк = АлгоритмЗаполнения_Выборка["СубконтоКт"+и1];
СчетКт = АлгоритмЗаполнения_Выборка["СчетКт"];
ВидСубконто = ОпределитьВидСубконто(СчетКт, Знач_Субк);
Если не ВидСубконто = неопределено Тогда
АлгоритмЗаполнения_Запись.СубконтоКт.Вставить(ВидСубконто, Знач_Субк);
КонецЕсли;
Исключение КонецПопытки;
КонецЦикла;
КонецЦикла;
АлгоритмЗаполнения_Налоговый.Записать();
КонецЦикла;
////--- Пишем регистр налоговый
////+++ Пишем регистр РАУЗРегл
АлгоритмЗаполнения_СКД = ВыборкаДетальныеЗаписи.АлгоритмБУРАУЗ.Получить();
Для каждого АлгоритмЗаполнения_НаборДанных из АлгоритмЗаполнения_СКД.НаборыДанных Цикл
АлгоритмЗаполнения_Запрос = Новый Запрос(АлгоритмЗаполнения_НаборДанных.Запрос);
Для каждого АлгоритмЗаполнения_Праметры из АлгоритмЗаполнения_СКД.Параметры Цикл
АлгоритмЗаполнения_Запрос.УстановитьПараметр(АлгоритмЗаполнения_Праметры.Имя, АлгоритмЗаполнения_Праметры.Значение);
КонецЦикла;
АлгоритмЗаполнения_Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(Источник.Дата));
АлгоритмЗаполнения_Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(Источник.Дата));
АлгоритмЗаполнения_Запрос.УстановитьПараметр("НачалоПериодаГраница", Новый Граница(НачалоМесяца(Источник.Дата), ВидГраницы.Включая));
АлгоритмЗаполнения_Запрос.УстановитьПараметр("КонецПериодаГраница", Новый Граница(КонецМесяца(Источник.Дата), ВидГраницы.Включая));
АлгоритмЗаполнения_Запрос.УстановитьПараметр("Регистратор", Источник.Ссылка);
АлгоритмЗаполнения_УчетЗатратРегл = Источник.Движения.УчетЗатратРегл;
АлгоритмЗаполнения_УчетЗатратРегл.Прочитать();
АлгоритмЗаполнения_Выборка = АлгоритмЗаполнения_Запрос.Выполнить().Выбрать();
Пока АлгоритмЗаполнения_Выборка.Следующий() Цикл
АлгоритмЗаполнения_Запись = АлгоритмЗаполнения_УчетЗатратРегл.Добавить();
ЗаполнитьЗначенияСвойств(АлгоритмЗаполнения_Запись, АлгоритмЗаполнения_Выборка);
КонецЦикла;
АлгоритмЗаполнения_УчетЗатратРегл.Записать();
КонецЦикла;
////--- Пишем регистр РАУЗРегл
КонецЦикла;
КонецПроцедуры
Функция ОпределитьВидСубконто(Счет, Знач_Субк) Экспорт
Результат = Неопределено;
ТипЗнчСК = ТипЗнч(Знач_Субк);
Для каждого ВС из Счет.ВидыСубконто Цикл
Если ВС.ВидСубконто.ТипЗначения.СодержитТип(ТипЗнчСК) Тогда
Результат = ВС.ВидСубконто;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
/////----------------- Расчет себестоимости ---
Подробные разъяснения по представленному коду давать особого смысла не вижу смысла. т.к. по окнчании статьи станет ясен каждый выполненный шаг. А что происходит в приведенном модуле примерно ясно по коду, даже на первый взгляд.
А в кратце так:
- Сначала ищем актуальный на текущий месяц алгоритм очистки регистров
- Выполняем непосредственное удаление записей по фильтру
- Ищем актуальный на текущий месяц алгоритм распределения
- Последовательно перебираем все запросы в СКД по определенному разделу учета. Производим заполнение параметров и выполнеям. Ничего осверхъестественного. Условности есть только в специфичных бухгалтерских регистрах, что видно по коду
