При разработке внешних обработок в среде «1С:Предприятие 8» начинающие специалисты часто сталкиваются с архитектурными и интерфейсными трудностями. Типичный пример — задача по созданию загрузчика данных из внешнего файла (например, формата XLSX), где на форме необходимо предоставить пользователю возможность выбирать вид цены из справочника, задавать ключ поиска номенклатуры и устанавливать флаги по умолчанию. Попытки решить эти задачи «в лоб» через написание сложных запросов и ручное заполнение списков выбора часто приводят к неработающему коду и перегрузке интерфейса.
В этой статье мы подробно разберем, как правильно реализовать данный функционал, опираясь на лучшие практики разработки на платформе «1С:Предприятие 8.3» для конфигурации «1С:Управление торговлей» (УТ 11). Мы уделим внимание как интерфейсным механизмам платформы, так и архитектуре хранения цен в типовом решении.
Первый вопрос, с которым сталкивается разработчик: как сделать так, чтобы при открытии формы обработки флажок «Перезаписывать дубли» (имеющий тип Булево) уже был установлен в значение Истина?
В старых версиях платформы (на обычных формах) для этого традиционно использовалось событие формы ПриОткрытии(). Однако в современной парадигме управляемого приложения (1С 8.3) инициализацию реквизитов формы крайне рекомендуется выполнять на сервере в обработчике события ПриСозданииНаСервере. Это позволяет избежать лишних серверных вызовов и подготовить данные формы до того, как она будет передана на клиент и отображена пользователю.
Рассмотрим правильный вариант реализации инициализации реквизитов:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Устанавливаем флаг перезаписи дублей по умолчанию в значение Истина
Объект.ПерезаписыватьДубли = Истина;
КонецПроцедуры
Если реквизит ПерезаписыватьДубли создан в самой обработке (в ветке метаданных «Реквизиты»), то на форме мы обращаемся к нему через стандартный реквизит формы Объект (как показано в примере выше). Если же это просто локальный реквизит формы, обращение будет происходить напрямую по имени: ПерезаписыватьДубли = Истина;.
Начинающие разработчики часто пытаются вручную написать запрос к регистру сведений или справочнику, выгрузить результат в таблицу или список значений, а затем программно вызывать метод ВыбратьИзСписка(). Это в корне неверный подход для платформы 1С. Платформа обладает мощным встроенным функционалом для работы со ссылочными типами данных.
Выясним причину, почему ручной запрос — это плохая идея:
Строка), вы лишаете систему возможности работать со ссылками. В дальнейшем, при записи цен, вам понадобится именно ссылка на элемент справочника (СправочникСсылка.ВидыЦен), а не его текстовое представление.Выполним правильную настройку поля «Вид цены» по шагам:
ВидЦены.ВидыЦен. Соответственно, тип должен быть: СправочникСсылка.ВидыЦен (в старых редакциях УТ 10.3 этот справочник назывался ТипыЦенНоменклатуры).ВидЦены на рабочую область формы, чтобы платформа автоматически сгенерировала элемент управления типа Поле ввода.БыстрыйВыбор) и установите для него значение Истина.Что это дает? При активации свойства «Быстрый выбор» платформа автоматически преобразует стандартное поле ввода в удобный выпадающий список. При нажатии на кнопку выбора пользователь сразу увидит список всех элементов справочника ВидыЦен, созданных в информационной базе. При этом у него останется возможность нажать кнопку «Показать все» для перехода к полноценной форме выбора справочника, если элементов окажется слишком много. Ни одной строчки программного кода для этого писать не требуется.
В процессе выполнения подобных задач важно понимать внутреннюю архитектуру конфигурации. Участники форумов часто путают регистры и документы. Разберем детальнее, как именно в УТ 11 хранятся и задаются цены продажи товаров.
Цены номенклатуры в системе хранятся в периодическом регистре сведений ЦеныНоменклатуры. Однако данный регистр является подчиненным регистратору. Это означает, что вы не можете напрямую сделать запись в этот регистр с помощью менеджера записи или набора записей (как в случае с независимыми регистрами сведений). Любые изменения в регистр должны вноситься только путем проведения документов-регистраторов.
Единственным стандартным документом, который выступает в роли регистратора для цен номенклатуры, является документ УстановкаЦенНоменклатуры. Таким образом, алгоритм вашей обработки при нажатии кнопки «Загрузить» должен быть следующим:
Номенклатура.УстановкаЦенНоменклатуры.ВидЦены (передав туда ссылку из нашего поля формы ВидЦены) и заполнить табличную часть товарами и их стоимостью.ЦеныНоменклатуры и станут доступны для использования в заказах и продажах.По условию задачи, поле «Ключ поиска» должно содержать строго определенный набор значений: «Артикул», «Код» или «Наименование». Вводить произвольный текст туда нельзя.
Для реализации этого требования настроим элемент формы:
КлючПоиска с типом Строка.РежимВыбораИзСписка = Истина). Это заблокирует ручной ввод текста пользователем.Истина.Теперь наполним этот список предопределенными значениями при создании формы на сервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Инициализация флага перезаписи дублей
Объект.ПерезаписыватьДубли = Истина;
// Программное заполнение списка выбора для ключа поиска
Элементы.КлючПоиска.СписокВыбора.Добавить("Артикул");
Элементы.КлючПоиска.СписокВыбора.Добавить("Код");
Элементы.КлючПоиска.СписокВыбора.Добавить("Наименование");
// Установим значение по умолчанию для ключа поиска
КлючПоиска = "Артикул";
КонецПроцедуры
Часто в технических заданиях присутствует требование: «при нажатии на кнопку Открыть в поле Путь к файлу, указанный файл должен открываться для просмотра». Многие разработчики предлагают пользователю самостоятельно находить файл в проводнике ОС и открывать его отдельно. Но для реализации хорошего тона программирования мы можем сделать это непосредственно из интерфейса 1С.
Для этого у поля ввода пути к файлу на форме включим свойство «Кнопка открытия» (КнопкаОткрытия = Истина). После этого у элемента появится стандартная кнопка в виде лупы или стрелки. Нам остается лишь прописать обработчик события открытия на клиенте:
&НаКлиенте
Процедура ПутьКФайлуОткрытие(Элемент, СтандартнаяОбработка)
// Отменяем стандартное системное действие платформы
СтандартнаяОбработка = Ложь;
// Проверяем заполненность пути к файлу
Если Не ПустаяСтрока(Объект.ПутьКФайлу) Тогда
// Запуск приложения, ассоциированного с файлом в операционной системе
ЗапуститьПриложение(Объект.ПутьКФайлу);
Иначе
ПоказатьПредупреждение(, "Не указан путь к файлу для просмотра!");
КонецЕсли;
КонецПроцедуры
Метод ЗапуститьПриложение() передает операционной системе команду на запуск указанного файла. Если в системе установлен Microsoft Excel, LibreOffice или другое приложение для работы с электронными таблицами, файл мгновенно откроется в нем для просмотра.
В завершение рассмотрим важный аспект интеграции. Традиционный способ чтения файлов Excel через COM-соединение (Новый COMОбъект("Excel.Application")) имеет ряд существенных недостатков: он требует обязательной установки MS Excel на компьютере пользователя, работает медленно и абсолютно несовместим с серверами под управлением ОС Linux.
Современный стандарт разработки в 1С рекомендует использовать для чтения файлов XLSX объект платформы ТабличныйДокумент. Этот метод полностью кроссплатформенный и работает невероятно быстро.
Рассмотрим пример программного кода для чтения загружаемого файла:
&НаСервере
Функция ПрочитатьФайлНаСервере(ПутьКФайлу)
ТабличныйДокумент = Новый ТабличныйДокумент;
Попытка
// Чтение файла формата XLSX в объект ТабличныйДокумент
ТабличныйДокумент.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
ВызватьИсключение "Не удалось прочитать файл! Ошибка: " + ОписаниеОшибки();
КонецПопытки;
// Получаем границы заполненной области таблицы
ВсегоСтрок = ТабличныйДокумент.ВысотаТаблицы;
ВсегоКолонок = ТабличныйДокумент.ШиринаТаблицы;
// Пример обхода строк файла (начиная со второй строки, предполагая наличие шапки)
Для НомерСтроки = 2 По ВсегоСтрок Цикл
КодТовара = ТабличныйДокумент.Область(НомерСтроки, 1).Текст;
Наименование = ТабличныйДокумент.Область(НомерСтроки, 2).Текст;
ЦенаТовара = ТабличныйДокумент.Область(НомерСтроки, 3).Значение; // Получаем числовое значение
// Далее здесь будет следовать логика поиска/создания номенклатуры
// и формирования документа установки цен
КонецЦикла;
Возврат Истина;
КонецФункции
Параметр СпособЧтенияЗначенийТабличногоДокумента.Значение указывает платформе, что при чтении ячеек необходимо извлекать типизированные значения (например, число для цен или дату для дат), а не просто их строковое представление, что существенно облегчает дальнейшую обработку данных.
Применяя данные подходы, вы сможете создать надежную, быструю и удобную внешнюю обработку, которая полностью соответствует стандартам разработки фирмы «1С» и успешно пройдет любую проверку качества кода.