При развитии торговых систем на базе 1С:Предприятие 7.7 часто возникает необходимость расширения стандартного функционала. Типичная задача — добавление возможности указывать способ доставки (например, «Самовывоз» или «Доставка») для каждого контрагента с последующей автоматической подстановкой этого значения в документы отгрузки.
В этой статье мы подробно разберем, как правильно реализовать эту задачу в конфигурации «Торговля и Склад 7.7» (включая локализованные версии, такие как «Торговля для Украины» от ABBYY), взвесим все за и против различных архитектурных подходов, напишем оптимизированную обработку для заполнения исторических данных и настроим интеграцию с документами.
---
Перед тем как вносить изменения в структуру метаданных в Конфигураторе, проанализируем, какой тип данных лучше использовать для реквизита «Способ доставки». В платформе 1С 7.7 у нас есть два основных пути:
SC***.dbf или таблице SQL). При построении отчетов отсутствуют лишние соединения (JOIN) таблиц.Если в вашей компании варианты доставки стабильны, смело выбираем Перечисление. Если планируется постоянное расширение логистических маршрутов и интеграция с курьерскими службами — выбираем Справочник.
---
Рассмотрим по шагам процесс создания нового реквизита на примере использования перечисления:
СпособыДоставки.Самовывоз (Синоним: Самовывоз)Доставка (Синоним: Доставка курьером / ТК)СпособДоставкиПеречисление.СпособыДоставкиКонтрагенты и перенесем новый реквизит на форму в виде поля выбора, чтобы пользователи могли его изменять.---
В типовой российской конфигурации «Торговля и Склад 7.7» существует мощный встроенный механизм — «Свойства контрагентов». Если вы работаете в украинской локализации или сильно измененной самописной конфигурации, этого механизма у вас может не оказаться. Однако мы можем перенести его вручную.
Проанализируем, какие объекты метаданных необходимо скопировать из типовой конфигурации «Торговля и Склад 7.7» через буфер обмена для развертывания этой системы:
ВидыСвойств — определяет категории свойств (например, «Способ доставки», «Надежность»).ЗначенияСвойств — хранит варианты значений, подчинен справочнику ВидыСвойств.СвойстваКонтрагентов — связывает конкретного контрагента с его свойствами и значениями. Этот справочник должен быть подчинен справочнику Контрагенты.После переноса метаданных достаточно разместить на форме списка или форме элемента справочника Контрагенты кнопку «Свойства» и прописать в ее формуле следующий вызов:
ОткрытьФорму("Справочник.СвойстваКонтрагентов", Контекст);
Этот способ максимально гибкий, так как позволяет добавлять любые новые свойства контрагентам (не только доставку) без изменения конфигурации в будущем.
---
После добавления нового реквизита нам необходимо установить значение по умолчанию (например, «Самовывоз») для всех уже существующих в базе контрагентов. Если база содержит тысячи записей, стандартный перебор элементов в цикле без оптимизации может привести к долгому зависанию системы и блокировке таблиц.
Рассмотрим оптимизированный алгоритм обновления данных с использованием механизма транзакций. Создадим внешнюю обработку (файл .ert) и напишем в модуле формы следующий код:
Процедура ВыполнитьОбновление()
спр = СоздатьОбъект("Справочник.Contragents"); // Укажите идентификатор вашего справочника (Контрагенты)
спр.ВыбратьЭлементы();
Счетчик = 0;
НачатьТранзакцию();
Пока спр.ПолучитьЭлемент() = 1 Цикл
// Пропускаем группы контрагентов, обновляем только элементы
Если спр.ЭтоГруппа() = 1 Тогда
Продолжить;
КонецЕсли;
// Изменяем только те элементы, у которых реквизит еще не заполнен
Если ПустоеЗначение(спр.СпособДоставки) = 1 Тогда
спр.Блокировка(1); // Блокируем элемент для предотвращения конфликтов совместного доступа
спр.СпособДоставки = Перечисление.СпособыДоставки.Самовывоз;
спр.Записать();
Счетчик = Счетчик + 1;
КонецЕсли;
// Каждые 500 элементов фиксируем транзакцию, чтобы не переполнять оперативную память и файлы транзакций СУБД
Если Счетчик % 500 = 0 Тогда
ЗафиксироватьТранзакцию();
НачатьТранзакцию();
КонецЕсли;
КонецЦикла;
ЗафиксироватьТранзакцию();
Предупреждение("Обновление успешно завершено! Обработано элементов: " + Счетчик);
КонецПроцедуры
Использование конструкции НачатьТранзакцию() и ЗафиксироватьТранзакцию() ускоряет процесс записи в файловой базе DBF в десятки раз, так как транзакции пишутся пакетами на диск, минуя постоянные дисковые операции записи для каждого отдельного файла.
---
Как совершенно верно подметили практикующие специалисты, способ доставки должен жестко фиксироваться в конкретной сделке (документе продажи), а значение в карточке контрагента должно служить лишь шаблоном для автоматического заполнения по умолчанию.
Разберем, как реализовать эту схему:
ЗаявкаПокупателя, Реализация).СпособДоставки с типом Перечисление.СпособыДоставки и вынесем его на форму документов.Реализация) и найдем процедуру изменения контрагента (обычно это процедура ПриВыбореКонтрагента() или вызов пересчета шапки).
Процедура ПриВыбореКонтрагента()
// Проверяем, что контрагент выбран
Если ПустоеЗначение(Контрагент) = 0 Тогда
// Автоматически заполняем способ доставки из карточки контрагента
СпособДоставки = Контрагент.СпособДоставки;
КонецЕсли;
// Другой типовой код обработки изменения контрагента...
КонецПроцедуры
При такой реализации менеджер всегда сможет изменить способ доставки в конкретном документе, если клиент в этот раз решил воспользоваться другим вариантом, но по умолчанию система всегда будет подставлять привычный для этого контрагента способ.
Если же вам требуется исключительно визуальное отображение способа доставки в документе без возможности его изменения в конкретной сделке (и без сохранения в документе), можно поступить проще. Достаточно разместить на форме документа текстовое поле, а в поле «Формула» указать динамическое выражение:
Контрагент.СпособДоставки
В этом случае платформа 1С 7.7 будет считывать значение «на лету» прямо из справочника контрагентов при открытии формы документа.