Как программно создать Excel-файл из 1С с выпадающими списками и защитой данных

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработчика 1С часто возникает задача организовать сбор данных от пользователей, которые не имеют прямого доступа к информационной базе. Одним из наиболее удобных и привычных инструментов для таких пользователей является Microsoft Excel. Однако, чтобы обеспечить корректность последующей загрузки данных обратно в 1С, нам необходимо строго ограничить варианты выбора в ячейках файла — создать так называемые "выпадающие списки" или механизм Data Validation (Проверка данных).

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

Реализация через COM-объект Excel

Самый распространенный способ управления Excel из 1С — это использование объекта COMОбъект("Excel.Application"). Рассмотрим алгоритм действий: нам нужно создать книгу с двумя листами. На первый лист пользователь будет вносить данные, а на втором листе будет храниться справочная информация (номенклатура, склады, ставки НДС), из которой будут формироваться списки выбора.

Разберем пример кода, который создает файл, заполняет технический лист данными из массива (или списка значений) и накладывает ограничение на колонку первого листа:


&НаКлиенте
Процедура СоздатьExcel(Команда)
    // 1. Получаем данные для заполнения списков (например, массив наименований номенклатуры)
    СписокНоменклатуры = ПолучитьСписокНаСервере(); 
    
    // 2. Инициализация Excel
    ПриложениеExcel = Новый COMОбъект("Excel.Application");
    ПриложениеExcel.DisplayAlerts = 0; // Отключаем уведомления
    ПриложениеExcel.Visible = 0;       // Работаем в фоновом режиме
    ПриложениеExcel.SheetsInNewWorkbook = 2; // Сразу создаем книгу с 2 листами
    
    КнигаExcel = ПриложениеExcel.Workbooks.Add();
    
    // 3. Оформляем первый лист (для пользователя)
    Лист1 = КнигаExcel.Sheets(1);
    Лист1.Name = "Для заполнения";
    Лист1.Cells(1, 1).Value = "Выберите номенклатуру";
    
    // 4. Оформляем второй лист (служебные данные)
    Лист2 = КнигаExcel.Sheets(2);
    Лист2.Name = "Данные";
    
    Для А = 1 По СписокНоменклатуры.Количество() Цикл
        Лист2.Cells(А, 1).Value = СписокНоменклатуры[А-1];
    КонецЦикла;
    
    // 5. Создаем именованный диапазон для удобной ссылки в проверке данных
    // Важно: ссылка должна быть в стиле R1C1 или A1, здесь используем R1C1
    АдресДиапазона = "=Данные!R1C1:R" + СписокНоменклатуры.Количество() + "C1";
    КнигаExcel.Names.Add("СписокДляВыбора", АдресДиапазона);
    
    // 6. Накладываем проверку данных на диапазон ячеек первого листа (например, первые 200 строк)
    // Type = 3 (xlValidateList), Formula1 = "=ИмяДиапазона"
    Для Б = 2 По 201 Цикл
        Лист1.Range("A" + Б).Validation.Add(3, 1, 1, "=СписокДляВыбора");
    КонецЦикла;
    
    // 7. Устанавливаем защиту на лист с данными и скрываем его
    Лист2.Protect("Пароль123");
    Лист2.Visible = 0; // Лист скрыт, но его можно отобразить вручную
    
    // 8. Сохранение и выход
    ПутьКФайлу = "C:\Temp\ШаблонДляЗаполнения.xls";
    КнигаExcel.SaveAs(ПутьКФайлу, -4143); // Формат Excel 97-2003
    ПриложениеExcel.Quit();
    
    Сообщить("Файл сформирован: " + ПутьКФайлу);
КонецПроцедуры

Тонкости настройки "Проверки данных"

При программном создании списков через Validation.Add следует учитывать несколько технических ограничений:

  1. Ограничение по длине формулы: Если передавать список значений напрямую в параметр Formula1 (через запятую), длина строки не должна превышать 255 символов. Именно поэтому мы использовали именованный диапазон (Names.Add). Ссылка на именованный диапазон позволяет обходить это ограничение и работать с тысячами строк данных.
  2. Синтаксис параметров: Метод Validation.Add принимает следующие основные параметры: Type (тип проверки, для списка это 3), AlertStyle, Operator и Formula1. При использовании списков параметры AlertStyle и Operator обычно принимают значение 1.
  3. Локализация: В некоторых версиях Excel при программном управлении важно соблюдать соответствие разделителей (запятая или точка с запятой), однако использование именованных диапазонов снимает большинство этих проблем.

Улучшенная защита данных и скрытие листов

Если мы хотим, чтобы пользователь вообще не видел служебный лист "Данные", обычного скрытия Visible = 0 может быть недостаточно, так как пользователь может нажать правую кнопку мыши на ярлыке листа и выбрать команду "Отобразить".

Для более надежной защиты проанализируем свойство xlSheetVeryHidden. Если установить Лист2.Visible = -2, лист станет "очень скрытым". Его невозможно отобразить через стандартный интерфейс Excel — только программно или через редактор VBA. Это гарантирует, что пользователь случайно не повредит структуру справочных данных.

Также хорошей практикой является защита структуры всей книги через КнигаExcel.Protect("пароль", Истина, Истина). Это запретит пользователю добавлять новые листы или удалять существующие, сохраняя целостность нашего шаблона.

Динамические списки с помощью формул Excel

В нашем примере мы жестко задали диапазон для имени "СписокДляВыбора". Если вы планируете, что данные на листе "Данные" могут дополняться, рассмотрим вариант с использованием формулы СМЕЩ (OFFSET). Это позволит списку автоматически расширяться при добавлении новых строк.

Пример задания динамического диапазона через код 1С:


КнигаExcel.Names.Add("ДинамическийСписок", "=СМЕЩ(Данные!$A$1;0;0;СЧЁТЗ(Данные!$A:$A);1)");

Здесь функция СЧЁТЗ (COUNTA) подсчитывает количество непустых ячеек в колонке А, а СМЕЩ формирует из них итоговый диапазон для выпадающего списка.

Подготовка к обратной загрузке: использование ID

Разберем ситуацию, когда в базе 1С есть две номенклатуры с одинаковым наименованием. Если пользователь выберет наименование в Excel, при загрузке возникнет неоднозначность. Выясним, как этого избежать.

Рекомендуется на скрытый лист выгружать данные в две колонки: Наименование и Уникальный идентификатор (GUID). В выпадающем списке пользователь будет видеть наименования, но при загрузке файла в 1С мы сможем программно прочитать GUID из соседней ячейки скрытого листа (используя функции поиска VLOOKUP в Excel или просто сопоставление строк в 1С). Это обеспечит 100% точность идентификации объектов.

Важные предупреждения при работе на сервере

Проанализируем ситуацию использования данного кода в серверных процедурах 1С (например, в регламентных заданиях). Использование Excel.Application на сервере является плохой практикой по нескольким причинам:

Если файл должен формироваться на сервере, рассмотрите возможность использования сторонних библиотек, которые работают с форматом XLSX напрямую как с XML-архивом (например, компоненты на базе .NET), или используйте штатный механизм ТабличныйДокумент.Записать(Путь, ТипФайлаТабличногоДокумента.XLSX), хотя последний и не поддерживает создание выпадающих списков "из коробки". Для формирования многостраничных файлов без офисных пакетов и COM-компонентов подойдёт решение для выгрузки данных из 1С в Excel с несколькими листами.

Таким образом, мы рассмотрели полноценный механизм создания интерактивных Excel-шаблонов. Сочетание программного управления COM-объектом и встроенных функций Excel (именованные диапазоны, проверка данных, защита листов) позволяет создавать надежные инструменты для обмена данными с внешними пользователями. При необходимости избежать программного формирования разметки можно использовать инструмент для выгрузки данных из 1С в готовый шаблон Excel.

← На главную