Перейти к основному содержимому

Загрузка данных из макетов

Описание

Для загрузки данных из макетов подойдет метод ЮТест.Данные().ЗагрузитьИзМакета

Он позволяет:

  • Загружать данные из табличных макет (ТабличныйДокумент или ТекстовыйДокумент с таблицей markdown)
  • Загружать данные на клиенте и на сервер
  • Загружать не весь макет, а конкретную область (в одном макете может находится несколько таблиц данных)
  • Приводить значения к указанным типам и создавать записи в базе данных

Пример табличного документа:

ТоварТовар.ПоставщикТовар.ВидЦенаКоличествоСумма
Товар 1Поставщик 1Товар1001100
Товар 11002200
Товар 1Поставщик 2Товар1003300
Товар 2Поставщик 1Товар2 00012000
УслугаУслуга300,51300.5

Особенности:

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

    подсказка

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

  • Можно указывать значения вложенных реквизитов, например при создании товаров (колонка Товар) необходимо указать конкретные значения поставщика и вида товара. Для этого необходимо добавить колонки Товар.Поставщик и Товар.Вид, в которых указать нужные значения.

  • Переиспользование созданных данных, используется КэшЗначений, в который помещаются все созданные данные, если кэш содержит данные подходящего типа с указанным идентификатором, то используется ранее созданное значение из кэша. Например, в примере выше, для первой строки будет создан товар с идентификатором Товар 1. В строках 2 и 3 будет использовано значение из кэша - Товар 1, в 4й и 5й строке - созданы новые товары.

    подсказка

    Кэш значений может передаваться между загрузками разных макетов, например есть макет с табличной частью документа и второй макет с набором ожидаемых движений. Чтобы созданные товары из табличной части соответствовали товарам движений необходимо передать КэшЗначений между загрузками.

    КэшЗначений = Неопределено;
    ТабличнаяЧасть = ЮТест.Данные().ЗагрузитьИзМакета("ОбщийМакет.ДанныеДокумента.ТабличнаяЧасть", ОписанияТиповТЧ, КэшЗначений);
    ОжидаемыеДвижения = ЮТест.Данные().ЗагрузитьИзМакета("ОбщийМакет.ДанныеДокумента.ДвиженияРегистра1", ОписанияТиповРегистра1, КэшЗначений);
    подсказка

    Значение в колонке "Товар" является идентификатором ссылки. Для справочника значение этой колонки по умолчанию записывается в реквизит "Наименование" или "Код", в зависимости от того, какой из этих реквизитов является основным представлением. Для документа это значение никуда не записывается, оно лишь является идентификатором. Таким образом, если одному значению в колонке "Товар" соответствуют различные значения в других колонках, то в элемент справочника запишутся реквизиты из первой строки, а для других строк ссылка на этот элемент будет проставлена по соответствующему идентификатору

Примеры

Загрузка всего макета

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

Исходные данные

ТоварТовар.ПоставщикТовар.ВидЦенаКоличествоСумма
Товар 1Поставщик 1Товар1001100
Товар 11002200
Товар 1Поставщик 2Товар1003300
Товар 2Поставщик 1Товар2 00012000
УслугаУслуга300,51300.5
к сведению

Этот код работает и на клиенте и на сервер. Для сервера результатом будет таблица значений, для клиента - массив структур

ОписанияТипов = Новый Соответствие;
ОписанияТипов.Вставить("Товар", Новый ОписаниеТипов("СправочникСсылка.Товары"));
ОписанияТипов.Вставить("Цена", Новый ОписаниеТипов("Число"));
ОписанияТипов.Вставить("Количество", Новый ОписаниеТипов("Число"));
ОписанияТипов.Вставить("Сумма", Новый ОписаниеТипов("Число"));

ТаблицаТоваров = ЮТест.Данные().ЗагрузитьИзМакета("ОбщийМакет.ЮТ_МакетТестовыхДанных", ОписанияТипов);

ЮТест.ОжидаетЧто(ТаблицаТоваров)
.ИмеетТип("ТаблицаЗначений")
.ИмеетДлину(5)
.Свойство("[0].Товар.Наименование").Равно("Товар 1")
.Свойство("[0].Товар.Поставщик.Наименование").Равно("Поставщик")
.Свойство("[0].Товар.Вид").Равно(Перечисления.ВидыТоваров.Товар)
.Свойство("[0].Количество").Равно(1)
.Свойство("[0].Цена").Равно(100)
.Свойство("[0].Сумма").Равно(100)
.Свойство("[1].Товар").Равно(ТаблицаТоваров[0].Товар)
.Свойство("[1].Количество").Равно(2)
.Свойство("[1].Цена").Равно(100)
.Свойство("[1].Сумма").Равно(200)
.Свойство("[2].Товар").Равно(ТаблицаТоваров[0].Товар)
.Свойство("[2].Количество").Равно(3)
.Свойство("[2].Цена").Равно(100)
.Свойство("[2].Сумма").Равно(300)
.Свойство("[3].Товар.Наименование").Равно("Товар 2")
.Свойство("[3].Товар.Поставщик.Наименование").Равно("Поставщик")
.Свойство("[3].Товар.Вид").Равно(Перечисления.ВидыТоваров.Товар)
.Свойство("[3].Количество").Равно(1)
.Свойство("[3].Цена").Равно(2000)
.Свойство("[3].Сумма").Равно(2000)
.Свойство("[4].Товар.Наименование").Равно("Услуга")
.Свойство("[4].Товар.Поставщик").НеЗаполнено()
.Свойство("[4].Товар.Вид").Равно(Перечисления.ВидыТоваров.Услуга)
.Свойство("[4].Количество").Равно(1)
.Свойство("[4].Цена").Равно(300.5)
.Свойство("[4].Сумма").Равно(300.5);

Загрузка области из макета

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

Пример юнит-теста для проверки работы метода. На входе он получает таблицу значений, которую заполняет и/или возвращает. В одной области табличного документа - исходные данные, передаваемые в качестве входящего параметра, а в другой - таблица с ожидаемым значением.

Исходные данные

ТоварТовар.ПоставщикТовар.ВидКоличество
Товар 1Поставщик 1Товар1
Товар 2Поставщик 1Товар1
УслугаУслуга1
ТоварЦенаКоличествоСумма
Товар 11001100
Товар 22 00012000
Услуга300,51300.5
ОписанияТипов = Новый Соответствие;
ОписанияТипов.Вставить("Товар", Новый ОписаниеТипов("СправочникСсылка.Товары"));
ОписанияТипов.Вставить("Количество", Новый ОписаниеТипов("Число"));

// Для общего использования созданных значений используется переменная КешЗначений.
// В двух табличных документах одинаковый состав товаров.
// Чтобы в обеих таблицах этому товару соответствовало одно значение справочника -
// нужно передавать в параметре функции переменную, в которой будут храниться соответствия
// наименований к ссылкам на объекты.
КэшЗначений = Новый Соответствие;

ТаблицаИсходныхДанных = ЮТест.Данные().ЗагрузитьИзМакета(
"ОбщийМакет.ЮТ_МакетТестовыхДанных.R1C1R4C4",
ОписанияТипов,
КэшЗначений
);

ОписанияТипов = Новый Соответствие;
ОписанияТипов.Вставить("Товар", Новый ОписаниеТипов("СправочникСсылка.Товары"));
ОписанияТипов.Вставить("Цена", Новый ОписаниеТипов("Число"));
ОписанияТипов.Вставить("Количество", Новый ОписаниеТипов("Число"));
ОписанияТипов.Вставить("Сумма", Новый ОписаниеТипов("Число"));

ТаблицаОжидаемыхЗначений = ЮТест.Данные().ЗагрузитьИзМакета(
"ОбщийМакет.ЮТ_МакетТестовыхДанных.R5C1R8C4",
ОписанияТипов,
КэшЗначений
);

ТаблицаРезультата = ОбщийМодуль1.ТаблицаТоваровСЦенамиИзОстатков(ТаблицаИсходныхДанных);

ЮТест.ОжидаетЧто(ТаблицаРезультата)
.Равно(ТаблицаОжидаемыхЗначений);

Загрузка документа с табличной частью и проверка движений

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

В макете мы создадим три именованные области с таблицами

Область Реквизиты_документа

ПриходТовараДатаПоставщикВалютаСкладОрганизация
Документ 1ДатаПоставщикВалютаСкладОрганизация

Область Табличная_часть_документа

ДокументТоварТовар.ПоставщикТовар.ВидЦенаКоличествоСумма
Документ 1Товар 1ПоставщикТовар1001100
Документ 1Товар 2ПоставщикТовар2 00012000
Документ 1УслугаУслуга300,51300.5

Область Ожидаемые_движения

ПериодАктивностьВидДвиженияРегистраторСкладТоварКоличество
ДатаИстинаПриходДокумент 1СкладТовар 11
ДатаИстинаПриходДокумент 1СкладТовар 21
ДатаИстинаПриходДокумент 1СкладУслуга1
КэшЗначений = Новый Соответствие;

Организация = ЮТест.КонтекстМодуля().Организация;
Поставщик = ЮТест.Данные().СоздатьЭлемент(Справочники.Контрагенты, "Поставщик");
ДатаДокумента = НачалоДня(ТекущаяДатаСеанса());

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

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

ТаблицаДокументов = ЮТест.Данные().ЗагрузитьИзМакета(
"ОбщийМакет.ЮТ_МакетТестовыхДанных.Реквизиты_документа"
ОписанияТипов,
КэшЗначений,
ЗаменяемыеЗначения
);

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

ТаблицаТоваров = ЮТест.Данные().ЗагрузитьИзМакета(
"ОбщийМакет.ЮТ_МакетТестовыхДанных.Табличная_часть_документа",
ОписанияТипов,
КэшЗначений,
ЗаменяемыеЗначения
);

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

ТаблицаДвижений = ЮТест.Данные().ЗагрузитьИзМакета(
"ОбщийМакет.ЮТ_МакетТестовыхДанных.Ожидаемые_движения",
ОписанияТипов,
КэшЗначений,
ЗаменяемыеЗначения
);

Для Каждого ДанныеДокументов Из ТаблицаДокументов Цикл

Отбор = Новый Структура("Документ", ДанныеДокументов.ПриходТовара);
ТоварыДокумента = ТаблицаТоваров.Скопировать(Отбор);

ДокументОбъект = ДанныеДокументов.Документ.ПолучитьОбъект();
ДокументОбъект.Товары.Загрузить(ТоварыДокумента);
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);

ТоварныеЗапасы = ДокументОбъект.Движения.ТоварныеЗапасы;
ТоварныеЗапасы.Прочитать();
ТаблицаТоварныхЗапасов = ТоварныеЗапасы.Выгрузить();

Отбор = Новый Структура("Регистратор", ДанныеДокументов.ПриходТовара);
ОжидаемыеТоварныеЗапасы = ТаблицаДвижений.Скопировать(Отбор);

ЮТест.ОжидаетЧто(ТаблицаТоварныхЗапасов)
.Равно(ОжидаемыеТоварныеЗапасы);

КонецЦикла;

Заменяемые значения

Создание и заполнение объектов двойной вложенности и более (например, "Товар.Поставщик.ВидКонтрагента") не поддерживается. Если есть такая потребность, следует использовать переменную "ЗаменяемыеЗначения". Т.е. следует создать и заполнять нужный объект перед преобразованием табличного документа в таблицу значений, а затем передать его в функцию получения таблицы значений.

Поставщик = ЮТест.Данные().КонструкторОбъекта(Справочники.Контрагенты)
.Установить("ВидКонтрагента", ВидКонтрагента)
.Записать();

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

ТаблицаЗначений = ЮТест.Данные().ЗагрузитьИзМакета(
ТабличныйДокумент,
ОписанияТипов,
Неопределено,
ЗаменяемыеЗначения
);

ЮТест.ОжидаетЧто(ТаблицаЗначений)
.Свойство("[0].Товар.Поставщик.ВидКонтрагента").Равно(ВидКонтрагента);

Заменяемые значения и составные типы

Можно использовать составные типы в колонках таблицы значений, но создание объектов метаданных для такой колонки не поддерживается. Можно воспользоваться соответствием "ЗаменяемыеЗначения", если потребуется в одну колонку записать значения разных типов.

ТипАналитики = Новый ОписаниеТипов("СправочникСсылка.Товары,СправочникСсылка.Контрагенты");

ОписанияТипов = Новый Соответствие;
ОписанияТипов.Вставить("Аналитика", ТипАналитики);

Поставщик = ЮТест.Данные().СоздатьЭлемент(Справочники.Контрагенты);
Товар = ЮТест.Данные().СоздатьЭлемент(Справочники.Товары);

ЗаменяемыеЗначения = Новый Соответствие;
ЗаменяемыеЗначения.Вставить("Аналитика (Поставщик)", Поставщик);
ЗаменяемыеЗначения.Вставить("Аналитика (Товар)", Товар);

ТаблицаЗначений = ЮТест.Данные().ЗагрузитьИзМакета(
ТабличныйДокумент,
ОписанияТипов,
Неопределено,
ЗаменяемыеЗначения
);

ЮТест.ОжидаетЧто(ТаблицаЗначений)
.Свойство("[0].Аналитика").Равно(Поставщик)
.Свойство("[1].Аналитика").Равно(Товар)
;

Inline макеты, загрузка из Markdown

При необходимости вы можете разместить таблицу с данными прямо в коде.

подсказка

Если вы используете EDT, то удобнее редактировать многострочные строки в Редакторе запроса

ТаблицаMarkDown = 
"| Товар | Цена | Количество | Сумма |
||---------|-------|------------|-------|
|| Товар 1 | 100 | 1 | 100 |
|| Товар 2 | 2 000 | 1 | 2000 |
|| Услуга | 300,9 | 1 | 300,9 |";

ОписанияТипов = Новый Соответствие;
ОписанияТипов.Вставить("Товар", Новый ОписаниеТипов("СправочникСсылка.Товары"));
ОписанияТипов.Вставить("Цена", Новый ОписаниеТипов("Число"));
ОписанияТипов.Вставить("Количество", Новый ОписаниеТипов("Число"));
ОписанияТипов.Вставить("Сумма", Новый ОписаниеТипов("Число"));

Данные = ЮТест.Данные().ЗагрузитьИзМакета(ТаблицаMarkDown, ОписанияТипов);

Другие методы загрузки

    Макет = 
"| Имя | ИмяКоллекции | Конструктор | Группы | Ссылочный | Реквизиты | Измерения | Ресурсы | РеквизитыАдресации | ТабличныеЧасти |
||------------------------|-------------------------|----------------------|--------|-----------|-----------|-----------|---------|--------------------|----------------|
|| Справочник | Справочники | СоздатьЭлемент | + | + | + | | | | + |
|| Документ | Документы | СоздатьДокумент | | + | + | | | | + |
|| ПланВидовХарактеристик | ПланыВидовХарактеристик | СоздатьЭлемент | + | + | + | | | | + |
|| ПланСчетов | ПланыСчетов | СоздатьСчет | | + | + | | | | + |
|| ПланВидовРасчета | ПланыВидовРасчета | СоздатьВидРасчета | | + | + | | | | + |
|| ПланОбмена | ПланыОбмена | СоздатьУзел | | + | + | | | | + |
|| РегистрСведений | РегистрыСведений | СоздатьНаборЗаписей | | | + | + | + | | |
|| РегистрНакопления | РегистрыНакопления | СоздатьНаборЗаписей | | | + | + | + | | |
|| РегистрБухгалтерии | РегистрыБухгалтерии | СоздатьНаборЗаписей | | | + | + | + | | |
|| РегистрРасчета | РегистрыРасчета | СоздатьНаборЗаписей | | | + | + | + | | |
|| БизнесПроцесс | БизнесПроцессы | СоздатьБизнесПроцесс | | + | + | | | | + |
|| Задача | Задачи | СоздатьЗадачу | | + | + | | | + | + |
|";
КоллекцияОписаний = ЮТТестовыеДанные.ТаблицаMarkDown(Макет);

ТипыМетаданных = Новый Структура();

Для Каждого Запись Из КоллекцияОписаний Цикл

Описание = Новый Структура();
Описание.Вставить("Имя", Запись.Имя);
Описание.Вставить("ИмяКоллекции", Запись.ИмяКоллекции);
Описание.Вставить("Конструктор", Запись.Конструктор);
Описание.Вставить("Группы", Запись.Группы = "+");
Описание.Вставить("Ссылочный", Запись.Ссылочный = "+");
Описание.Вставить("Реквизиты", Запись.Реквизиты = "+");
Описание.Вставить("Измерения", Запись.Измерения = "+");
Описание.Вставить("Ресурсы", Запись.Ресурсы = "+");
Описание.Вставить("РеквизитыАдресации", Запись.РеквизитыАдресации = "+");
Описание.Вставить("ТабличныеЧасти", Запись.ТабличныеЧасти = "+");

ТипыМетаданных.Вставить(Описание.Имя, Описание);
ТипыМетаданных.Вставить(Описание.ИмяКоллекции, Описание);

КонецЦикла;

Возврат ТипыМетаданных;
    Функция ИмяКоллекции(Имя) Экспорт
Макет =
"| Имя | ИмяКоллекции |
||------------------------|-------------------------|
|| Справочник | Справочники |
|| Документ | Документы |
|| ПланВидовХарактеристик | ПланыВидовХарактеристик |
|| ПланСчетов | ПланыСчетов |
|| ПланВидовРасчета | ПланыВидовРасчета |
|| ПланОбмена | ПланыОбмена |
|| РегистрСведений | РегистрыСведений |
|| РегистрНакопления | РегистрыНакопления |
|| РегистрБухгалтерии | РегистрыБухгалтерии |
|| РегистрРасчета | РегистрыРасчета |
|| БизнесПроцесс | БизнесПроцессы |
|| Задача | Задачи |
|";
Описания = ЮТТестовыеДанные.СтруктураMarkDown("Имя", Макет);

Возврат Описания[Имя].ИмяКоллекции;

КонецФункции