Что такое модули и зачем они нужны?
Модуль — это контейнер для программного кода в 1С. Каждый объект метаданных имеет свой модуль, где описывается его поведение.
Основные типы модулей:
-
Модуль формы — обработка событий интерфейса
-
Модуль объекта — бизнес-логика объекта
-
Модуль менеджера — общие методы для работы с объектом
-
Общие модули — переиспользуемый код
-
Модуль сеанса — глобальные настройки и функции
Модуль формы — для работы с интерфейсом
bsl// Модуль формы документа "Заказ покупателя" &НаКлиенте Процедура ПриОткрытии(Отказ) // Инициализация значений по умолчанию Если Объект.Новый() Тогда Объект.Дата = ТекущаяДата(); Объект.Организация = ОсновнаяОрганизация(); КонецЕсли; // Настройка интерфейса Элементы.ПолеСкидки.Видимость = ПользовательИмеетПраво("ИзменениеСкидок"); КонецПроцедуры &НаКлиенте Процедура КонтрагентПриИзменении(Элемент) // Автозаполнение связанных полей Если Объект.Контрагент <> Неопределено Тогда Объект.Договор = Неопределено; // Сбрасываем договор ЗаполнитьСписокДоговоров(); // Обновляем доступные договоры КонецЕсли; КонецПроцедуры &НаКлиенте Процедура РассчитатьСумму(Кнопка) // Вызываем серверный метод для расчетов Сумма = РассчитатьИтоговуюСуммуНаСервере(Объект.Ссылка); Элементы.ПолеСуммы.Значение = Сумма; КонецПроцедуры
Что размещать в модуле формы:
-
Обработчики событий элементов управления
-
Логику взаимодействия с пользователем
-
Валидацию вводимых данных
-
Визуальные эффекты и анимации
Модуль объекта — для бизнес-логики
bsl// Модуль объекта документа "Заказ покупателя" &НаСервере Процедура ПриЗаписи(Отказ) // Проверка обязательных полей Если Объект.Контрагент = Неопределено Тогда Отказ = Истина; Сообщить("Не выбран контрагент!"); Возврат; КонецЕсли; // Автоматические расчеты Если Объект.Сумма = 0 Тогда Объект.Сумма = РассчитатьСуммуДокумента(); КонецЕсли; // Установка номера Если Объект.Новый() Тогда Объект.Номер = ПолучитьСледующийНомер(); КонецЕсли; КонецПроцедуры &НаСервере Процедура ОбработкаПроведения(Отказ, РежимПроведения) // Резервирование товаров Если Не РезервироватьТоварыНаСкладе() Тогда Отказ = Истина; Возврат; КонецЕсли; // Создание движений по регистрам СформироватьДвиженияВзаиморасчетов(); СформироватьДвиженияОстатковТоваров(); КонецПроцедуры &НаСервере Функция РассчитатьСуммуДокумента() Запрос = Новый Запрос; Запрос.Текст = " | ВЫБРАТЬ | SUM(Товары.Сумма) КАК СуммаДокумента | ИЗ | Документ.ЗаказПокупателя.Товары КАК Товары | ГДЕ | Товары.Ссылка = &Ссылка"; Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка); Результат = Запрос.Выполнить().Выбрать(); Если Результат.Следующий() Тогда Возврат Результат.СуммаДокумента; КонецЕсли; Возврат 0; КонецФункции
Что размещать в модуле объекта:
-
Обработку событий жизненного цикла объекта (запись, проведение)
-
Бизнес-правила и валидации
-
Сложные расчеты и преобразования данных
-
Интеграционную логику
Модуль менеджера — для общих операций
bsl// Модуль менеджера справочника "Номенклатура" &НаСервере Функция НайтиПоАртикулу(Артикул) Запрос = Новый Запрос; Запрос.Текст = " | ВЫБРАТЬ | Номенклатура.Ссылка | ИЗ | Справочник.Номенклатура КАК Номенклатура | ГДЕ | Номенклатура.Артикул = &Артикул"; Запрос.УстановитьПараметр("Артикул", Артикул); Результат = Запрос.Выполнить().Выбрать(); Если Результат.Следующий() Тогда Возврат Результат.Ссылка; КонецЕсли; Возврат Неопределено; КонецФункции &НаСервере Функция СоздатьЭлемент(Наименование, Артикул = "", ТипНоменклатуры = Неопределено) НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент(); НовыйЭлемент.Наименование = Наименование; НовыйЭлемент.Артикул = Артикул; Если ТипНоменклатуры <> Неопределено Тогда НовыйЭлемент.ТипНоменклатуры = ТипНоменклатуры; КонецЕсли; НовыйЭлемент.Записать(); Возврат НовыйЭлемент.Ссылка; КонецФункции &НаСервере Процедура УстановитьЦену(СсылкаНоменклатуры, Цена, ТипЦены) Запись = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи(); Запись.Период = ТекущаяДата(); Запись.Номенклатура = СсылкаНоменклатуры; Запись.ТипЦены = ТипЦены; Запись.Цена = Цена; Запись.Записать(); КонецПроцедуры
Что размещать в модуле менеджера:
-
Методы для поиска и создания объектов
-
Операции с группами объектов
-
Утилиты для работы с данным типом объектов
-
Статические методы доступа к данным
Общие модули — для переиспользуемого кода
bsl// Общий модуль "РаботаСФайлами" // Настройки: Сервер (вызывается на сервере), Привилегированный (не требует прав) &НаСервере Функция ПрочитатьФайл(ПутьКФайлу) Экспорт Попытка ЧтениеФайла = Новый ЧтениеТекста(ПутьКФайлу); Возврат ЧтениеФайла.Прочитать(); Исключение ВызватьИсключение "Ошибка чтения файла: " + ОписаниеОшибки(); КонецПопытки; КонецФункции &НаСервере Функция ЗаписатьВФайл(Данные, ПутьКФайлу) Экспорт Попытка ЗаписьФайла = Новый ЗаписьТекста(ПутьКФайлу); ЗаписьФайла.Записать(Данные); ЗаписьФайла.Закрыть(); Возврат Истина; Исключение Сообщить("Ошибка записи: " + ОписаниеОшибки()); Возврат Ложь; КонецПопытки; КонецФункции // Общий модуль "РаботаСДатами" &НаСервере Функция ПолучитьНачалоМесяца(Дата = Неопределено) Экспорт Если Дата = Неопределено Тогда Дата = ТекущаяДата(); КонецЕсли; Возврат НачалоМесяца(Дата); КонецФункции &НаСервере Функция ПолучитьКоличествоРабочихДней(ДатаНачала, ДатаОкончания) Экспорт // Логика расчета рабочих дней... Возврат КоличествоДней; КонецФункции
Что размещать в общих модулях:
-
Утилиты и хелперы
-
Алгоритмы не привязанные к конкретным объектам
-
Интеграционные сервисы
-
Математические функции
Принципы организации кода
1. Принцип единой ответственности
bsl// ПЛОХО - модуль делает слишком много Процедура ОбработатьЗаказ() // Проверяем данные... // Рассчитываем цены... // Сохраняем в базу... // Отправляем email... // Формируем отчет... КонецПроцедуры // ХОРОШО - разделяем ответственность Процедура ОбработатьЗаказ() Если Не ПроверитьДанные() Тогда Возврат; КонецЕсли; РассчитатьИтоги(); СохранитьЗаказ(); ОтправитьУведомления(); КонецПроцедуры
2. Принцип DRY (Don't Repeat Yourself)
bsl// ПЛОХО - дублирование кода Процедура ЗаписатьДокумент1() // 20 строк проверок и подготовки... Документ1.Записать(); КонецПроцедуры Процедура ЗаписатьДокумент2() // Те же 20 строк проверок и подготовки... Документ2.Записать(); КонецПроцедуры // ХОРОШО - выносим общую логику Процедура ПодготовитьКЗаписи(Документ) // 20 строк проверок и подготовки... КонецПроцедуры Процедура ЗаписатьДокумент1() ПодготовитьКЗаписи(Документ1); Документ1.Записать(); КонецПроцедуры
3. Правило "один уровень абстракции"
bsl// ПЛОХО - смешиваем уровни абстракции Процедура ОбработатьПлатеж() // Высокий уровень Если Не ПроверитьЛимиты() Тогда Возврат; КонецЕсли; // Низкий уровень - работа с файлами Файл = Новый ЧтениеТекста("C:\payments\file.txt"); Данные = Файл.Прочитать(); // Высокий уровень СоздатьДокументПоступления(); // Низкий уровень - SQL запрос Запрос = Новый Запрос("ВЫБРАТЬ ..."); КонецПроцедуры // ХОРОШО - разделяем уровни Процедура ОбработатьПлатеж() Если Не ПроверитьЛимиты() Тогда Возврат; КонецЕсли; Данные = ПрочитатьФайлПлатежа(); СоздатьДокументПоступления(Данные); КонецПроцедуры
Чек-лист организации модулей
Для модуля формы:
-
Только клиентские методы (кроме вызовов на сервер)
-
Только работа с интерфейсом
-
Минимум бизнес-логики
-
Четкие обработчики событий
Для модуля объекта:
-
Бизнес-правила и валидации
-
Обработка событий жизненного цикла
-
Сложные расчеты
-
Интеграционная логика
Для общего модуля:
-
Четкое назначение (работа с датами, файлами, строками)
-
Правильные настройки вызова (сервер/клиент)
-
Только экспортируемые методы
-
Независимость от конкретных объектов
Заключение
Золотые правила организации кода:
-
Каждый модуль должен иметь четкую зону ответственности
-
Избегайте дублирования кода — создавайте общие модули
-
Разделяйте уровни абстракции — не смешивайте логику и детали реализации
-
Следуйте принципам SOLID — особенно принципу единой ответственности
Правильно организованный код легче поддерживать, тестировать и развивать. Начинайте с простой структуры и постепенно refactor-ите код по мере роста проекта. Хорошая архитектура сэкономит вам время и нервы в будущем!
