1с прочитать xml в таблицу значений
Иногда требуется перенести таблицу значений между базами через файл XML. Для этого предлагаю почти универсальный быстрый способ программной разработки без долгого описания типов, узлов, полей и т.д. На чтение или запись таблицы значений по 4 строки кода в процедурах.
Статья будет интересна для начинающих программистов 1С и тем, кто слышал про термины ФабрикаXDTO и СериализаторXDTO, но не использовал их для быстрого «общения» таблицы значений и файла XML.
Небольшое ограничение – типы данных в реквизитах обрабатываемой таблицы значений должны быть примитивные (Null, Неопределено, число, строка, дата) или одинаковые в базе из которой выгружается таблица значений и базе, в которую загружается таблица значений. При переносе ссылочных значений база может не найти такие типы значений, сообщит об этом. Это связано с тем, что ФабрикаXDTO содержит все пакеты XDTO, имеющиеся в конфигурации, а также предопределенные пакеты, т.е. «знает» объекты конфигурации и сама их описывает в файле XML. Если между конфигурациями переносится таблица только с примитивными типами – то нет проблем!
Даже синтакс-помощник версии 8.3.14.1565 для СериализаторXDTO.ЗаписатьXML не упоминает о работе с таблицей значений. Обработки тестировалось на версии 8.3.13.1513. Есть вероятность, что на «старых» версиях не будет работать – надо проверять.
Предлагаю рабочие обработки для обычных и управляемых форм, которые позволяют записать таблицу значений в файл XML всего в 4 строки, и обработки для чтения сохраненной таблицы значений из файла XML всего в 4 строки. Дополнительно в обработках используются различные приемы, например:
- Формирование колонок по данным загруженной таблицы значений для обычных и управляемых форм.
- В управляемой форме программное добавление таблицы значений с командной панелью и колонками по данным обрабатываемой таблицы значений.
- Выбор любого доступного документа из базы и чтение выбранной табличной части в таблицу значений с возможность редактирования полученной таблицы значений и записи в файл XML.
- В управляемой форме использование асинхронных методов для диалогов выбора файла.
Обработки для демонстрации записи таблицы значений в файл XML:
- ЗаписьТаблицыЗначенийВXML.epf – для обычной формы
- ЗаписьТаблицыЗначенийВXMLУФ.epf – для управляемой формы
Для примера формируется таблица значений из доступных данных любой табличной части любого документа. Необходимо выбрать тип документа, выбрать документ. Можно изменить выбранную табличную часть, по умолчанию выбирается первая табличная часть.
Кнопка «Заполнить таблицу» - очищает таблицу, создает необходимые колонки и заполняет таблицу значений данными выбранной табличной части. Данные таблицы можно редактировать.
Кнопка «Записать в XML» вызывает диалог выбора файла и сохраняет таблицу значений в файл XML.
Кнопка «Очистить таблицу» очищает данные таблицы.
Кнопка «Очистить все» очищает выбранные значения всех полей и данные таблицы.
Обработки для демонстрации чтения таблицы значений из файла XML:
- ЧтениеТаблицыЗначенийИзXML.epf – для обычной формы
- ЧтениеТаблицыЗначенийИзXMLУФ.epf – для управляемой формы
Кнопка «Прочитать таблицу их XML» - вызывает диалог выбора файла, очищает таблицу, создает необходимые колонки и заполняет таблицу значений данными из загруженного файла XML. Данные таблицы можно редактировать.
Если будет загружен файл с таблицей данных из другой базы с «незнакомыми» типами объектов – система сообщит о такой ошибке. В обычной форме для «незнакомых» полей будет указано, например: (95:a31d14dae9b19a4811e61dcf2b5e5ea3), а другие данные будут загружены. В управляемой форме система полностью не загрузит данные, если есть «незнакомые» типы объектов.
Желательно подготовить данные перед выгрузкой, чтобы их можно было обработать в базе приемнике. Например – задать такое же имя поля для совпадающих типов или передавать уникальные идентификаторы вместо ссылок. Примитивные типы (Null, Неопределено, число, строка, дата) передаются без проблем между разными конфигурациями баз.
Кнопка «Очистить» очищает данные таблицы.
Файл XML, записанный этими обработками для демонстрации записи в обычной или управляемой форме, может быть прочитан любой этой обработкой для демонстрации чтения - в обычной или управляемой форме с учетом указанных ограничений. Если между конфигурациями переносится таблица только с примитивными типами – то нет проблем!
Надеюсь, что после демонстрации такого эффективного использования появится дополнительный интерес к изучению и использованию объектов ФабрикаXDTO и СериализаторXDTO.
Разработчики которые начинают интегрировать 1С8 с внешними системами достаточно часто сталкиваются с необходимость чтения XML. В свое время для унификации обработки чтения была создана обработка разворачивающая дерево XML по определенному узловому элементу в таблицу значения, где имена колонок являются по сути путем к данным XPATH.
2. Имя узлового элемента (элемент который развернётся в строку таблицы значений,)
3. Имя файла в который будет записано сериализованное представление таблицы значений
4. Суб путь. необязательный параметр, в случае если надо указать в какой ветке XML искать узловые элементы
В случае если утилитка вложена в качестве макета в обработку то её можно вызвать следующей функцией
Функция ПрочитататьВТЧXMLИерархВнеш(пСТрДанных,пТЗ,пИмяУзловогоЭлемента,пСубпуть = "") Экспорт
лПуть = КаталогВременныхФайлов()+"CreatingTZFor1C.exe";
Попытка
ЭтотОбъект.ПолучитьМакет("CreatingTZFor1C").Записать(лПуть);
Исключение
лФайл = Новый Файл(лПуть);
Если НЕ лФайл.Существует() Тогда
Возврат Неопределено;
КонецЕсли;
КонецПопытки;
лВремФайл = ПолучитьИмяВременногоФайла("xml");
лЗаписьТекста = Новый ЗаписьТекста(лВремФайл);
лЗаписьТекста.Записать(пСТрДанных);
лЗаписьТекста.Закрыть();
лВремРезФайл = ПолучитьИмяВременногоФайла("data");
лТЧ = Новый ТаблицаЗначений;
ЗначениеВФайл(лВремРезФайл,лТЧ);
Если ПустаяСтрока(пСубпуть) Тогда
лКоманда = """"+лПуть+""" """+лВремФайл+""" """+пИмяУзловогоЭлемента+""" """+лВремРезФайл+"""";
Иначе
лКоманда = """"+лПуть+""" """+лВремФайл+""" """+пИмяУзловогоЭлемента+""" """+лВремРезФайл+""" """+пСубпуть+"""";
КонецЕсли;
//КомандаСистемы(лКоманда,КаталогВременныхФайлов());
ЗапуститьПриложение(лКоманда,КаталогВременныхФайлов(), Истина);
пТЗ = ЗначениеИзФайла(лВремРезФайл);
Возврат лВремРезФайл;
КонецФункции
И собственно вызов
ТЧДанных = Новый таблицазначений;
// лСтрРез - Строка с XML
// Policy - Имя узла разворачиваемого в строку
Такой финт ушами позволяет из XML файла весом более 17 МБ за 10 секунд положить в таблицу значений 6000 строк и 2700 колонок. Так что польза очевидна :-)
Через Пакеты XDTO ты описываешь свои данные. Данные могут быть как структурой так и массивом или списком структур или примитивных типов.
Для того что бы создать массив нужно указать минимальное количество 0, максимальное количество размер массива, для списка это -1. Ну и выдумать свое пространство имен. Все достаточно просто.
А ты обычным чтение XML пройдись, а сериализатору подсовывай не весь файл, а только данные относящиеся к одному объекту. Объект может быть списком.
еще я чет не понял - нафик я создаю сериализатор, если все равно пользуюсь только Сериализатор.ФабрикаХДТО?
Не СписокОбъектов.Добавить посмотри в отладчике какие у СписокОбъектов свойчтва. Сейчас сам посмотрю тже
по причине:
Несоответствие типов XDTO:
Тип 'TypeDescription' не найден
Значение не может быть установлено свойству, имеющему объектный тип
напоролся
по причине:
по причине:
Ошибка преобразования данных XDTO:
Чтение объекта типа: Array - [7,16]
Проверка дополнительного свойства:
имя: Value
по причине:
Ошибка преобразования данных XDTO:
Чтение объекта типа: CatalogObject.усНоменклатура - [16,3]
Проверка дополнительного свойства:
имя: БазоваяЕдиницаХранения
по причине:
Ошибка отображения типов:
Отображение лексического значения '' в значение типа 'СправочникСсылка.усЕдиницыХранения'
по причине:
чего то снова не хваатет?
(68)Не правильно. Не точно мысль выражена.
Для объектов справочника в xml данных, должны быть все реквизиты которые определены для объекта с учетом значения предопределенного реквизита ЭтоГруппа. Реквизиты могут быть определены для групп и для элементов по-разному. Это никак не отражается в xml-схеме, но это влияет на сериализацию и успешность десериализации.
В сериализации первого объекта в массиве видно что это группа (
1)они все определены для группы?
2)пустые значения (в понятиях 1С значения по умолчанию) не всегда могут быть представлены просто пустой строкой, например xml-предствление пустой ссылки - это вовсе не пустая строка (если БазоваяЕдиницаХранения это ссылочный тип, то должно быть 00000000-0000-0000-0000-000000000000).
по причине:
Несоответствие свойства и элемента данных XDTO:
Свойство: 'ТипТранспортнойЕдиницы'
на момент установки это свойство неопределено
Ты эксортируй пакеты в выгружаемую конфигурацию из загружаемой. Тогда заполнение должно пройти нормально и загрузка.
(70)почему CatalogObject.усТипыТранспортныхЕдиниц?
там не может быть CatalogObject, там должен быть CatalogRef
Ну и вообще в целом в Array выгружать все это вовсе не обязательно. Можно выгружать в корневой элемент с любым именем, а потом просто читать сериализатором последовательно уже в объекты, как написано в (28).
(74) фабрика в моей конфиге создается по хмл-схеме приемника
(73) при попытке создать ref - получаю вместо ссылки Неопределено, так хоть объект создается
(75) да я хочу без лишнего класса, через фабрику )
при попытке загрузки
имя: БазоваяЕдиницаХранения
по причине:
Ошибка отображения типов:
Отображение лексического значения '' в значение типа 'СправочникСсылка.усЕдиницыХранения'
по причине:
(75) С эрраем то проще читать. Меньше буковок нажимать. Он для выгрузки использует родной сериализатор, а по уму должен заполнять объекты из пакета в экспортируемую конфигурацию
Однаждый Джоель Мозес (англ. Joel Moses ) сказал «APL как красивый бриллиант — безупречный, симметричный. Но вы ничего не можете к нему добавить. Если вы попытаетесь приклеить к нему другой алмаз — вы не получите бóльший алмаз. Лисп же — это ком грязи. Добавь еще и он останется комом грязи — он все еще будет выглядеть как Лисп.» Для меня, кроме лиспа, таким комом грязи стал XML. На протяжении долгого времени на эти значки и > натягивают все больше и больше семантики. Появляются страшные слова — DTD, xsd, xslt, RDF …. Сегодня уже вовсю идет подготовка к Xforms, и кто знает что еще прикрутят к этому формату завтра? Кассанрой работать всегда тяжело, но одно знаю точно — XML останется XML — заголовок и корневой элемент, открывающие и закрывающие тэги, текстовое представление — останется всегда. А раз так — то вечным будет вопрос — как прочитать XML и работать с ним?
Многие пишут свои универсальные функции которые разбирают XML в дерево, в таблицу значений, в массив или как в этой заметке — в структуру. У всех этих способов есть свои плюсы и минусы.
Плюсы подхода изложенного в этой заметке — типизация полученного результата.
Минусы — время работы, объем потребляемой памяти. Поэтому для чтения больших файлов (более 5 kb) слабо подходит.
Для примера используется такое определение XSD
и вот такой xml для теста
Код для преобразования —
При помощи этого кода легко и быстро можно превратить входящий xml в структуру и затем уже работать с ней в своем приложении.
Вот так будет выглядеть корневой элемент
На этом скриншоте — элементы массива (кстати, если XML — простой (нет пересекающихся имен типов) можно легко отказаться от описания типа)
Так выглядит загруженный элемент one (обратите внимание что тэг age — уже приведен к числу, согласно схемы)
В обработке прикрепленной к заметке — тот же самый код (плюс несколько несложных сервисных функций)
Related Posts
6 Comments
Пхе. В своё время я написал функцию-универсалку, которая любой XDTO-объект раздербанивает в коллекции 1С (например, в дерево, в строках которого массивы, или структуры, или ещё что, короче, полностью соответствуя структуре исходного объекта). Короче, усложнённый вариант вашей версии. Разумеется, исходя из его URI и фабрики. Но и то публиковать не стал, ибо техническая вспомогательная хрень.
А вы, автор, совсем простые вещи эдак разжёвываете… Зачем? Всё равно, что перебор элементов массива объяснять статьёй на 5 страниц.
Кстати, конечно же, можно определять факт «списочности» иначе. Например, навскидку, так:
Если СвойствоXDTO.НижняяГраница=0 и СвойствоXDTO.ВерхняяГраница=-1 Тогда // списочный
ну или учитывать, что кол-во в списке может быть ограничено, и тогда уж исходя из него ))
В 1С XML используется в основном для обмена информацией с WEB, электронными библиотеками, различными внешними системами для экспорта/импорта данных. XML это текстовые файлы с разметками, которые позволяют хранить данные в уникальном структурированном виде. Могут редактироваться в любом текстовом редакторе.
-< Ресторан Кухня fs10lh1-5">Азиатская " Счет fs10lh1-5">3500 " Категория fs10lh1-5">Высшая " Название fs10lh1-5">Китайская грамота ">
-< Ресторан Кухня fs10lh1-5">Европейская " Счет fs10lh1-5">5000 " Категория fs10lh1-5">Люкс " Название fs10lh1-5">Итальянский Экспресс ">
✔ Чтение файла в формате XML по порядку (способ №1)
//Подходит для файлов более 100Mb
&НаСервере
Процедура ПрочитатьФайлXMLПоПорядкуСпособ1 ( ПутьКФайлу )
XML = Новый ЧтениеXML ;
XML . ОткрытьФайл ( ПутьКФайлу );
Пока XML . Прочитать () Цикл
Если XML . ТипУзла = ТипУзлаXML . НачалоЭлемента И XML . Имя = "Ресторан" Тогда
Название = XML . ЗначениеАтрибута ( "Название" );
Если Название <> Неопределено Тогда
Сообщить ( "Название ресторана:" + Название );
КонецЕсли;
Категория = XML . ЗначениеАтрибута ( "Категория" );
Если Категория <> Неопределено Тогда
Сообщить ( ". наценочная категория ресторана: " + Категория );
КонецЕсли;
Счет = XML . ЗначениеАтрибута ( "Счет" );
Если Счет <> Неопределено Тогда
Сообщить ( ". средний счет ресторана: " + Счет );
КонецЕсли;
Кухня = XML . ЗначениеАтрибута ( "Кухня" );
Если Кухня <> Неопределено Тогда
Сообщить ( ". кухня ресторана: " + Кухня );
КонецЕсли;
Пока XML . Прочитать () Цикл //
Если XML . ТипУзла = ТипУзлаXML . НачалоЭлемента И XML . Имя = "Меню" Тогда
Сообщить ( "Меню:" );
Пока XML . Прочитать () Цикл //
Если XML . ТипУзла = ТипУзлаXML . НачалоЭлемента И XML . Имя = "Блюдо" Тогда
Название = XML . ЗначениеАтрибута ( "Название" );
Если Название <> Неопределено Тогда
Сообщить ( ". название блюда:" + Название );
КонецЕсли;
ИначеЕсли XML . ТипУзла = ТипУзлаXML . КонецЭлемента И XML . Имя = "Меню" Тогда
Прервать;
КонецЕсли;
КонецЦикла; //
ИначеЕсли XML . ТипУзла = ТипУзлаXML . НачалоЭлемента И XML . Имя = "Описание" Тогда
XML . Прочитать ();
Если XML . ТипУзла = ТипУзлаXML . Текст Тогда
Сообщить ( "Описание:" + XML . Значение );
КонецЕсли;
ИначеЕсли XML . ТипУзла = ТипУзлаXML . КонецЭлемента И XML . Имя = "Ресторан" Тогда
//Подходит для файлов более 100Mb
&НаСервере
Процедура ПрочитатьФайлXMLПоПорядкуСпособ2 ( ПутьКФайлу )
XML = Новый ЧтениеXML ;
XML . ОткрытьФайл ( ПутьКФайлу );
СписокИмен = Новый СписокЗначений ;
Пока XML . Прочитать () Цикл
Если XML . ТипУзла = ТипУзлаXML . НачалоЭлемента Тогда
СписокИмен . Добавить ( XML . Имя );
ПутьXML = СобратьПуть ( СписокИмен );
Если ПутьXML = "/Рестораны/Ресторан" Тогда
Название = XML . ЗначениеАтрибута ( "Название" );
Если Название <> Неопределено Тогда
Сообщить ( "Название ресторана: " + Название ); //"Китайская грамота"
КонецЕсли;
Категория = XML . ЗначениеАтрибута ( "Категория" );
Если Категория <> Неопределено Тогда
Сообщить ( ". наценочная категория ресторана: " + Категория ); // Высшая
КонецЕсли;
Счет = XML . ЗначениеАтрибута ( "Счет" );
Если Счет <> Неопределено Тогда
Сообщить ( ". средний счет ресторана: " + Счет ); // 3500
КонецЕсли;
Кухня = XML . ЗначениеАтрибута ( "Кухня" );
Если Кухня <> Неопределено Тогда
Сообщить ( ". кухня ресторана: " + Кухня ); // Азиатская
КонецЕсли;
ИначеЕсли ПутьXML = "/Рестораны/Ресторан/Меню" Тогда
ИначеЕсли ПутьXML = "/Рестораны/Ресторан/Меню/Блюдо" Тогда
Название = XML . ЗначениеАтрибута ( "Название" );
Если Название <> Неопределено Тогда
Сообщить ( ". название блюда: " + Название );
КонецЕсли;
ИначеЕсли ПутьXML = "/Рестораны/Ресторан/Описание" Тогда
XML . Прочитать ();
Если XML . ТипУзла = ТипУзлаXML . Текст Тогда
Сообщить ( "Описание: " + XML . Значение );
КонецЕсли;
ИначеЕсли XML . ТипУзла = ТипУзлаXML . КонецЭлемента Тогда
СписокИмен . Удалить ( СписокИмен . Количество () - 1 );
&НаСервере
Функция СобратьПуть ( СписокИмен )
Для Каждого Имя Из СписокИмен Цикл
НашПуть = НашПуть + "/" + Имя ;
КонецЦикла;
//Подходит для файлов менее 100Mb, для больших Не подходит
&НаСервере
Процедура ПрочитатьФайлXMLЧерезDOMСпособ3 ( ПутьКФайлу )
//Поочередная обработка всех узлов документа, представленных в XML:
//1.Объявление механизмов, с помощью которых происходит чтение XML файла; Цикл для обхода узлов;
//2.Считывание данных и атрибутов в узле;
//3.Вывод информации. Если есть необходимость, на этом этапе может происходить запись в переменные или сразу в нужные таблицы;
//4.Завершение работы механизма
ЧтениеXML = Новый ЧтениеXML ;
ЧтениеXML . ОткрытьФайл ( ПутьКФайлу );
Построитель_DOM = Новый ПостроительDOM ;
ДокументXML = Построитель_DOM . Прочитать ( ЧтениеXML );
Для Каждого ТекУзел Из ДокументXML . ЭлементДокумента . ДочерниеУзлы Цикл
Если ТекУзел . ИмяУзла = "Ресторан" Тогда
Название = Ресторан . Атрибуты . ПолучитьИменованныйЭлемент ( "Название" );
Если Название <> Неопределено Тогда
Сообщить ( "Название ресторана:" + Название . Значение ); //"Китайская грамота"
КонецЕсли;
Категория = Ресторан . Атрибуты . ПолучитьИменованныйЭлемент ( "Категория" );
Если Категория <> Неопределено Тогда
Сообщить ( ". наценочная категория ресторана: " + Категория . Значение ); // Высшая
КонецЕсли;
СрСчет = Ресторан . Атрибуты . ПолучитьИменованныйЭлемент ( "Счет" );
Если СрСчет <> Неопределено Тогда
Сообщить ( ". средний счет ресторана: " + СрСчет . Значение ); // 3500
КонецЕсли;
Кухня = Ресторан . Атрибуты . ПолучитьИменованныйЭлемент ( "Кухня" );
Если Кухня <> Неопределено Тогда
Сообщить ( ". кухня ресторана: " + Кухня . Значение ); // Азиатская
КонецЕсли;
Для Каждого ТекУзел1 Из Ресторан . ДочерниеУзлы Цикл
Если ТекУзел1 . ИмяУзла = "Меню" Тогда
Меню = ТекУзел1 ;
Сообщить ( "Меню:" );
Для Каждого ТекУзел2 Из Меню . ДочерниеУзлы Цикл
Если ТекУзел2 . ИмяУзла = "блюдо" Тогда
Блюдо = ТекУзел2 ;
Название = Блюдо . Атрибуты . ПолучитьИменованныйЭлемент ( "Название" );
Если Название <> Неопределено Тогда
Сообщить ( ". название блюда:" + Название . Значение );
КонецЕсли;
ИначеЕсли ТекУзел1 . ИмяУзла = "Описание" Тогда
Сообщить ( "Описание :" + ТекУзел1 . ТекстовоеСодержимое );
&НаКлиенте
Процедура ЗаписатьДанныеВФорматеXML ( ПутьКФайлу )
Рестораны = СоздатьДанныеДляЗаписиВXML ();
ПараметрыЗаписи = Новый ПараметрыЗаписиXML ( "UTF-8" , "1.0" , Ложь); //необязательно их прописовать
XML = Новый ЗаписьXML ;
XML . ОткрытьФайл ( ПутьКФайлу , ПараметрыЗаписи );
XML . ЗаписатьОбъявлениеXML ();
XML . ЗаписатьНачалоЭлемента ( "Рестораны" );
Для Каждого Ресторан Из Рестораны Цикл
XML . ЗаписатьНачалоЭлемента ( "Ресторан" );
XML . ЗаписатьАтрибут ( "Название" , Ресторан . Значение . Название );
XML . ЗаписатьАтрибут ( "Категория" , Ресторан . Значение . Категория );
XML . ЗаписатьАтрибут ( "Счет" , Ресторан . Значение . Счет );
XML . ЗаписатьАтрибут ( "Кухня" , Ресторан . Значение . Кухня );
XML . ЗаписатьНачалоЭлемента ( "Меню" );
Для Каждого БлюдоИзМеню Из Ресторан . Значение . Меню Цикл
XML . ЗаписатьНачалоЭлемента ( "Блюдо" );
XML . ЗаписатьАтрибут ( "Название" , БлюдоИзМеню . Значение . Название );
XML . ЗаписатьКонецЭлемента (); // Блюдо
XML . ЗаписатьКонецЭлемента (); // Меню
XML . ЗаписатьНачалоЭлемента ( "Описание" );
XML . ЗаписатьТекст ( Ресторан . Значение . Описание );
XML . ЗаписатьКонецЭлемента (); // Описание
XML . ЗаписатьКонецЭлемента (); // Ресторан
XML . ЗаписатьКонецЭлемента (); // Рестораны
&НаКлиенте
Функция СоздатьДанныеДляЗаписиВXML ()
Рестораны = Новый СписокЗначений ;
Китайский_ресторан = Новый Структура ( "Название, Категория, Счет, Кухня, Меню, Описание" );
Китайский_ресторан . Название = "Китайская грамота" ;
Китайский_ресторан . Категория = "Высшая" ; //наценочная категория
Китайский_ресторан . Счет = "3500" ; //средний счет
Китайский_ресторан . Кухня = "Азиатская" ;
Китайский_ресторан . Меню = Новый СписокЗначений ;
Китайский_ресторан . Меню . Добавить (Новый Структура ( "Название" , "Суши из форели" ));
Китайский_ресторан . Меню . Добавить (Новый Структура ( "Название" , "Лапша фирменная" ));
Китайский_ресторан . Меню . Добавить (Новый Структура ( "Название" , "Суп из малюсков" ));
Китайский_ресторан . Описание = "Ресторан азиатской кухни Высшей наценочной категории" ;
Рестораны . Добавить ( Китайский_ресторан );
Европейский_ресторан = Новый Структура ( "Название, Категория, Счет, Кухня, Меню, Описание" );
Европейский_ресторан . Название = "Итальянский Экспресс" ;
Европейский_ресторан . Категория = "Люкс" ; //наценочная категория
Европейский_ресторан . Счет = "5000" ; //средний счет
Европейский_ресторан . Кухня = "Европейская" ;
Европейский_ресторан . Меню = Новый СписокЗначений ;
Европейский_ресторан . Меню . Добавить (Новый Структура ( "Название" , "Мясная нарезка из мраморной говядины" ));
Европейский_ресторан . Меню . Добавить (Новый Структура ( "Название" , "Салат де-люкс Комплимент" ));
Европейский_ресторан . Меню . Добавить (Новый Структура ( "Название" , "Пицца от шеф повара" ));
Европейский_ресторан . Описание = "Ресторан европейской кухни категории Люкс" ;
Рестораны . Добавить ( Европейский_ресторан );
Читайте также: