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