Как программно выбрать значение реквизита из справочника и сохранить файл Word в 1С?

Программист 1С v8.3 (Обычные формы)
← На главную

В процессе разработки в среде «1С:Предприятие 8» (особенно в обычных формах) часто возникают задачи, выходящие за рамки стандартного поведения платформы. Одной из таких задач является необходимость при выборе из справочника подставлять в поле ввода не ссылку на объект и не его наименование, а значение конкретного текстового реквизита. Параллельно с этим часто требуется автоматизировать работу с внешними файлами, например, формировать договор в MS Word, сохранять его в структурированную папку на диске и прикреплять к базе данных.

В данной статье мы разберем, как правильно реализовать программный выбор данных, настроить фильтрацию в открывающихся формах и организовать безошибочную работу с COM-объектами для сохранения документов.

Реализация нестандартного выбора данных

Рассмотрим ситуацию: на форме справочника Контрагенты есть поле ввода, связанное с реквизитом ДоговорПокупки. Нам нужно, чтобы при нажатии на кнопку выбора открывался справочник ХранилищеДополнительнойИнформации, но после выбора строки в поле попадало не наименование справочника, а данные из его реквизита ДомДоговор.

Для решения этой задачи нам потребуется переопределить стандартную обработку выбора. Проанализируем шаги реализации:

  1. Изменение типа данных: Если нам нужно хранить именно текст договора, тип реквизита ДоговорПокупки должен быть Строка. Если же мы хотим сохранить связь с объектом, тип должен оставаться ссылочным, но в таком случае для отображения текста потребуется дополнительное текстовое поле на форме.
  2. Событие НачалоВыбора: Мы должны остановить стандартное открытие формы и вызвать её программно, передав элемент формы в качестве владельца.
  3. Событие ОбработкаВыбора: Здесь мы перехватываем выбранную ссылку и извлекаем из неё нужный нам реквизит.

Разберем пример кода для этих событий:


Процедура ДоговорПокупкиНачалоВыбора(Элемент, СтандартнаяОбработка)
    // Отключаем стандартный механизм открытия справочника
    СтандартнаяОбработка = Ложь;
    
    // Получаем форму выбора программно
    ФормаВыбора = Справочники.ХранилищеДополнительнойИнформации.ПолучитьФормуВыбора(, Элемент);
    
    // Открываем форму
    ФормаВыбора.Открыть();
КонецПроцедуры

Процедура ДоговорПокупкиОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
    // Отменяем стандартное заполнение поля ссылкой
    СтандартнаяОбработка = Ложь;
    
    // Проверяем, что значение выбрано и имеет нужный тип
    Если ЗначениеЗаполнено(ВыбранноеЗначение) И ТипЗнч(ВыбранноеЗначение) = Тип("СправочникСсылка.ХранилищеДополнительнойИнформации") Тогда
        // Записываем в реквизит формы значение конкретного поля выбранного объекта
        ДоговорПокупки = ВыбранноеЗначение.ДомДоговор;
    КонецЕсли;
КонецПроцедуры

Использование свойства СтандартнаяОбработка = Ложь критически важно, так как оно говорит платформе, что программист берет управление процессом на себя.

Установка фильтра при открытии формы выбора

Часто требуется, чтобы пользователь видел не весь список справочника, а только те записи, которые относятся к текущему объекту (например, только файлы текущего контрагента). Рассмотрим, как установить отбор по наименованию в открываемой форме.

Проанализируем ситуацию: нам нужно сравнить Наименование контрагента с Наименованием в хранилище. Для этого в процедуре НачалоВыбора перед открытием формы добавим настройки отбора:


Процедура ДоговорПокупкиНачалоВыбора(Элемент, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    Форма2 = Справочники.ХранилищеДополнительнойИнформации.ПолучитьФормуВыбора(, Элемент);
    
    // Настройка фильтра (отбора)
    // Устанавливаем использование отбора по наименованию
    Форма2.Отбор.Наименование.Использование = Истина;
    // Указываем значение для фильтрации (берем из текущего объекта)
    Форма2.Отбор.Наименование.Значение = Наименование; 
    // Вид сравнения по умолчанию "Равно"
    
    Форма2.Открыть();
КонецПроцедуры

Важный нюанс: Фильтрация по строковому наименованию не всегда надежна. Если есть возможность, лучше использовать отбор по реквизиту Объект (владелец информации), где хранится ссылка на контрагента.

Автоматизация сохранения документов через MS Word

Теперь рассмотрим более сложный процесс: программное создание папки на диске, сохранение туда документа Word и последующая загрузка этого файла в базу данных 1С в объект ХранилищеЗначения.

Выясним причину частых ошибок при сохранении. Основная проблема заключается в попытке прочитать файл (создать ДвоичныеДанные), пока он еще открыт в приложении Word. Для успешной работы необходимо соблюдать строгую последовательность действий.

Разберем алгоритм по шагам:

  1. Сформировать путь к каталогу и убедиться в его существовании.
  2. Использовать метод SaveAs у COM-объекта Word.
  3. Обязательно закрыть документ и завершить работу с объектом Word.
  4. Прочитать файл с диска в объект ДвоичныеДанные.
  5. Записать данные в справочник ХранилищеДополнительнойИнформации.

Посмотрим на пример реализации:


// 1. Подготовка пути
ДатаД = Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy");
НоваяПапка = "F:\Dogovora\" + ДатаД;

// Проверяем наличие каталога и создаем его при необходимости
КаталогОбъект = Новый Файл(НоваяПапка);
Если НЕ КаталогОбъект.Существует() Тогда
    СоздатьКаталог(НоваяПапка);
КонецЕсли;

// Формируем полное имя файла
ИмяФайла = НомеДог + " на " + НаименованиеПолное + ".doc";
ПолныйПуть = НоваяПапка + "\" + ИмяФайла;

// 2. Сохранение документа через Word
Попытка
    Word.SaveAs(ПолныйПуть, 0); // 0 - формат документа Word 97-2003
    // 3. Критически важный шаг: закрываем Word перед чтением файла!
    Word.Close();
    Word = Неопределено;
Исключение
    Сообщить("Ошибка при сохранении Word: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

// 4. Чтение файла в 1С
Попытка
    ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПолныйПуть);
    
    // 5. Запись в справочник
    НовыйФайл = Справочники.ХранилищеДополнительнойИнформации.СоздатьЭлемент();
    НовыйФайл.Объект = Ссылка;
    НовыйФайл.Наименование = "Договор " + НомеДог;
    НовыйФайл.Хранилище = Новый ХранилищеЗначения(ДвоичныеДанныеФайла, Новый СжатиеДанных(9));
    НовыйФайл.Записать();
    
    Сообщить("Файл успешно сохранен и прикреплен!");
Исключение
    Сообщить("Не удалось прочитать файл с диска: " + ОписаниеОшибки());
КонецПопытки;

Рекомендации по работе с файлами и путями

При работе с файловой системой и внешними компонентами следует придерживаться нескольких правил, чтобы избежать «зависания» процессов и ошибок доступа:

Проанализировав вышеописанные подходы, мы видим, что гибкость платформы 1С позволяет реализовать практически любой сценарий взаимодействия с пользователем и внешним ПО, если правильно использовать событийную модель и методы работы с файловой системой.

← На главную