INFOSTART EVENT 2018 EDUCATION

Второй тур голосования за доклады.
Окончание 5 сентября.

Макаров Дмитрий | Руководитель проектного отдела | ООО "Информационные Технологии"

«Poka-yoke. Оператор производственной линии - пользователь 1С, кто сказал что 1С только для финансов»

Опыт автоматизации непосредственно на производственной линии или складе. В докладе поделимся опытом разработки и запуска Poka-yoke систем. 1. Что такое Poka-yoke системы и зачем они нужны. Как меняется работа на предприятии при внедрении подобных систем. 2. Почему используем 1С. 2. Чем отличается запуск системы классического учета от Poka-yoke систем. 3. "Подводные камни". На что необходимо обратить внимание при проектировании/внедрении и чем грозят ошибки, примеры из опыта. 4. Возможности интеграции. Arduino, Мобильный клиент 1С, MobileLogistics, технология штрих кодирования. Как все это применить для своего проекта, как связать "кучу" оборудования и тех. процессов в единую систему, какие проблемы встречаются, какие плюсы для предприятия - об этом мой доклад.

Заполнение справочника с изображениями элементами по умолчанию

Программирование - Практика программирования

1
Пример одного из решений, как можно заполнить справочник с изображениями значениями по умолчанию включая сами изображения. Сами изображения взяты из программы MapSource 6.16.3. Данные для загрузки хранятся в макете в формате XML.

Добрый день, коллеги.

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

На начальном этапе мы имеем список данных изображений вида:

Outdoor;Улица
1.Trail Head;Начало тропы
2.Bike Trail;Велосипедная дорожка
3.Skiing Area;Лыжная зона
4.Swimming Area;Зона купания
5.Ski Resort;Лыжный курорт
6.Ice Skating;Каток
7.Golf Course;Поле для гольфа
8.Ball Park;Футбольне поле
9.Scenic Area;Живописная местность
10.Picnic Area;Место для пикников
11.Park;Парк
12.Forest;Лес
13.Summit;Вершина
14.Campground;Кэмпинг
15.Lodge;Охотничий домик
16.RV Park;Кемпинг
17.Shower;Душевая
18.Drinking Water;Питевая вода
19.Geocache;Тайник
20.Multi-Cache;Несколько тайников
21.Letterbox Cache;Тайник почтовый щик
22.Puzzle Cache;Тайник-загадка
23.Geocache Found;Тайник найден
24.Truck;Грузовик
25.ATV;Вездеход
26.Cemetery;Кладбище
27.Ghost Town;Город без жителей
28.TracBack Point;Точка обратного отсчета

Hunting;Преследование
1.Hunting Area;Охотничьи угодья
2.Blind;Вслепую
3.Tree Stand;Древесное насаждения
4.Cover;Укрытие
5.Food Source;Источник пищи
6.Water Source;Источник воды
.....

Тут у нас есть группы изображений и потом пронумерованные изображения, которые входят в саму группу. Наименования у нас на двух языках: русский и английский.

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

Создавать предопределенные элементы в справочнике, загружать картинки, копирую по 100 раз наименования - не наш путь.

Было принято решение: делаем макет предопределенных значений и из него грузим все элементы с группами.

Таким образом решение задачи было разбито на 2 части:

1) Формирование макета XML с данными, в том числе картинками в виде двоичных данных.

2) написание механизма загрузки предопределенных значений из макета.

Для работы с XML и создания пакета данных было решено использовать пакеты XDTO. Для нашего случая был разработан следующий пакет:

<xs:schema xmlns:tns="http://www.MapsImage.Kim" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.MapsImage.Kim" attributeFormDefault="unqualified" elementFormDefault="qualified">
	<xs:element name="Images" type="tns:ImagesType"/>
	<xs:complexType name="ImageGroupType">
		<xs:sequence>
			<xs:element name="Image" type="tns:ImageType" maxOccurs="unbounded"/>
			<xs:element name="NameEnglish" type="xs:string"/>
			<xs:element name="NameRussian" type="xs:string"/>
		</xs:sequence>
	</xs:complexType>
	<xs:complexType name="ImageType">
		<xs:sequence>
			<xs:element name="NameEnglish" type="xs:string"/>
			<xs:element name="NameRussian" type="xs:string"/>
			<xs:element name="binImage" type="xs:base64Binary" nillable="true"/>
			<xs:element name="fileNameImage" type="xs:string" nillable="true"/>
		</xs:sequence>
	</xs:complexType>
	<xs:complexType name="ImagesType">
		<xs:sequence>
			<xs:element name="ImageGroup" type="tns:ImageGroupType" maxOccurs="unbounded"/>
		</xs:sequence>
	</xs:complexType>
</xs:schema>

Для формирования нашего XML разработал простую обработку:

Мы указывали файл txt в котором лежит список всех изображений, указали путь к папке с изображениями. С этими данными мы и будем работать.

Рассмотрим самые интересные моменты. В первую очередь мы разбираем файл .txt на составляющие и сохраняем прочитанные значения в массив структур. По факту мы повторяем дерево, которое будет грузится в объект XDTO и потом выгружаться в XML. Пришлось делать так, потому что наш добавленный пакет XDTO не доступен на клиенте и доступен только на сервере. В итоге начальная функция разбора входящих данных выглядит так:

&НаКлиенте
Процедура СоздатьXML(Команда)
	Если ФайлTXT = "" ИЛИ ПапкаИзображений = "" Тогда
		Возврат;
	КонецЕсли;
	Файл = Новый ЧтениеТекста(ФайлTXT,КодировкаТекста.UTF8);
	ТекстФайла = Файл.Прочитать();
	Файл.Закрыть();
	
	МассивПодстрок = СтрРазделить(ТекстФайла,Символы.ПС,Ложь);
		
	СтрокаЦифр = "0123456789";
	МассивГрупп = Новый Массив;
	СтруктураГруппы = НЕОПРЕДЕЛЕНО;
			
	Для Каждого СтрМассива ИЗ МассивПодстрок Цикл
		ПервыйСимвол = Лев(СтрМассива,1);
		Если Найти(СтрокаЦифр,ПервыйСимвол) = 0 Тогда
			//Это группа
			СтруктураГруппы = ПолучитьСтруктуруДанных(Истина);
			РазобратьСтрокуНаИмена(СтрМассива,СтруктураГруппы,Истина);
			
			МассивГрупп.Добавить(СтруктураГруппы);
		Иначе
			//Это элемент
			СтруктураИзображения = ПолучитьСтруктуруДанных();
			РазобратьСтрокуНаИмена(СтрМассива,СтруктураИзображения);
			
			СтруктураГруппы["Image"].Добавить(СтруктураИзображения);
			
	//		Картинка = ПолучитьИмяФайлаИзображения(МассивФайлов,СтруктураИзображения["fileNameImage"]);
		КонецЕсли;
	КонецЦикла;
	
	СтрукутраПараметров = Новый Структура;
	СтрукутраПараметров.Вставить("МассивГрупп",МассивГрупп);
	
	ОписаниеОповещения = Новый ОписаниеОповещения("ЗавершениеПоискФайлов",ЭтотОбъект,СтрукутраПараметров);
	
	НачатьПоискФайлов(ОписаниеОповещения,ПапкаИзображений,"*",Истина);
	
КонецПроцедуры

Функция "ПолучитьСтруктуруДанных" возвращают структуру нужного, а "РазобратьСтрокуНаИмена" работает со строкой, преобразуя ее и заполняя данные структуры. Они просты в реализации и не представляют большого интереса.

На этом этапе мы получили массив структур групп изображений и самих изображений. Теперь нам надо подтянуть к каждому изображению конкретно само изображение (в виде двоичных данных) и имена файлов. У меня данная база работает наплатформе версии 8.3.10.2580 и по умолчанию отключено использование модальных окон. Воспользуемся асинхронной функцией поиска файлов "НачатьПоискФайлов".

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

&НаКлиенте
Процедура ЗавершениеПоискФайлов (Результат, ДополнительныеПараметры) ЭКСПОРТ
	Если Результат = НЕОПРЕДЕЛЕНО Тогда
		Возврат;
	КонецЕсли;
	МассивГрупп = ДополнительныеПараметры.МассивГрупп;
	Для Каждого СтрГруппы ИЗ МассивГрупп Цикл
		Для Каждого СтрИзображения ИЗ СтрГруппы["Image"] Цикл
			Картинка = ПолучитьИмяФайлаИзображения(Результат,СтрИзображения["fileNameImage"]);
			Если Картинка = НЕОПРЕДЕЛЕНО Тогда
				Продолжить;
			КонецЕсли;
			
			СтрИзображения["binImage"] = Новый ДвоичныеДанные(Картинка.ПолноеИмя);
			СтрИзображения["fileNameImage"] = СтрИзображения["fileNameImage"] + Картинка.Расширение;
		КонецЦикла;
	КонецЦикла;
	
	ТекстXML = ПолучитьОбъектXDTOПоПространствуИмен(МассивГрупп);
КонецПроцедуры

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

&НаСервереБезКонтекста
Функция ПолучитьОбъектXDTOПоПространствуИмен (МассивГрупп)
	ПространствоИмен = "http://www.MapsImage.Kim";
	КорневоеСвойство = "Images";
	ОбъектИзображений = ФабрикаXDTO.Создать(ФабрикаXDTO.Пакеты.Получить(ПространствоИмен).КорневыеСвойства.Получить(КорневоеСвойство).Тип);
	
	Для Каждого СтрМассива ИЗ МассивГрупп Цикл
		ГруппаИзображений = ОбъектИзображений.ImageGroup.Добавить(ФабрикаXDTO.Создать(ФабрикаXDTO.Тип(ПространствоИмен,"ImageGroupType")));
		ЗаполнитьЗначенияСвойств(ГруппаИзображений,СтрМассива,"NameEnglish,NameRussian");
		Для Каждого СтрМассиваИзображения ИЗ СтрМассива["Image"] Цикл
			Если СтрМассиваИзображения.binImage = НЕОПРЕДЕЛЕНО Тогда
				Сообщить ("Нет изображения!! + " + СтрМассиваИзображения["NameEnglish"]);
			КонецЕсли;
			Изображение = ГруппаИзображений.Image.Добавить(ФабрикаXDTO.Создать(ФабрикаXDTO.Тип(ПространствоИмен,"ImageType")));
			ЗаполнитьЗначенияСвойств(Изображение,СтрМассиваИзображения,"NameEnglish,NameRussian,fileNameImage");
			Если СтрМассиваИзображения.binImage <> НЕОПРЕДЕЛЕНО Тогда
				Изображение["binImage"] = Base64Строка(СтрМассиваИзображения.binImage);
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла(".gpx");
	
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.ОткрытьФайл(ИмяВременногоФайла,"UTF-8");
	
	ЗаписьXML.ЗаписатьОбъявлениеXML();	
	
	ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, ОбъектИзображений, КорневоеСвойство,ПространствоИмен,,НазначениеТипаXML.Явное);
	
	ЗаписьXML.Закрыть();

	Файл = Новый ЧтениеТекста(ИмяВременногоФайла, КодировкаТекста.UTF8);
	ДанныеXML = Файл.Прочитать();

	Возврат ДанныеXML;
	
КонецФункции

По факту мы обходим ранее сформированную структуру и переносим ее в XDTO пакет.

На выходе (в форме обработки) получим текст вида:

<?xml version="1.0" encoding="UTF-8"?>
<Images xmlns="http://www.MapsImage.Kim" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ImagesType">
	<ImageGroup>
		<Image>
			<NameEnglish>Trail Head</NameEnglish>
			<NameRussian>Начало тропы</NameRussian>
			<binImage>iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAIAAABvFaqvAAAFNElEQVR42q2Ve0xT
VxzH77n3tvTBbWtb+rAtSHlUYTBAqHMmytBNYerM3hvJ1KETH5s4l/iIcZs6o5vT
GLOIBKawuanzkbiJM1s0M06GTBxCZGB59mGhpbTYQh/33rNz2w5dsj89f9z8cs65
n/u939/v/A6AEGJPYgAEamlpqVy/zelJBNGBZnEcjwWxQdM0y7IEQaAY7UdxLAAM
UKnGa776zGw2c6CCovm0pMZgMIjEOEviPAgwErE4ECQwNsza+i0YHZSp9GKhlImO
GC7gZxz9g6HRir7uWxxIbVyWkf99fq4QicBJGJOFAsRiWXinqWnpginGFOpmy+jA
0FS1QREJcVpoThbW0uoaaK9w2S5yIK1xaWbBqSyTiFshMRLHAA8LB+H4OIuEhMea
T31dglZ8Y+zbq/9KnZHPRDgKUoRwHZ3uvraVQ7af4qC0p09mZFJoNwEg4IFwkPUO
W7Rquq8HuWP/5UIpWnrgpFe8fzc5vQBGYARAPCrpbqfH1vFuHKRJXWLM/TbNKOXM
BxhfBFv/uFs2N7R7h7lqy+9T9ZLyl7O6LZ4r14dvd8r1yRr0azGPcIzt7B513Fv1
CKTPakgzSCEJUWoikUhvx/WTNbNmTE/s6Q2nGfnoA7X1XZ8fsc2ZPz80hqwGGEvH
cmfp9dq7Kobtl6JmT1usz2wwGChkMo9H9tzvnmceO7i3cMTLKmT4ZBG8sfL2BPaU
gE9GUNKYSAzU3+91Wt6LgzSGJVrTca2awkmW5Avampv37JCXv57ZP8BMSyEmQWcv
2D/cacufWQQBEh3BaG5y0OZx9a39V5F+sSq9VqOKFiRPaO1rN2ePmDIUFStyVUng
8fI9dKSr4YyVJ8iQyZWoStGM3erz2CpdjkYOpNK9qEg9ppTLIAFR9tHTZb1vSvec
qX+OR0a1/GgXJxClL2hQHKGxdZvu3GihVCoVqsyhIZ/Xse4RSK6vlsglSBBXRATP
4x5O0fSeaygWiTlFxWWNg9aEvBy4f09xhpE8Vmfddzig1qmRUy7XwzHnBveDy3EQ
pT1KURQgmChLYLf3zMrznK2fhxMcqP60de+XExAQBNt59GBR05/B2m8YiUSC/PZ6
vf7hD0acP3OgpKllwqQjiYmJseOKngM9zT8cz1+0UDfpTmHxNW8gXaOwHfg08+R5
z6Vf+SIBH/2a3+sf91bFQUptaYLisCCBq2xSQDrt1tl57sZzzyM57ff8OVncB747
71y+qqOslNq9PWvj1q5+m5YE0XMbCITHqjxDVziQQrMoQXoYJ8RY1Fq3tX3/Pv3G
NTkoznvmzCfb5ix7SefxQYXsxDuVubu25BSW3BKJ0wAdpCEIhf1MYHMcJFcv5FGH
WCAmSdLtceZNd/zWuBjZXF3bvWX73/Pmii6eXfDQj0mo2g1V2ZurzKmma6oUE2BC
qMQhO86Of/QIBIRfAJw7/QGvZc/H6s0b86PJunqzVaaTdvd1vYmyrk6uW16euWbV
s1m5N6bokwFkOP1w4j8gXHQAYgJUY0zQUn80+5VXjY2XrRXr7ROsMjh6LehbjV6Z
Oft0+Vum7OnJZa91yZSa/wMpFmLSQzjGRwmO+B0pyYOFecqm27TDqeMJqbCvbcNa
nUBEVle3lZRopVN0J07hQqEQgdB+CCcw3ybPSBSUU1Bic+8EpIpLP2TYMGpoYUBQ
OEgAOM3dDrQXdQUaI5mQHSdVJC8JAxG0mUHb6WG9cld769V486+o3GqzkZNVwzX2
x5p/7KZBM5PB5JJeT9dV7ysqKgJP6jr6B+fh0+/Kt4cZAAAAAElFTkSuQmCC</binImage>
			<fileNameImage>TrailHead.png</fileNameImage>
		</Image>
		<Image>
			<NameEnglish>Bike Trail</NameEnglish>
			<NameRussian>Велосипедная дорожка</NameRussian>
			<binImage>iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAIAAABvFaqvAAACAklEQVR42q2UMUtc
QRDH//O880wgnyCtVnYRLEISxBQBQQsJBGxCLAQNCrk010UsUlj4EQJJITY2Ymfl
VTYJWJmQFAEhnyBwp+c5zszue2/29BQOH8Pe8t7u7/4z898lZsZ9PBRARDQwIhLk
Ryi8CK4BFQvlymdQF7jQ4A7orBzRBrV1DPPsj7Ii6HIZVI0gHgJ9dvm+Jw+K+1vl
PPvpQasKCqIoA9ZLENdJJZyVEnTeinNVlIA+RBANm66GU/SRij0eV4iikxSEEaOM
....

На этом процесс генерации XML файла с данными завершен и мы переходить ко второй части задачи - загрузке данных в справочник.

Справочник будет иметь следующий вид:

Как мы видим, в справочник я добавил 2 макета.

Описание данных - это макет и с итоговой XML для загрузки.

Описание пакета - это XDS схема пакет XDTO. Мы будем загружать XML так же через пакет XDTO.

В форме списка справочника добавим команду загрузки. Выглядеть она будет так:

&НаСервереБезКонтекста
Процедура ЗагрузитьЗначенияПоУмолчаниюНаСервере()
	
	//Получим описание пакета
	ИмяФайла = ПолучитьИмяФайлаМакета("ОписаниеПакета");
			
	//Получим свою фабрику XDTO
	Фабрика = ПолучитьСвоюФабрикуXDTO(ИмяФайла);
	
	//Получим из макета данные XML и сохраним в файл
	ИмяФайлаДанных = ПолучитьИмяФайлаМакета("ОписаниеДанных");
		
	//Прочитаем данные из фабрики
	ОбъектИзображений = ПолучитьОбъектXDTOДанных(Фабрика,ИмяФайлаДанных);
	
	//Загрузим данные в справочник
	ЗагрузкаСпискаИзображений (ОбъектИзображений);
КонецПроцедуры

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

1) Получение своей фабрики XDTO

2) Получение объекта XDTO из XML

3) Разбор объекта XDTO

Для получения данных воспользуемся универсальной функцией, которая сохраняет данные из макета в файл и возвращает полный путь к этому файлу:

&НаСервереБезКонтекста
Функция ПолучитьИмяФайлаМакета (ИмяМакета)
	ИмяФайла = ПолучитьИмяВременногоФайла(".xml");
	
	МакетОписанияПакета = Справочники.ИзображенияMapSource.ПолучитьМакет(ИмяМакета);
	ТекстОписанияПакета = МакетОписанияПакета.ПолучитьТекст();
		
	ТекстовыйФайл = Новый ТекстовыйДокумент;
	ТекстовыйФайл.ДобавитьСтроку(ТекстОписанияПакета);
	ТекстовыйФайл.Записать(ИмяФайла,КодировкаТекста.UTF8);
	
	Возврат ИмяФайла
КонецФункции

Для получения своей фабрики воспользуемся следующим кодом (спасибо большое за понимание принципов работы с XDTO Андрею Овсянкину и его циклу статей про XDTO)

&НаСервереБезКонтекста
Функция ПолучитьСвоюФабрикуXDTO(ИмяФайлаОписанияПакета)
	Чтение = Новый ЧтениеXML;
	Чтение.ОткрытьФайл(ИмяФайлаОписанияПакета);

	ПостроительDOM = Новый ПостроительDOM;
	Документ = ПостроительDOM.Прочитать(Чтение);
	ПостроительСхем = Новый ПостроительСхемXML;

	Схема = ПостроительСхем.СоздатьСхемуXML(Документ.ЭлементДокумента);

	НаборСхем = Новый НаборСхемXML;
	НаборСхем.Добавить(Схема);
	Фабрика = Новый ФабрикаXDTO(НаборСхем);
	
	Возврат Фабрика;
КонецФункции

С помощью нашей фабрики мы и прочитывали объект XDTO и уже исходя из объекта формируем элементы справочника.

Для получения объекта XDTO с помощью нашей созданной фабрики используется функция:

&НаСервереБезКонтекста
Функция ПолучитьОбъектXDTOДанных(Фабрика,ИмяФайлаДанных)
	ЧтениеXMLДанных = Новый ЧтениеXML;
	ЧтениеXMLДанных.ОткрытьФайл(ИмяФайлаДанных);
	
	ОбъектModel = Фабрика.ПрочитатьXML(ЧтениеXMLДанных);
	
	Возврат ОбъектModel;
КонецФункции

Создаем элементы, на основании объекта XDTO в следующем коде:

&НаСервереБезКонтекста
Процедура ЗагрузкаСпискаИзображений (ОбъектИзображений)
	ШаблонПоиска = "Custom";
	Для Каждого СтрГруппы ИЗ ОбъектИзображений.ImageGroup Цикл
		ГруппаИзображения = Справочники.ИзображенияMapSource.СоздатьГруппу();
		ГруппаИзображения.Наименование = СтрГруппы["NameRussian"];
		ГруппаИзображения.НаименованиеАнглийское = СтрГруппы["NameEnglish"];
		ГруппаИзображения.ЗначениеПоУмолчанию = Истина;
		ГруппаИзображения.Записать();
		
		СсылкаНаГруппу = ГруппаИзображения.Ссылка;
				
		Для Каждого СтрИзображения ИЗ СтрГруппы.Image Цикл
			Изображение = Справочники.ИзображенияMapSource.СоздатьЭлемент();
			Изображение.Наименование = СтрИзображения["NameRussian"];
			Изображение.НаименованиеАнглийское = СтрИзображения["NameEnglish"];
			Изображение.ЗначениеПоУмолчанию = Истина;
			Изображение.ИмяФайла = СтрИзображения["fileNameImage"];
			Если Найти(Изображение.ИмяФайла,ШаблонПоиска) Тогда
				Изображение.ИмяФайла = ПолучитьНовоеИмяФайла(СтрИзображения["fileNameImage"],ШаблонПоиска);
			КонецЕсли;
			ДвоичныеДанныеИзображения = СтрИзображения["binImage"];
			Изображение.ДанныеФайла = Новый ХранилищеЗначения(ДвоичныеДанныеИзображения,Новый СжатиеДанных(9));
			Изображение.Родитель = СсылкаНаГруппу;
			Изображение.Записать();
		КонецЦикла;
		
		
	КонецЦикла;
КонецПроцедуры

В итоге мы получаем то, что нам и требовалось:

Прикрепил архив с конфигурацией, с описанными объектами, изображениями и текстовым файлом, а так же отдельно изображения - вдруг кому-нибудь понадобятся

1

Скачать файлы

Наименование Файл Версия Размер
Демо конфигурация (с файлами для загрузки)
.rar 332,90Kb
28.03.18
1
.rar 1.0.1 332,90Kb 1 Скачать
Изображения
.rar 160,80Kb
26.03.18
1
.rar 1.1.1 160,80Kb 1 Скачать

См. также

Сортировка: Древо
В этой теме еще нет сообщений.
Оставьте свое сообщение