gifts2017

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

Опубликовал Александр Тарасинский (axxell) в раздел Обработки - Обработка документов

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

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

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

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

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. Добавить в конфигурацию обработку "Управление содержимым документа" из этой статьи

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

Наименование Файл Версия Размер
Управление содержимым документа 51
.ert 217,00Kb
13.01.13
51
.ert 217,00Kb Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

2. Александр Тарасинский (axxell) 14.01.13 10:18
(1) Ёпрст,
Ага, хорошая обработка, проголосовал. Только я свою создал в 2008 году и дополнительно предлагаю механизм группового проведения по некоторым регистрам документа, а не по всем сразу.
3. Епрст (Ёпрст) 14.01.13 13:05
на счет давности, аналогичные поделки на проклабе валяются еще с 2000 года.
Смысл моей поделки - не трогать конфу и код в ней вообще.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа