Внешние функции обработки СБИС для 1С 8.х — различия между версиями

Материал из razgovorov.ru
Перейти к: навигация, поиск
(Расположение файла ВнешниеФункции_Клиент.epf)
(Внешние функции в файлах настроек)
Строка 81: Строка 81:
 
КонецФункции
 
КонецФункции
 
</source>
 
</source>
 +
 +
В примере 2 необходимо пояснить, что типом значения Контекст.Документ в функции сбисДанныеОрганизацииНаДатуДокумента является тип "Структура". Это объект, который мы собираем через ини для последующего заполнения в базу 1С. Тем не менее, обращение к значениям платформенных объектов 1С (массивы, списки значений, структуры) возможно на клиенте без ограничений. Тогда как обращение к реквизитам объектов базы данных (справочники, документы, регистры) на клиенте не возможно. Так если бы в Контекст.Документ находилась ссылка на документ РеализацияТоваровУслуг, у которого есть реквизит Организация, то обращение к этому свойству на клиенте вызвало бы ошибку.
  
 
==Внешние функции, вызываемые из обработки==
 
==Внешние функции, вызываемые из обработки==

Версия 10:32, 21 октября 2019

Так как код самой обработки Sbis1C.epf ни при каких условиях менять нельзя, для внесения изменений под клиента предусмотрена дополнительная внешняя обработка ВнешниеФункции_Клиент.epf. Данная обработка отсутствует в стандартной поставке и создается самостоятельно с помощью конфигуратора 1С. Внешние функции пишутся при необходимости изменить выгрузку или загрузку документов, если изменения требуют определенных вычислений и нельзя обойтись простой правкой файла настроек, а также для изменения механизма работы со статусами документов и сопоставления номенклатуры.

Расположение файла ВнешниеФункции_Клиент.epf

Файл "ВнешниеФункции_Клиент.epf" может распологаться:

  1. В каталоге настроек обработки
  2. В 1С в справочниках "Дополнительные отчеты и обработки" или "Внешние обработки" (в зависимости от конфигурации)

При этом в случае п. 2 для обычных форм достаточно просто поместить обработку в нужный справочник. Для управляемых же форм необходимо:

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

Запись справочника "Внешние Обработки".png

Внешние функции для выгрузки документов

Внешние функции в файлах настроек

Параметры в файлах настроек могут определяться через функцию. Все функции, вызываемые из стандартных файлов настроек, описаны в форме РаботаСДокументами1С обработки Sbis1C.epf. Эти функции можно переопределить в обработке ВнешниеФункции_Клиент.epf, а также для любого параметра файла настроек написать свою функцию.

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

Чтобы определить параметр через внешнюю функцию:

  • Создаем внешнюю обработку ВнешниеФункции_Клиент.epf в конфигураторе 1С (меню Файл/Новый/Внешняя обработка). Имя обработки так же указываем ВнешниеФункции_Клиент:
ОбработкаВнешниеФункции.png
Сохраняем файл в каталог настроек.
  • В обработке создаем форму "РаботаСДокументами1С" (название можно скопировать из основной обработки)
  • В модуле формы пишем экспортную функцию с одним параметром (для единообразия называем параметр "Контекст")
Параметр Контекст представляет из себя структуру, поля которой соответствуют параметрам блока мФайл в файле настроек (по которому выгружается документ), а в значениях полей - уже рассчитанные значения параметров, которые определены не через функции, то есть примерно такая структура:
СтруктураКонтекстВыгрузка.png

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

Важно! Для управляемых форм! Для ускорения процесса выгрузки необходимо минимизировать количество обращений к серверу 1С. Получение любого реквизита документа, организации, контрагента и т.д. - это обращение к серверу. Поэтому по возможности все реквизиты, которые необходимы для вычислений во внешней функции, определяем в файле настроек, чтобы все они были рассчитаны за одно обращение к серверу. В случае, если всё же нет невозможности описать обращение через инишку (лучше ещё сесть и пару раз подумать, вдруг можно), необходимо минимизировать объем данных, передаваемых на сервер. Для этого стоит сделать свою переменную, например КонтекстСервера, в которую необходимо поместить те данные, которые будут использоваться в серверной функции. Например, для получения неких данных по организации на дату документа, нет необходимости передавать весь документ. Можно взять только ссылку на организацию и дату и поместить их в контекст. Саму функцию на сервере необходимо объявлять без контекста формы, с директивой компиляции &НаСервереБезКонтекста. Директива компиляции &НаСервере используется в том случае, когда есть необходимость обратиться к данным реквизитов текущей формы (обычно это табличная часть), в большинстве остальных случаев, контекст формы на сервере вам не потребуется. Важно понимать, что в случае если директива компиляции у функции не указана, то по-умолчанию, на управляемых формах (в модуле форм) используется директива &НаСервере. На формах обычного приложения директива по-умолчанию &НаКлиенте. Так же минимизировать время обработки серверного вызова поможет, если переменную на сервер вы будете передавать по значению (ключевое слово Знач при объявлении переменной в функции). В таком случае, важно понимать принцип формирования переменных на сервере: при вызове с клиента, по-умолчанию, переменная передаётся по ссылке, т.е. целиком копируется на сервер, а после завершения серверной функции возвращается на клиент, заменяя старое значение. Так, как возвращаемая переменная является глубокой копией, то из-за этого поменяется ссылочность внутри переменной. Например, вы взяли вложение из пакета и поместили его в реквизит формы, а после передали пакет на сервер. В таком случае, по завершении серверного вызова, вложение в пакете будет уже другой переменной (пусть и с теми же данными) и при её изменении, переменная в реквизите не поменяется. Ключевое слово Знач говорит платформе о том, что переменная НЕ возвращается на клиент, в таком случае ссылочность не нарушается, исключается операция лишнего переноса данных с сервера, однако все изменения в переменной, которые были сделаны на сервере так же пропадут.

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

<СторонаНаименованиеПолное>[Сторона].НаименованиеПолное</СторонаНаименованиеПолное>
<СторонаНаименованиеСокращенное>[Сторона].НаименованиеСокращенное </СторонаНаименованиеСокращенное>
<Сторона_Наименование>{сбисНаименованиеОрганизации()}</Сторона_Наименование>

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

&НаКлиенте
Функция сбисНаименованиеОрганизации(Контекст) Экспорт
	Если ЗначениеЗаполнено(Контекст.СторонаНаименованиеПолное) Тогда
		Возврат Контекст.СторонаНаименованиеПолное;
	Иначе
		Возврат Контекст.СторонаНаименованиеСокращенное;
	КонецЕсли;
КонецФункции

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

&НаКлиенте
Функция сбисДанныеОрганизацииНаДатуДокумента(Контекст) Экспорт
	КонтекстСервера = Новый Структура("Организация, ДатаДокумента", Контекст.Документ.Организация, Контекст.Документ.Дата);
	Возврат сбисДанныеОрганизацииНаДатуДокумента_Сервер(КонтекстСервера);
КонецФункции

&НаСервереБезКонтекста
Функция сбисДанныеОрганизацииНаДатуДокумента_Сервер(Знач КонтекстСервера)
	Запрос = Новый Запрос('ВЫБРАТЬ
	...
	')
	Запрос.УстановитьПараметр("Организация", КонтекстСервера.Организация);
	Запрос.УстановитьПараметр("ДатаДокумента", КонтекстСервера.ДатаДокумента);
	Результат = Запрос.Выполнить().Выбрать();
	Если Результат.Следующий() Тогда
		Возврат СамописныйМодульКонфигурации.ДополнительнаяОбработкаПолученногоЗначения(Результат.ТребуемоеЗначение)
	КонецЕсли;
	Возврат Неопределено;	
КонецФункции

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

Внешние функции, вызываемые из обработки

В стандартном механизме формирования электронного документа есть два места для "встраивания", то есть для внесения изменений в выгружаемый документ:

1. Функция сбисПослеФормированияСтроки(НоваяСтрока, Кэш, Контекст, Стр) - предназначена для внесения изменений в строки табличной части, а также определяет, нужно ли добавлять данную строку в документ.

Возвращает Истину - в этом случае строка добавляется в документ, или Ложь - в этом случае строка не добавляется в документ (см. пример)
Вызывается после формирования структуры строки стандартным механизмом в форме Файл_Шаблон. Сама функция пишется в обработке ВнешниеФункции_Клиент в форме «Файл_[Формат файла]_[Версия формата файла]». Например, при формировании накладной создается форма "Файл_ЭДОНакл_3_01". Если нужно написать данную функцию для нескольких типов документов, то для каждого создается своя форма. Нельзя выносить во внешние функции форму "Файл_Шаблон"!

Параметры Функции:

  • НоваяСтрока - структура строки, которая будет добавлена в выгружаемый документ. То есть именно в нее при необходимости нужно вносить изменения.
  • Кэш - общий кэш обработки (структура)
  • Контекст - структура с данными по текущей выгрузке документов
  • Стр - структура строки, заполненная по файлу настроек

2. Функция сбисПослеФормированияДокумента(Док, Кэш, Контекст) - предназначена для внесения изменений в сформированный документ. Также используется при необходимости добавить к пакету печатную форму документа в формате pdf.

Вызывается после формирования структуры документа стандартным механизмом в форме Файл_Шаблон. Сама функция пишется в обработке ВнешниеФункции_Клиент в форме «Файл_[Формат файла]_[Версия формата файла]».

Параметры Функции:

  • Док - структура выгружаемого документа. В нее при необходимости нужно вносить изменения.
  • Кэш - общий кэш обработки (структура)
  • Контекст - структура с данными по текущей выгрузке документов

Пример кода в функции сбисПослеФормированияДокумента для добавления в пакет внешней печатной формы документа:

	Запрос = Новый Запрос;
	Запрос.Текст = 
 	   "ВЫБРАТЬ
 	   |    Справочник.ВнешниеОбработки.Ссылка КАК Объект
  	   |ИЗ
 	   |   Справочник.ВнешниеОбработки
	   |ГДЕ
           |   (Справочник.ВнешниеОбработки.Наименование = &НаимФормы)";
 
	Запрос.УстановитьПараметр("НаимФормы", "АктВодоканал");
	Выборка = Запрос.Выполнить().Выбрать();
	Если Выборка.Количество() = 0 Тогда
		Возврат Ложь;
	КонецЕсли;
	Пока Выборка.Следующий() Цикл
		Обработка = Выборка.Объект;
		Прервать();
	КонецЦикла;

	Обработка = Обработка.ХранилищеВнешнейОбработки.Получить();
        ВремКаталог = КаталогВременныхФайлов();
	Путь = ВремКаталог+"АктВодоканал.epf"; 
	Обработка.Записать(Путь);
	Обработка = ВнешниеОбработки.Создать(Путь);	
  	Обработка.СсылкаНаОбъект = Контекст.Документ;		
	ТабДокумент = Обработка.Печать();				
	ИмяФайла = "АктВодоканал.pdf";
	ПолноеИмяФайла = ВремКаталог+ИмяФайла;
	ТабДокумент.Записать(ПолноеИмяФайла,ТипФайлаТабличногоДокумента.pdf);
	Контекст.СоставПакета.Вложение.Добавить(Новый Структура("ПолноеИмяФайла,ИмяФайла,Название", ПолноеИмяФайла,ИмяФайла,ИмяФайла));

Переопределяемые функции выгрузки документов

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

  • В обработке ВнешниеФункции_Клиент создаем форму «Файл_[Формат файла]_[Версия формата файла]»
  • Переносим в нее функции ПолучитьДанныеИзДокумента1С(Кэш,Контекст) и ПолучитьТабличнуюЧастьДокумента1С(Кэш,Контекст) из формы Файл_Шаблон и пишем в этих функциях свой код формирования структуры документа.

Параметры Функций:

  • Кэш - общий кэш обработки (структура)
  • Контекст - структура с данными по текущей выгрузке документов

Не забываем в конце добавить свое вложение в состав пакета:

Контекст.СоставПакета.Вложение.Добавить(Вложение);

Так же есть возможность полностью переопределить отправку документов из определенного реестра. Для этого:

  • В обработке ВнешниеФункции_Клиент создаем форму «Документ_[тип документа 1С]»
  • Переносим в нее функцию ОтправитьДокументы(Кэш,МассивСтрок) из формы Документ_Шаблон и пишем свой код.

Параметры Функции:

  • Кэш - общий кэш обработки (структура)
  • МассивСтрок - список отмеченных строк таблицы документов, которые необходимо отправить

Внешние функции для загрузки документов

Внешние функции в файлах настроек

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

Чтобы заполнить реквизит документа 1С через клиентскую функцию:

  • Создаем внешнюю обработку ВнешниеФункции_Клиент.epf в конфигураторе 1С
  • В обработке создаем форму "РаботаСДокументами1С"
  • В модуле формы пишем экспортную функцию с одним параметром (для единообразия называем параметр "Контекст")
Контекст - структура с полями:
  • Ини - структура файла настроек, по которому идет загрузка
  • Документ - структура документа 1С, который будет загружен
  • СтрТабл - структура текущей строки табличной части создаваемого документа
  • СтруктураФайла - структура файла, на основании которого создается документ
  • СтрокаФайла - текущая строка файла, на основании которой заполняется текущая строка документа
  • СоставПакета - структура, содержащая полный состав загружаемого пакета

Внешние функции, вызываемые из обработки

После того, как документ 1С создан стандартным механизмом, есть возможность внести в него изменения. Для этого предназначена функция ДопРасчетыПриЗагрузке(Документ1С, Контекст), вызываемая из формы Документ_Шаблон.

Функция пишется в обработке ВнешниеФункции_Клиент в форме «Документ_[Тип документа 1С]». Например, при загрузке документа ПоступлениеТоваровУслуг создается форма "Документ_ПоступлениеТоваровУслуг". Если нужно написать данную функцию для нескольких типов документов, то для каждого создается своя форма. Нельзя выносить во внешние функции форму "Документ_Шаблон"!

Параметры Функции:

  • Документ1С - Загруженный документ 1С
  • Контекст - структура с полями СтруктураФайла - структура загружаемого файла, СоставПакета - структура загружаемого пакета документов

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

Переопределяемые функции загрузки документов

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

  • В обработке ВнешниеФункции_Клиент создаем форму «Документ_[Тип документа 1С]»
  • Переносим в нее функцию СоздатьДокумент из формы Документ_Шаблон и пишем свой код загрузки документа.

Внешние функции для работы со статусами

В обработке присутствуют две стандартные формы работы со статусами документов: Статусы_Регистры и Статусы_ДБФ. В процессе работы используется одна из них, указанная в файле настроек конфигурации. При необходимости изменения механизма работы со статусами выносим используемую форму во ВнешниеФункции_Клиент.epf и выносим функции данной формы, которые необходимо переопределить.

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

Внешние функции для сопоставления номенклатуры

В обработке присутствуют несколько стандартных форм работы с сопоставлением номенклатуры (название формы начинается с "СопоставлениеНоменклатуры_"). В процессе работы используется одна из них, указанная в файле настроек конфигурации. При необходимости изменения механизма работы с сопоставлением номенклатуры выносим используемую форму во ВнешниеФункции_Клиент.epf и выносим функции данной формы, которые необходимо переопределить.

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