Прямое редактирование движений регистров и перепроведение документов по выбранным регистрам в 1С 7.7


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

Предистория:

Запускал торговую систему в нашем филиале в Казахстане (до этого система уже работала в Украине и России). И во время переноса движений из старой базы в новую, постоянно сталкивался с проблемой несоответствия движений регистров из-за ошибок в старой базе. В конце концов, пришлось создать не только обработку, которая позволила произвольно редактировать содержимое регистров и реквизитов документа, но и механизм проведения документов по выбранным регистрам. Благо, что конфигурация создавалась с нуля и не нужно было втискиваться в рамки типовой конфигурации.

Проверялось на релизе:

1С 7.7.27, 1С++ 2.0.3.7, установлен MS Office с ActiveX компонентой MSComctlLib.TreeCtrl или наличие компоненты COMCTL.TreeCtrl (для навигации в виде дерева).

Что делает обработка и механизм:

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

Кому будет интересна:

Сразу запустить обработку не получится — в этой статье предлагается конструктор. Необходима модификация как кода обработки, так и кода конфигурации. Если Вы готовы пойти на этот шаг, тогда она для Вас. Учтите, что обработка создавалась для редактирования регистров оперативного учёта.

Что нужно будет поменять в конфигурации:

  1. Для всех документов конфигурации необходимо снять признак «Автоматическое удаление движений».
  2. Исправить во всех документах процедуру ОбработкаПроведения
  3. Ввести в систему понятие «участок»: включает в себя набор логически связанных регистров, движения которых взаимосвязаны и раздельное проведение может вызвать логичские разногласия. Например, для ТиС это может быть регистр Остатки и Партии. Участки определяются в глобальной переменной.
  4. Модифицировать глобальный модуль для встраивания служебных процедур и функций, а также модифицировать существующие процедуры записи движений в регистры.

Подробности:

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

А вот для редактирования движений регистров уже нужна модификация конфигурации. Нужно в режиме конфигуратора для документов снять признак «Автоматическое удаление движений» и модифицировать процедуру ОбработкаПроведения. Идея заключается в том, чтобы считать движения регистров в таблицу значений. После интерактивного редактирования таблицы, запустить процедуру ОбработкаПроведения документа с параметром типа ТаблицаЗначений, в котором будет передана таблица значений с исправленным содержимым регистров. Дальше исправленная процедура проведения будет записывать движения в регистр из переданной таблицы значений, а не выполнять расчет новых значений регистров, как это предусмотренно в обычном механизме проведения документа.

Для перепроведения документов по избранным участкам учёта, понадобится отдельная обработка, в которой можно указать участки для проведения. Обработка будет передавать в процедуру ОбработкаПроведения() параметр типа СписокЗначений. Этот параметр будет содержать список участков, по которым нужно перепроведение.

Необходимые изменения в конфигурации:

1. Добавить глобальную переменную для определения участков (групп регистров, которые проводятся всегда совместно) и инициализировать её 

глСоставРегистровПоУчасткам = СоздатьОбъект("СписокЗначений");
глСоставРегистровПоУчасткам.ДобавитьЗначение("ПартииНаличие" , "Товары" );
глСоставРегистровПоУчасткам.ДобавитьЗначение("РезервыТоваров" , "Товары" );
глСоставРегистровПоУчасткам.ДобавитьЗначение("РезервыКонтрагентов" , "Товары" );
глСоставРегистровПоУчасткам.ДобавитьЗначение("ПартииКорректировка" , "Товары" );
глСоставРегистровПоУчасткам.ДобавитьЗначение("ОстаткиМОЛ" , "Товары" );
глСоставРегистровПоУчасткам.ДобавитьЗначение("ОстаткиВКамерах" , "Товары" );
глСоставРегистровПоУчасткам.ДобавитьЗначение("РасходыНаТовары" , "Расходы на товары");
глСоставРегистровПоУчасткам.ДобавитьЗначение("Покупатели" , "Взаиморасчеты" );
глСоставРегистровПоУчасткам.ДобавитьЗначение("Поставщики" , "Взаиморасчеты" );
глСоставРегистровПоУчасткам.ДобавитьЗначение("Касса" , "Деньги" );
глСоставРегистровПоУчасткам.ДобавитьЗначение("Банк" , "Деньги" );
глСоставРегистровПоУчасткам.ДобавитьЗначение("ОплатыДоговоров" , "Деньги" );
глСоставРегистровПоУчасткам.ДобавитьЗначение("Факторинг" , "Деньги" );
глСоставРегистровПоУчасткам.ДобавитьЗначение("ИсполнениеПриказов" , "Приказы" );

2. Изменить во всех документах процедуру ОбработкаПроведения — добавить параметр ВидыДвижений

Процедура ОбработкаПроведения(ВидыДвижений="")

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

// тар - при проведении из таблицы значений не должно выполняться никаких проверок на корректность данных
спУправлениеПроведением = СоздатьОбъект("СписокЗначений");
Если ТипЗначенияСтр(ВидыДвижений) = "ТаблицаЗначений" Тогда
Если глУправлениеПроведениемДокумента(Контекст, ВидыДвижений, спУправлениеПроведением) = 0 Тогда
Возврат;
КонецЕсли;
КонецЕсли;

Таблица значений с содержимым регистров содержит в себе названия регистров и вложенные таблицы с содержимым регистров

тбРегистры = СоздатьОбъект("ТаблицаЗначений");
тбРегистры.НоваяКолонка("Регистр", "Строка", 30);
тбРегистры.НоваяКолонка("ДвиженияРегистра");

тбРегистры.НоваяСтрока();
тбРегистры.Регистр = НазваниеРегистра;
тбРегистры.ДвиженияРегистра = СоздатьОбъект("ТаблицаЗначений");

4. Добавить в глобальный модуль процедуру глУправлениеПроведениемДокумента, которая определит по каким участкам нужно проводить регистры и очистит движения регистров если тип параметра ВидДвижений — СписокЗначений или есть ТаблицаЗначений — заменит движения регистров данными из таблицы значений.

// ====================================
// тар - вызывается из ОбработкиПроведения документа
// очищает содержимое регистров или если передан РежимПроведения как ТаблицаЗначений,
// то проводит документ по этим регистрам
// возвращает 1 - когда нужно в обработке проведения передать управление дальше и проводить регистры
// и 0 - когда дальше проводить не нужно
Функция глУправлениеПроведениемДокумента(Конт, ВидыДвижений, СписокПараметров) Экспорт
Перем Рез;

Рез = 1;
ПровестиТовары = 1;
ПровестиРасходыНаТовары = 1;
ПровестиВзаиморасчеты = 1;
ПровестиДеньги = 1;
ПровестиПриказы = 1;
Перепроведение = 0;

ТипРП = ТипЗначенияСтр(ВидыДвижений);
Если ТипРП = "СписокЗначений" Тогда

ПровестиТовары = 0;
ПровестиВзаиморасчеты = 0;
ПровестиДеньги = 0;
ПровестиРасходыНаТовары = 0;
ПровестиПриказы = 0;

Перепроведение = 1;

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

ИначеЕсли ТипРП = "ТаблицаЗначений" Тогда

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

ИначеЕсли ТипРП = "Строка" Тогда
Если НРег(ВидыДвижений) = "перепроведение" Тогда
Перепроведение = 1;
КонецЕсли;
КонецЕсли;

// тар - т.к. отменено автоматическое удаление движений
спОчищаемыеРегистры = СоздатьОбъект("СписокЗначений");
Для Номер = 1 По Метаданные.Регистр() Цикл
УдалитьДвиженияРегистра = 1;
ИдРегистра = Метаданные.Регистр(Номер).Идентификатор;

ТекУчасток = "";
поз = глСоставРегистровПоУчасткам.НайтиЗначение(ИдРегистра);
Если поз > 0 Тогда
глСоставРегистровПоУчасткам.ПолучитьЗначение(поз, ТекУчасток);
КонецЕсли;

Если (ПровестиТовары = 0) И (ТекУчасток = "Товары") Тогда
УдалитьДвиженияРегистра = 0;
КонецЕсли;
Если (ПровестиВзаиморасчеты = 0) И (ТекУчасток = "Взаиморасчеты") Тогда
УдалитьДвиженияРегистра = 0;
КонецЕсли;
Если (ПровестиДеньги = 0) И (ТекУчасток = "Деньги") Тогда
УдалитьДвиженияРегистра = 0;
КонецЕсли;
Если (ПровестиРасходыНаТовары = 0) И (ТекУчасток = "Расходы на товары") Тогда
УдалитьДвиженияРегистра = 0;
КонецЕсли;
Если (ПровестиПриказы = 0) И (ТекУчасток = "Приказы") Тогда
УдалитьДвиженияРегистра = 0;
КонецЕсли;

Если УдалитьДвиженияРегистра = 1 Тогда
Конт.ОчиститьДвижения("Регистр." + ИдРегистра);
спОчищаемыеРегистры.ДобавитьЗначение(ИдРегистра);
КонецЕсли;

КонецЦикла; // тар

// тар
Если (Перепроведение = 1) И (ТипЗначенияСтр(ВидыДвижений) = "СписокЗначений") Тогда
//глСообщить("Очищаются регистры:" + спОчищаемыеРегистры.ВСтрокуСРазделителями(), "i");
КонецЕсли; // тар

СписокПараметров.Установить("ПровестиТовары" , ПровестиТовары );
СписокПараметров.Установить("ПровестиРасходыНаТовары" , ПровестиРасходыНаТовары );
СписокПараметров.Установить("ПровестиВзаиморасчеты" , ПровестиВзаиморасчеты );
СписокПараметров.Установить("ПровестиДеньги" , ПровестиДеньги );
СписокПараметров.Установить("ПровестиПриказы" , ПровестиПриказы );

СписокПараметров.Установить("Перепроведение" , Перепроведение );

Возврат Рез;

КонецФункции

5. Если ВидДвижений — СписокЗначений, запустить в ОбработкеПроведения механизм очистки содержимого регистров, которые будут перепроводится и не трогать регистры, которые проводиться не будут

Если глУправлениеПроведениемДокумента(Контекст, ВидыДвижений, спУправлениеПроведением) = 0 Тогда
Возврат;
Иначе
ПровестиТовары = спУправлениеПроведением.Получить("ПровестиТовары");
ПровестиРасходыНаТовары = спУправлениеПроведением.Получить("ПровестиРасходыНаТовары");
ПровестиВзаиморасчеты = спУправлениеПроведением.Получить("ПровестиВзаиморасчеты");
ПровестиДеньги = спУправлениеПроведением.Получить("ПровестиДеньги");

Перепроведение = спУправлениеПроведением.Получить("Перепроведение");
КонецЕсли; // тар

6. В зависимости от перепроводимых участков, вызвать нужные процедуры расчета и заполнения регистров

Если ПровестиТовары = 1 Тогда // участок - товары

ДвиженияПартии();
ДвиженияРезерв();

КонецЕсли;

Если ПровестиВзаиморасчеты = 1 Тогда

ДвиженияВзаиморасчеты();

КонецЕсли;

7. Добавить в глобальный модуль процедуру заполнения движений регистра по таблице значений

Функция Присвоить(Чему,Что) Экспорт
Чему = Что;
Возврат "";
КонецФункции

Процедура глПровестиПоТаблицеЗначений(Конт, ВидыДвижений) Экспорт

ВидыДвижений.ВыбратьСтроки();
Пока ВидыДвижений.ПолучитьСтроку() = 1 Цикл
ВидРегистра = СокрЛП(ВидыДвижений.Регистр);
ОпределениеРегистра = "Регистр." + ВидРегистра;
ТекРегистр = ВидыДвижений.ДвиженияРегистра;

Если НЕ(ТипЗначенияСтр(ТекРегистр) = "ТаблицаЗначений") Тогда
Продолжить
КонецЕсли;

Конт.ОчиститьДвижения(ОпределениеРегистра);

Рег = 0;
СсылкаНаРегистр = "Конт." + ОпределениеРегистра;
Шаблон("[Присвоить(Рег, " + Шаблон("[СсылкаНаРегистр]") + ")]");

Для дв = 1 По ТекРегистр.КоличествоСтрок() Цикл
ТекРегистр.ПолучитьСтрокуПоНомеру(дв);
Для к = 1 По ТекРегистр.КоличествоКолонок() Цикл
ТекАтрибут = ТекРегистр.ПолучитьПараметрыКолонки(к);
ТекЗначениеАтрибута = ТекРегистр.ПолучитьЗначение(дв, к);
Если ТекАтрибут = "НомерСтрокиРегистра" Тогда
Если ТекЗначениеАтрибута > 0 Тогда
Рег.ПривязыватьСтроку(ТекЗначениеАтрибута);
КонецЕсли;
ИначеЕсли (ТекАтрибут = "НомерСтроки") ИЛИ (ТекАтрибут = "ФлагДвижения") Тогда
Продолжить
Иначе
Рег.УстановитьАтрибут(ТекАтрибут, ТекЗначениеАтрибута);
КонецЕсли;
КонецЦикла;
ФлагДвижения = ТекРегистр.ФлагДвижения;
Если ФлагДвижения = "+" Тогда
Рег.ДвижениеПриходВыполнить();
ИначеЕсли ФлагДвижения = "-" Тогда
Рег.ДвижениеРасходВыполнить();
Иначе
Рег.ДвижениеВыполнить();
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры

8. Добавить в конфигурацию обработку «Управление содержимым документа» из этой статьи

3 Comments

  1. Ёпрст
  2. axxell

    (1) Ёпрст,

    Ага, хорошая обработка, проголосовал. Только я свою создал в 2008 году и дополнительно предлагаю механизм группового проведения по некоторым регистрам документа, а не по всем сразу.

    Reply
  3. Ёпрст

    на счет давности, аналогичные поделки на проклабе валяются еще с 2000 года.

    Смысл моей поделки — не трогать конфу и код в ней вообще.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *