Коллеги, сегодня мы разберем сложную, но часто встречающуюся задачу: как из одной информационной базы 1С открыть другую, передать в нее определенные параметры и на их основе отобразить отфильтрованный список документов или справочников. Мы рассмотрим различные методы реализации, от классических до более современных, и проанализируем их применимость в разных условиях.
Исходная ситуация заключается в следующем: необходимо из формы документа, например, "Поступление товаров и услуг" (ПТУ), по нажатию кнопки, запустить другую базу 1С, предназначенную для хранения инструкций. При этом важно, чтобы в открывшейся базе уже был применен определенный отбор, который мы передаем из текущей базы. Целевая база запускается методом ЗапуститьПриложение. Нам нужно понять, как "на той стороне" принять этот отбор и корректно его применить.
Прежде чем приступать к реализации, важно учитывать несколько факторов: возможности платформы (особенно если речь идет о старых версиях или специфических конфигурациях, как в упомянутой "гос. отрасли" или на "платформе Z"), вопросы лицензирования (каждое открытие новой базы может потреблять дополнительную лицензию), а также общую сложность поддержки создаваемого решения.
Один из наиболее прямолинейных и универсальных способов — использование параметров командной строки при запуске 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СтрокаПараметров + """";
// Запускаем приложение
ЗапуститьПриложение(СтрокаЗапуска);
В этом примере:
Соответствие для хранения наших параметров.ЗаписатьJSON для сериализации этого объекта в строку. Это удобно для передачи сложных данных.ENTERPRISE для запуска в режиме предприятия, ключ /F для указания пути к файловой базе (или /S для клиент-серверной), а также /N и /P для автоматической авторизации пользователя./C, в кавычках передавая нашу JSON-строку. Двойные кавычки вокруг JSONСтрокаПараметров нужны, чтобы строка с пробелами или специальными символами воспринималась как единый параметр.ЗапуститьПриложение.В целевой базе нам потребуется код, который будет выполняться при запуске системы и читать переданные параметры. Обычно это делается в модуле приложения или в модуле обычного/управляемого приложения в обработчике ПриНачалеРаботыСистемы.
// В модуле приложения целевой базы (например, в обработчике ПриНачалеРаботыСистемы)
Процедура ПриНачалеРаботыСистемы(Отказ)
Если Не ПустаяСтрока(ПараметрЗапуска) Тогда
// ПараметрЗапуска содержит строку, переданную через /C
// Попытаемся десериализовать JSON-строку обратно в объект
Попытка
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(ПараметрЗапуска);
ПереданныеПараметры = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Если ТипЗнч(ПереданныеПараметры) = Тип("Соответствие") Тогда
// Теперь у нас есть соответствие с параметрами отбора
ТипДокумента = ПереданныеПараметры.Получить("ТипДокумента");
ВидОперации = ПереданныеПараметры.Получить("ВидОперации");
// Программно открываем форму списка справочника "Инструкции"
// и устанавливаем отбор
ФормаСписка = ПолучитьФорму("Справочник.Инструкции.ФормаСписка");
// Если форма на управляемых формах, работаем с динамическим списком
Если ТипЗнч(ФормаСписка.Элементы.Список.Отбор) = Тип("ОтборДинамическогоСписка") Тогда
ЭлементОтбораТип = ФормаСписка.Элементы.Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбораТип.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ТипИнструкции"); // Предположим, есть реквизит "ТипИнструкции"
ЭлементОтбораТип.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбораТип.ПравоеЗначение = ТипДокумента;
ЭлементОтбораТип.Использование = Истина;
ЭлементОтбораОперация = ФормаСписка.Элементы.Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбораОперация.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ВидОперации"); // Предположим, есть реквизит "ВидОперации"
ЭлементОтбораОперация.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбораОперация.ПравоеЗначение = ВидОперации;
ЭлементОтбораОперация.Использование = Истина;
Иначе
// Для обычных форм работаем по-другому
// ... (реализация для обычных форм)
КонецЕсли;
ФормаСписка.Открыть();
КонецЕсли;
Исключение
Сообщить("Ошибка при десериализации параметров запуска: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецПроцедуры
В этом коде мы проверяем наличие ПараметрЗапуска, десериализуем его из JSON, а затем программно открываем форму списка справочника "Инструкции" и устанавливаем необходимый отбор на его динамический список. Важно учесть, что структура отбора будет зависеть от типа формы (управляемая или обычная).
Ключ /Execute [имя файла внешней обработки] предназначен для запуска внешней обработки в режиме 1С:Предприятие сразу после старта системы. Это может быть полезно, если логика обработки параметров и открытия форм достаточно сложна, и вы не хотите засорять модуль приложения. Внешняя обработка может сама прочитать ПараметрЗапуска, выполнить все необходимые действия и даже закрыться после выполнения.
// Строка запуска с /Execute
СтрокаЗапуска = ПутьК1С + " ENTERPRISE /F " + ПутьКЦелевойБазе + " /N ПользовательИнструкций /P ПарольИнструкций /Execute ""C:\ПутьКОбработке\ОбработкаОтбора.epf"" /C """ + JSONСтрокаПараметров + """";
ЗапуститьПриложение(СтрокаЗапуска);
В этом случае, внешняя обработка ОбработкаОтбора.epf, которая будет запущена, сможет получить ПараметрЗапуска и выполнить все необходимые действия. Такой подход централизует логику обработки параметров в отдельном объекте.
Более современный и гибкий подход к интеграции между базами 1С, особенно если мы хотим избежать открытия нового экземпляра 1С и потребления дополнительных лицензий, — это использование веб-сервисов или HTTP-сервисов. В этом случае целевая база выступает в роли сервера, предоставляющего данные, а текущая база — в роли клиента.
ПолеHTMLДокумента, без необходимости запускать отдельную базу 1С.Традиционные 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-сервисы, появившиеся с платформы 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-данные, которые можно обработать и представить в своей форме в любом удобном виде.
Термин "бесшовная интеграция" в 1С обычно относится к связке 1С:Документооборот с другими типовыми конфигурациями. Она позволяет пользователю работать с документами из Документооборота, не выходя из основного интерфейса. Если база инструкций может быть адаптирована под принципы бесшовной интеграции (или если у вас уже есть Документооборот), это может быть очень мощным решением. Однако это достаточно трудоемкий процесс, требующий глубокой проработки архитектуры.
Этот метод является своего рода "костылем", но может быть рабочим в условиях жестких ограничений или при нежелании использовать сложные интеграционные механизмы. Идея заключается в следующем:
ЗапуститьПриложение, не передавая никаких специфических параметров командной строки, кроме стандартных (путь, пользователь и т.д.).ПриНачалеРаботыСистемы) мы проверяем наличие этого временного файла, читаем из него параметры отбора, применяем их и сразу удаляем файл, чтобы он не мешал при последующих запусках.
// В базе-источнике
ПутьКВременномуФайлу = КаталогВременныхФайлов() + "InstructionFilter.json";
ПередаваемыеПараметры = Новый Соответствие();
ПередаваемыеПараметры.Вставить("ТипДокумента", "ПоступлениеТоваровУслуг");
// ...
ЗаписатьJSON(ПередаваемыеПараметры, ПутьКВременномуФайлу);
СтрокаЗапуска = ПутьК1С + " ENTERPRISE /F " + ПутьКЦелевойБазе + " /N ПользовательИнструкций /P ПарольИнструкций";
ЗапуститьПриложение(СтрокаЗапуска);
// В целевой базе (в ПриНачалеРаботыСистемы)
ПутьКВременномуФайлу = КаталогВременныхФайлов() + "InstructionFilter.json";
Если ФайлСуществует(ПутьКВременномуФайлу) Тогда
Попытка
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьФайл(ПутьКВременномуФайлу);
ПереданныеПараметры = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
// Применяем отбор, как в Методе 1
УдалитьФайлы(ПутьКВременномуФайлу); // Обязательно удаляем файл!
Исключение
Сообщить("Ошибка чтения/удаления временного файла: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Этот метод прост в реализации, но имеет недостатки: зависимость от файловой системы, потенциальные проблемы с правами доступа, возможность "зависания" файла (если целевая база не смогла его удалить) и, конечно, конкурентный доступ (если несколько пользователей одновременно пытаются использовать этот механизм с одним и тем же файлом).
Возможно, сам подход с открытием отдельной базы для инструкций является неоптимальным. Давайте рассмотрим, как мы можем достичь той же цели более простыми и интегрированными способами, избегая сложностей межбазового взаимодействия.
Мы можем хранить инструкции непосредственно в текущей базе или предоставлять к ним доступ через внешние обработки или печатные формы. Для этого можно создать:
Преимущества: инструкции всегда находятся "под рукой", не потребляются дополнительные лицензии, нет необходимости в сложной интеграции баз. Обновление инструкций может происходить через централизованное обновление внешних обработок или через механизм обмена данными со справочником "Шаблоны инструкций" из некой мастер-базы.
Пример реализации в ВнО:
// Внешняя обработка или печатная форма
// В модуле объекта
Функция СведенияОВнешнейОбработке() Экспорт
// ... описание обработки ...
КонецФункции
// В форме обработки
Перем ОбъектОснование; // Ссылка на текущий документ
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("ОбъектОснование") Тогда
ОбъектОснование = Параметры.ОбъектОснование; // Получаем ссылку на документ, из которого вызвали
Если ОбъектОснование <> Неопределено Тогда
ТипДокументаОснования = ТипЗнч(ОбъектОснование);
// Далее, на основе ТипДокументаОснования,
// мы можем получить и отобразить нужные инструкции
// Например, заполнить динамический список формы
// СпискомИнструкций.Отбор.Элементы.Добавить(...)
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Если инструкции можно представить в 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С.Таким образом, хотя прямое открытие базы с передачей параметров через командную строку реализуемо, мы настоятельно рекомендуем рассмотреть альтернативные подходы, такие как использование веб/HTTP-сервисов или интеграцию инструкций непосредственно в текущую базу с помощью ВнО/ВПФ или расширений. Эти методы часто оказываются более эффективными, экономичными с точки зрения лицензий и проще в поддержке в долгосрочной перспективе.