Как открыть другую базу 1С из текущей и отобрать в ней нужные документы?

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

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

Исходная ситуация заключается в следующем: необходимо из формы документа, например, "Поступление товаров и услуг" (ПТУ), по нажатию кнопки, запустить другую базу 1С, предназначенную для хранения инструкций. При этом важно, чтобы в открывшейся базе уже был применен определенный отбор, который мы передаем из текущей базы. Целевая база запускается методом ЗапуститьПриложение. Нам нужно понять, как "на той стороне" принять этот отбор и корректно его применить.

Прежде чем приступать к реализации, важно учитывать несколько факторов: возможности платформы (особенно если речь идет о старых версиях или специфических конфигурациях, как в упомянутой "гос. отрасли" или на "платформе Z"), вопросы лицензирования (каждое открытие новой базы может потреблять дополнительную лицензию), а также общую сложность поддержки создаваемого решения.

Метод 1: Передача параметров через командную строку (ЗапуститьПриложение)

Один из наиболее прямолинейных и универсальных способов — использование параметров командной строки при запуске 1С. Метод ЗапуститьПриложение позволяет передавать строку запуска с необходимыми ключами.

Формирование строки запуска

Для передачи параметров в конфигурацию мы используем ключ /C [строка текста]. Эта строка будет доступна в целевой базе через свойство ПараметрЗапуска. Если нам нужно передать несколько параметров или сложную структуру данных, рекомендуется сериализовать их в строку, например, в формате JSON или XML.

Рассмотрим, как мы можем сформировать строку запуска:


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

// Сериализуем параметры в JSON-строку
JSONСтрокаПараметров = ЗаписатьJSON(ПередаваемыеПараметры);

// Путь к исполняемому файлу 1С и к целевой базе
ПутьК1С = "C:\Program Files\1cv8\common\1cestart.exe"; // Или другой путь
ПутьКЦелевойБазе = "C:\Bases\Инструкции\"; // Путь к файловой базе

// Формируем полную строку запуска
СтрокаЗапуска = ПутьК1С + " ENTERPRISE /F " + ПутьКЦелевойБазе + " /N ПользовательИнструкций /P ПарольИнструкций /C """ + JSONСтрокаПараметров + """";

// Запускаем приложение
ЗапуститьПриложение(СтрокаЗапуска);

В этом примере:

  1. Мы создаем объект Соответствие для хранения наших параметров.
  2. Используем функцию ЗаписатьJSON для сериализации этого объекта в строку. Это удобно для передачи сложных данных.
  3. Собираем полную строку запуска, включая путь к платформе 1С, ключ ENTERPRISE для запуска в режиме предприятия, ключ /F для указания пути к файловой базе (или /S для клиент-серверной), а также /N и /P для автоматической авторизации пользователя.
  4. Самое главное — используем ключ /C, в кавычках передавая нашу JSON-строку. Двойные кавычки вокруг JSONСтрокаПараметров нужны, чтобы строка с пробелами или специальными символами воспринималась как единый параметр.
  5. Наконец, вызываем метод ЗапуститьПриложение.

Прием параметров в целевой базе

В целевой базе нам потребуется код, который будет выполняться при запуске системы и читать переданные параметры. Обычно это делается в модуле приложения или в модуле обычного/управляемого приложения в обработчике ПриНачалеРаботыСистемы.


// В модуле приложения целевой базы (например, в обработчике ПриНачалеРаботыСистемы)
Процедура ПриНачалеРаботыСистемы(Отказ)

    Если Не ПустаяСтрока(ПараметрЗапуска) Тогда
        // ПараметрЗапуска содержит строку, переданную через /C

        // Попытаемся десериализовать JSON-строку обратно в объект
        Попытка
            ЧтениеJSON = Новый ЧтениеJSON();
            ЧтениеJSON.УстановитьСтроку(ПараметрЗапуска);
            ПереданныеПараметры = ПрочитатьJSON(ЧтениеJSON);
            ЧтениеJSON.Закрыть();

            Если ТипЗнч(ПереданныеПараметры) = Тип("Соответствие") Тогда
                // Теперь у нас есть соответствие с параметрами отбора
                ТипДокумента = ПереданныеПараметры.Получить("ТипДокумента");
                ВидОперации = ПереданныеПараметры.Получить("ВидОперации");

                // Программно открываем форму списка справочника "Инструкции"
                // и устанавливаем отбор
                ФормаСписка = ПолучитьФорму("Справочник.Инструкции.ФормаСписка");

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

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

                Иначе
                    // Для обычных форм работаем по-другому
                    // ... (реализация для обычных форм)
                КонецЕсли;

                ФормаСписка.Открыть();

            КонецЕсли;

        Исключение
            Сообщить("Ошибка при десериализации параметров запуска: " + ОписаниеОшибки());
        КонецПопытки;

    КонецЕсли;

КонецПроцедуры

В этом коде мы проверяем наличие ПараметрЗапуска, десериализуем его из JSON, а затем программно открываем форму списка справочника "Инструкции" и устанавливаем необходимый отбор на его динамический список. Важно учесть, что структура отбора будет зависеть от типа формы (управляемая или обычная).

Дополнительный параметр: /Execute

Ключ /Execute [имя файла внешней обработки] предназначен для запуска внешней обработки в режиме 1С:Предприятие сразу после старта системы. Это может быть полезно, если логика обработки параметров и открытия форм достаточно сложна, и вы не хотите засорять модуль приложения. Внешняя обработка может сама прочитать ПараметрЗапуска, выполнить все необходимые действия и даже закрыться после выполнения.


// Строка запуска с /Execute
СтрокаЗапуска = ПутьК1С + " ENTERPRISE /F " + ПутьКЦелевойБазе + " /N ПользовательИнструкций /P ПарольИнструкций /Execute ""C:\ПутьКОбработке\ОбработкаОтбора.epf"" /C """ + JSONСтрокаПараметров + """";
ЗапуститьПриложение(СтрокаЗапуска);

В этом случае, внешняя обработка ОбработкаОтбора.epf, которая будет запущена, сможет получить ПараметрЗапуска и выполнить все необходимые действия. Такой подход централизует логику обработки параметров в отдельном объекте.

Метод 2: Использование HTTP-сервисов и Web-сервисов

Более современный и гибкий подход к интеграции между базами 1С, особенно если мы хотим избежать открытия нового экземпляра 1С и потребления дополнительных лицензий, — это использование веб-сервисов или HTTP-сервисов. В этом случае целевая база выступает в роли сервера, предоставляющего данные, а текущая база — в роли клиента.

Принцип работы

  1. В базе с инструкциями (целевая база) мы публикуем HTTP-сервис или Web-сервис, который будет принимать параметры отбора.
  2. Сервис обрабатывает запрос, получает из базы нужные инструкции с учетом переданного отбора.
  3. Сервис возвращает результат в удобном формате (например, JSON, XML, или даже HTML-фрагмент).
  4. В текущей базе (источнике) мы отправляем запрос к этому сервису, получаем данные и отображаем их, например, в элементе формы ПолеHTMLДокумента, без необходимости запускать отдельную базу 1С.

Web-сервисы (SOAP)

Традиционные Web-сервисы (протокол SOAP) позволяют описывать методы, доступные для использования сторонними программами. Мы создаем Web-сервис в конфигурации базы с инструкциями, публикуем его на веб-сервере (Apache или IIS). В текущей базе мы используем объект WSОпределения и WebСервисПрокси для вызова методов этого сервиса.


// Пример вызова Web-сервиса в базе-источнике
Попытка
    Определение = Новый WSОпределения("http://localhost/instructions_base/ws/ИнструкцииСервис.1cws?wsdl"); // URL к WSDL сервиса
    Прокси = Новый WebСервисПрокси(Определение, "http://www.example.com/ИнструкцииСервис", "ИнструкцииСервис", "ИнструкцииСервисSoap");

    // Передаем параметры отбора как параметры метода Web-сервиса
    Результат = Прокси.ПолучитьИнструкции("ПоступлениеТоваровУслуг", "ЗакупкаУПоставщика");

    // Обрабатываем полученный Результат (например, строку JSON)
    // и отображаем в ПолеHTMLДокумента
    // ...

Исключение
    Сообщить("Ошибка при работе с Web-сервисом: " + ОписаниеОшибки());
КонецПопытки;

HTTP-сервисы (REST-подобные)

HTTP-сервисы, появившиеся с платформы 8.3.5, предлагают более простой и "легкий" подход, часто используемый для REST-подобных API. Они ориентированы на ресурсы и позволяют использовать стандартные HTTP-методы (GET, POST). Их проще разрабатывать и, как правило, они дают меньший объем передаваемых данных.


// Пример вызова HTTP-сервиса в базе-источнике
Попытка
    // Создаем HTTP-запрос
    Запрос = Новый HTTPЗапрос();
    Запрос.Метод = "GET";
    // Предполагаем, что сервис находится по адресу
    // /instructions_base/hs/instructions/byDocType?type=ПоступлениеТоваровУслуг&operation=ЗакупкаУПоставщика
    АдресРесурса = "/hs/instructions/byDocType?type=" + УРЛЕнкод("ПоступлениеТоваровУслуг") + "&operation=" + УРЛЕнкод("ЗакупкаУПоставщика");
    Запрос.УстановитьЗаголовки(Новый Соответствие());
    Запрос.Заголовки.Вставить("Content-Type", "application/json");

    // Создаем HTTP-соединение
    Соединение = Новый HTTPСоединение("localhost", , , , , , Истина, 10000); // Адрес веб-сервера, порт, таймаут

    // Отправляем запрос и получаем ответ
    Ответ = Соединение.Отправить(Запрос, АдресРесурса);

    Если Ответ.КодСостояния = 200 Тогда
        // Успешный ответ
        Результат = Ответ.ПолучитьТелоКакСтроку();
        // Десериализуем JSON-строку и отображаем данные
        // ...
    Иначе
        Сообщить("Ошибка запроса к HTTP-сервису. Код состояния: " + Ответ.КодСостояния);
    КонецЕсли;

Исключение
    Сообщить("Ошибка при работе с HTTP-сервисом: " + ОписаниеОшибки());
КонецПопытки;

HTTP-сервисы, в отличие от запуска отдельной базы, позволяют более гибко управлять отображением данных. Вы можете получить от сервиса HTML-разметку, которую напрямую отобразите в ПолеHTMLДокумента, или JSON-данные, которые можно обработать и представить в своей форме в любом удобном виде.

Метод 3: Бесшовная интеграция

Термин "бесшовная интеграция" в 1С обычно относится к связке 1С:Документооборот с другими типовыми конфигурациями. Она позволяет пользователю работать с документами из Документооборота, не выходя из основного интерфейса. Если база инструкций может быть адаптирована под принципы бесшовной интеграции (или если у вас уже есть Документооборот), это может быть очень мощным решением. Однако это достаточно трудоемкий процесс, требующий глубокой проработки архитектуры.

Метод 4: Временный файл для обмена данными

Этот метод является своего рода "костылем", но может быть рабочим в условиях жестких ограничений или при нежелании использовать сложные интеграционные механизмы. Идея заключается в следующем:

  1. В текущей базе, по кнопке, мы записываем параметры отбора во временный файл (например, JSON-файл) в известном месте (например, в папке временных файлов пользователя или на сетевом диске).
  2. Запускаем целевую базу через ЗапуститьПриложение, не передавая никаких специфических параметров командной строки, кроме стандартных (путь, пользователь и т.д.).
  3. В целевой базе при старте (в ПриНачалеРаботыСистемы) мы проверяем наличие этого временного файла, читаем из него параметры отбора, применяем их и сразу удаляем файл, чтобы он не мешал при последующих запусках.

// В базе-источнике
ПутьКВременномуФайлу = КаталогВременныхФайлов() + "InstructionFilter.json";
ПередаваемыеПараметры = Новый Соответствие();
ПередаваемыеПараметры.Вставить("ТипДокумента", "ПоступлениеТоваровУслуг");
// ...

ЗаписатьJSON(ПередаваемыеПараметры, ПутьКВременномуФайлу);

СтрокаЗапуска = ПутьК1С + " ENTERPRISE /F " + ПутьКЦелевойБазе + " /N ПользовательИнструкций /P ПарольИнструкций";
ЗапуститьПриложение(СтрокаЗапуска);

// В целевой базе (в ПриНачалеРаботыСистемы)
ПутьКВременномуФайлу = КаталогВременныхФайлов() + "InstructionFilter.json";
Если ФайлСуществует(ПутьКВременномуФайлу) Тогда
    Попытка
        ЧтениеJSON = Новый ЧтениеJSON();
        ЧтениеJSON.УстановитьФайл(ПутьКВременномуФайлу);
        ПереданныеПараметры = ПрочитатьJSON(ЧтениеJSON);
        ЧтениеJSON.Закрыть();

        // Применяем отбор, как в Методе 1

        УдалитьФайлы(ПутьКВременномуФайлу); // Обязательно удаляем файл!
    Исключение
        Сообщить("Ошибка чтения/удаления временного файла: " + ОписаниеОшибки());
    КонецПопытки;
КонецЕсли;

Этот метод прост в реализации, но имеет недостатки: зависимость от файловой системы, потенциальные проблемы с правами доступа, возможность "зависания" файла (если целевая база не смогла его удалить) и, конечно, конкурентный доступ (если несколько пользователей одновременно пытаются использовать этот механизм с одним и тем же файлом).

Метод 5: Альтернативные подходы к организации инструкций (без открытия отдельной базы)

Возможно, сам подход с открытием отдельной базы для инструкций является неоптимальным. Давайте рассмотрим, как мы можем достичь той же цели более простыми и интегрированными способами, избегая сложностей межбазового взаимодействия.

Внешние обработки и отчеты (ВнО/ВПФ)

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

  1. Справочник "Шаблоны инструкций": В нем будут храниться сами инструкции (в виде текста, HTML-разметки или прикрепленных файлов) и метаданные (например, тип документа, к которому относится инструкция, раздел, ключевые слова).
  2. Единая внешняя печатная форма или обработка "Просмотрщик инструкций":
    • Эта ВПФ/ВнО будет прикреплена к типовым объектам конфигурации (документам, справочникам).
    • При ее вызове из конкретного документа (например, "Поступление товаров и услуг"), она сможет автоматически определить тип документа, получить связанные инструкции из справочника "Шаблоны инструкций" и отобразить список, отфильтрованный по типу текущего документа.
    • Внутри самой ВПФ/ВнО можно реализовать удобный интерфейс для поиска и просмотра инструкций.

Преимущества: инструкции всегда находятся "под рукой", не потребляются дополнительные лицензии, нет необходимости в сложной интеграции баз. Обновление инструкций может происходить через централизованное обновление внешних обработок или через механизм обмена данными со справочником "Шаблоны инструкций" из некой мастер-базы.

Пример реализации в ВнО:


// Внешняя обработка или печатная форма
// В модуле объекта
Функция СведенияОВнешнейОбработке() Экспорт
    // ... описание обработки ...
КонецФункции

// В форме обработки
Перем ОбъектОснование; // Ссылка на текущий документ

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

Использование ПолеHTMLДокумента

Если инструкции можно представить в HTML-формате, мы можем хранить их как строки в базе и отображать в элементе формы ПолеHTMLДокумента. Это может быть как HTML-код, сгенерированный программно, так и ссылки на веб-страницы, где размещены инструкции.


// В форме документа или обработки
Элементы.ПолеИнструкции.УстановитьТекстHTML("<p>Привет! Вот <b>важная</b> инструкция.</p>");
// Или
Элементы.ПолеИнструкции.УстановитьТекстHTML("<html><body><h3>Заголовок инструкции</h3><p>Текст инструкции...</p></body></html>");
// Или даже
// Элементы.ПолеИнструкции.УстановитьURL("http://инструкции.моякомпания.ru/ПТУ_Закупка.html");

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

Хранение сведений в текущей базе

Мы можем хранить инструкции непосредственно в текущей базе, создав для них новый справочник или регистр сведений. Это позволяет полностью интегрировать информацию и управлять ею средствами одной базы. Недостаток — увеличение объема базы и необходимость синхронизации инструкций, если они должны быть одинаковыми в 150 базах.

Расширения конфигурации

Если ваша платформа 1С поддерживает расширения конфигурации (начиная с 8.3.6), это отличный способ добавлять функционал без изменения основной конфигурации. Мы можем создать расширение, которое будет содержать справочник "Инструкции" и форму для их просмотра. Затем это расширение можно подключить ко всем 150 базам. Это значительно упрощает централизованное управление инструкциями и их обновление.

Важные соображения и ограничения

  1. Лицензирование: Помните, что каждое запущенное через ЗапуститьПриложение отдельное окно 1С предприятия потребляет лицензию. Если у вас мало лицензий, этот подход может быть дорогим. Веб-сервисы или хранение инструкций в текущей базе не потребляют дополнительных лицензий 1С.
  2. Безопасность: Особенно в "гос. отрасли", вопросы безопасности критически важны. Публикация веб-сервисов требует настройки веб-сервера (Apache/IIS) и тщательного контроля прав доступа. Использование внешних файлов для обмена также может быть уязвимо.
  3. Инфраструктура: Состояние технической инфраструктуры (старые компьютеры, медленные сети, "платформа Z") может накладывать существенные ограничения на выбор решений. Запуск второй базы может быть медленным и ресурсоемким. Веб-сервисы требуют настроенного веб-сервера.
  4. Сложность решения: Стремление к "бесшовному" или слишком сложному решению может привести к увеличению ошибок, трудностям в поддержке и дороговизне разработки. Часто более простые и прямые подходы оказываются надежнее.
  5. Поддержка: При 150 базах в отрасли любое изменение в механизме инструкций потребует его распространения на все базы. Централизованные решения (веб-сервис, расширения, внешние обработки) гораздо проще в поддержке, чем доработка кода в каждой из 150 баз.

Таким образом, хотя прямое открытие базы с передачей параметров через командную строку реализуемо, мы настоятельно рекомендуем рассмотреть альтернативные подходы, такие как использование веб/HTTP-сервисов или интеграцию инструкций непосредственно в текущую базу с помощью ВнО/ВПФ или расширений. Эти методы часто оказываются более эффективными, экономичными с точки зрения лицензий и проще в поддержке в долгосрочной перспективе.

← На главную