---
title: 2. Настраиваемые алгоритмы загрузки в справочники
slug: общие-бсп-стандартные-подсистемы-3-1-10-загрузка-данных-из-файла/2-настраиваемые-алгоритмы-загрузки-в-справочники
---

Т.к. справочники, имеющие реквизиты типа `ХранилищеЗначения` не отображаются в обработке `Загрузка данных из файла` по умолчанию, их при необходимости можно подключить самостоятельно. Также можно отключить какой-нибудь справочник и сделать его недоступным для использования в обработке.

В общем модуле `ЗагрузкаДанныхИзФайлаПереопределяемый` в процедуре `ПриОпределенииСправочниковДляЗагрузкиДанных` определяем состав справочников для загрузки данных

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

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

## Реализация собственных механизмов загрузки и сопоставления

Если в процедуре `ЗагрузкаДанныхИзФайлаПереопределяемый.ПриОпределенииСправочниковДляЗагрузкиДанных` для справочника указать `Сведения.ПрикладнаяЗагрузка = Истина;`, то необходимо:
- Создать макет табличного документа для загруки
- в модуле менеджера реализовать несколько методов служебного программного интерфейса

## Создание макета
Макет создается на уровне объекта и должен **обязательно иметь имя `ЗагрузкаИзФайла`**. В нем настраиваем вид шапки таблицы **именя ячеек которой должны соответствовать именам реквизитов объекта**. 
> В пользовательском режиме полужирным будут выделены обязательные реквизиты (`ПроверкаЗаполнения = ВыдаватьОшибку`) и те реквизиты, которые будут добавлены в массив `Параметры.ОбязательныеКолонки` метода `ОпределитьПараметрыЗагрузкиДанныхИзФайла` (см. [главу ОпределитьПараметрыЗагрузкиДанныхИзФайла](#ОпределитьПараметрыЗагрузкиДанныхИзФайла))

![Изображение](/bsp-zagruzka-iz-faila/5.png)

Если справочник подключен к подсистемам `Свойства` и/или `Контактная информация`, то в макете нужно создавать колонки с заголовком `<Дополнительные реквизиты>` и `<Контактная информация>` (именно с треугольными скобками). Для таких колонок `Имя` не имеет значения - они заполняются автоматически

![Изображение](/bsp-zagruzka-iz-faila/6.png)
![Изображение](/bsp-zagruzka-iz-faila/7.png)

## Реализация методов программного интерфейса
В модуле менеджера необходимо реализовать 3 экспортных процедуры:
- `Процедура ОпределитьПараметрыЗагрузкиДанныхИзФайла(Параметры) Экспорт`, в котором нужно определить параметры создания таблицы `ЗагружаемыеДанные`, используемой далее

<details style="margin: 1em 0; padding: 0.5em; border: 1px solid #ccc; border-radius: 6px;">
<summary style="font-weight: bold; cursor: pointer;">Подробнее</summary>

![Изображение](/bsp-zagruzka-iz-faila/14.png)

</details>

- `Процедура СопоставитьЗагружаемыеДанныеИзФайла(ЗагружаемыеДанные) Экспорт`, в котором нужно заполнить служебный реквизиты `ОбъектСопоставления` - ссылка на найденный по требуемым правилам элемент справочника.
- `Процедура ЗагрузитьИзФайла(ЗагружаемыеДанные, ПараметрыЗагрузки, Отказ) Экспорт`, в котором осуществляется непосредственная загрузка данных в ИБ

### ОпределитьПараметрыЗагрузкиДанныхИзФайла
В этом методе нужно настроить параметры перед загрузкой данных. 
Одним из ключевых параметров - `ТипДанныхКолонки`, который определяет, в какие типы система будет пытаться преобразовать введенное значение в колонках таб.док при формировании таблицы значений `ЗагружаемыеДанные`, используемой далее в методе `СопоставитьЗагружаемыеДанныеИзФайла`
<details style="margin: 1em 0; padding: 0.5em; border: 1px solid #ccc; border-radius: 6px;">
<summary style="font-weight: bold; cursor: pointer;">Подробнее</summary>

![Изображение](/bsp-zagruzka-iz-faila/8.png)
![Изображение](/bsp-zagruzka-iz-faila/9.png)
![Изображение](/bsp-zagruzka-iz-faila/10.png)
![Изображение](/bsp-zagruzka-iz-faila/11.png)

Пример с датой
![Изображение](/bsp-zagruzka-iz-faila/12.png)
![Изображение](/bsp-zagruzka-iz-faila/13.png)

</details>

```bsl
Процедура ОпределитьПараметрыЗагрузкиДанныхИзФайла(Параметры) Экспорт

//  Структура:
//    * Заголовок - Строка - представление в списке вариантов загрузки и в заголовке окна.
//    * ТипДанныхКолонки - Соответствие из КлючИЗначение:
//        ** Ключ - Строка - имя колонки таблицы.
//        ** Значение - ОписаниеТипов - описание типа данных колонки.
//    * ОбязательныеКолонки - Массив из Строка - содержит список обязательных полей для заполнения.
//    * ПолноеИмяОбъекта - Строка - полное имя объекта, как в метаданных. Например Справочник.Партнеры.
//    * ПредставлениеОбъекта - Строка - представление объекта в таблице сопоставления данных. Например, "Клиент".
//    * ТипЗагрузки - Строка - варианты загрузки данных (служебный).

    Параметры.ОбязательныеКолонки.Добавить("КолонкаСТипомДата");
    Параметры.ТипДанныхКолонки.Вставить("КолонкаСТипомБулево", Новый ОписаниеТипов("Булево"));
    Параметры.ТипДанныхКолонки.Вставить("КолонкаСТипомДата", ОбщегоНазначения.ОписаниеТипаДата(ЧастиДаты.Дата));

КонецПроцедуры
```
> ВАЖНО! Если предполагается сопоставлять элементы справочника по строковым реквизитам, то обязательно в процедуре `ОпределитьПараметрыЗагрузкиДанныхИзФайла` нужно их описать с указанием длины. Без этого в запросе дальше не получится их использовать, т.к. длина по умолчанию устанавливается неограниченная

### СопоставитьЗагружаемыеДанныеИзФайла
По стандартному сценарию колонки для сопоставления указываются пользователем вручную:
![Изображение](/bsp-zagruzka-iz-faila/15.png)
В случае реализации собственных механизмов загрузки это поле отсутствует,
![Изображение](/bsp-zagruzka-iz-faila/16.png)
поэтому в этом методе необходимо определить алгоритм и заполнить колонку `ОбъектСопоставления` таблицы `ЗагружаемыеДанные` подобранными элементами справочника

```bsl
// Производит сопоставление загружаемых данных с данными в ИБ.
// Состав и тип колонок таблицы соответствует реквизитам справочника или макету "ЗагрузкаИзФайла".
//
// Параметры:
//   ЗагружаемыеДанные - см. ЗагрузкаДанныхИзФайла.ТаблицаСопоставления
//
Процедура СопоставитьЗагружаемыеДанныеИзФайла(ЗагружаемыеДанные) Экспорт
    
    // примитивный пример сопоставления

    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |	ЗагружаемыеДанные.Идентификатор КАК Идентификатор,
    |	ЗагружаемыеДанные.Наименование КАК Наименование
    |ПОМЕСТИТЬ ВТЗагружаемыеДанные
    |ИЗ
    |	&ЗагружаемыеДанные КАК ЗагружаемыеДанные
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |	ТестовыйСправочник.Ссылка КАК Ссылка,
    |	ВТЗагружаемыеДанные.Идентификатор КАК Идентификатор
    |ИЗ
    |	ВТЗагружаемыеДанные КАК ВТЗагружаемыеДанные
    |		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ТестовыйСправочник КАК ТестовыйСправочник
    |		ПО ВТЗагружаемыеДанные.Наименование = ТестовыйСправочник.Наименование";
    Запрос.УстановитьПараметр("ЗагружаемыеДанные", ЗагружаемыеДанные);
    
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        
        СтрокаТаблицы = ЗагружаемыеДанные.Найти(Выборка.Идентификатор, "Идентификатор");
        Если СтрокаТаблицы <> Неопределено Тогда
            СтрокаТаблицы.ОбъектСопоставления = Выборка.Ссылка;
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры
```
![Изображение](/bsp-zagruzka-iz-faila/17.png)

### ЗагрузитьИзФайла
В этом методе по данным ТЗ `ЗагружаемыеДанные` и структуры `ПараметрыЗагрузки` необходимо реализовать создание/обновление элементов справочников.
В структуре  `ПараметрыЗагрузки` указаны значения этих параметров
![Изображение](/bsp-zagruzka-iz-faila/18.png)
|Свойство|Тип|Значение|
|-|-|-|
|`ОбновлятьСуществующие`|Число|1, если обновлять сопоставленные элементы, 0, если не обновлять|
|`СоздаватьНовые`|Число|1, если создавать новые несопоставленные элементы, 0, если пропускать|

Пример
```bsl
// Загрузка данных из файла.
//
// Параметры:
//  ЗагружаемыеДанные - см. ЗагрузкаДанныхИзФайла.ОписаниеЗагружаемыхДанныхДляСправочников
//  ПараметрыЗагрузки - см. ЗагрузкаДанныхИзФайла.НастройкиЗагрузкиДанных
//  Отказ - Булево    - отмена загрузки. Например, если данные некорректные.
//
Процедура ЗагрузитьИзФайла(ЗагружаемыеДанные, ПараметрыЗагрузки, Отказ) Экспорт
	
	Для Каждого СтрокаТаблицы Из ЗагружаемыеДанные Цикл
		
		ОбъектСопоставленияЗаполнен = ЗначениеЗаполнено(СтрокаТаблицы.ОбъектСопоставления);

		Если (ОбъектСопоставленияЗаполнен И ПараметрыЗагрузки.ОбновлятьСуществующие = 0)
			Или (Не ОбъектСопоставленияЗаполнен И ПараметрыЗагрузки.СоздаватьНовые = 0) Тогда
			
			СтрокаТаблицы.РезультатСопоставленияСтроки = "Пропущен";
			
			Продолжить;
			
		КонецЕсли;

		НачатьТранзакцию();
		
		Попытка
			Если ОбъектСопоставленияЗаполнен Тогда

				Блокировка        = Новый БлокировкаДанных;
				ЭлементБлокировки = Блокировка.Добавить("Справочник.ТестовыйСправочник");
				ЭлементБлокировки.УстановитьЗначение("Ссылка", СтрокаТаблицы.ОбъектСопоставления);
				Блокировка.Заблокировать();

				ЭлементСправочника = СтрокаТаблицы.ОбъектСопоставления.ПолучитьОбъект();

				Если ЭлементСправочника = Неопределено Тогда
					ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
						НСтр("ru = 'Номенклатура с артикулом %1 не существует.'"), СтрокаТаблицы.Артикул);
				КонецЕсли;
				СтрокаТаблицы.РезультатСопоставленияСтроки = "Обновлен";

			Иначе

				ЭлементСправочника = СоздатьЭлемент();
				СтрокаТаблицы.РезультатСопоставленияСтроки = "Создан";

			КонецЕсли;

			ЭлементСправочника.Наименование = СтрокаТаблицы.Наименование;

			Если Не ЭлементСправочника.ПроверитьЗаполнение() Тогда
				
				СтрокаТаблицы.РезультатСопоставленияСтроки = "Пропущен";
				ОтменитьТранзакцию();
				
			Иначе
				ЭлементСправочника.Записать();
				СтрокаТаблицы.ОбъектСопоставления = ЭлементСправочника.Ссылка;

				// Для записи данных из колонки <Дополнительные реквизиты>
				ЗагрузкаДанныхИзФайла.ЗаписатьСвойстваОбъекта(ЭлементСправочника.Ссылка, СтрокаТаблицы);
				
				ЗафиксироватьТранзакцию();
				
			КонецЕсли;
		Исключение
			ОтменитьТранзакцию();
			УправлениеДоступом.ОтключитьОбновлениеКлючейДоступа(Ложь, Ложь);
			Причина = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
			СтрокаТаблицы.РезультатСопоставленияСтроки = "Пропущен";
			СтрокаТаблицы.ОписаниеОшибки = НСтр("ru = 'Невозможна запись данных по причине:'") + Символы.ПС + Причина;
		КонецПопытки;
	КонецЦикла;
	
КонецПроцедуры
```