Имя: Пароль:
1C
1С v8
Создание Установка цен номенклатуры из XML файла
0 slavabatov
 
28.08.17
02:28
Здравствуйте.
Необходимо создать и записать документ Установка цен номенклатуры
из XML файла
Фрагмент файла XML
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!--13714 8/7/2017 12:16:33 PM-->
<data>
<tires>
<cae>PXR0033103</cae>
<price_sk3>11029</price_sk3>
<price_sk3_rozn>12350</price_sk3_rozn>
<name>245/40R17 91S Blizzak VRX</name>
<tiretype>Легковая</tiretype>

Bridgestone</brand>
<model>Blizzak VRX</model>
<width>245</width>
<height>40</height>
<diameter>R17</diameter>
<diametr_out>0</diametr_out>
<design>R</design>
<speed_index>S</speed_index>
<load_index>91</load_index>
<season>Зимняя</season>
</tires>
<tires>
<cae>NW00102</cae>
<price_sk3>6569</price_sk3>
<price_sk3_rozn>7355</price_sk3_rozn>
<name>265/60R18 114T Therma Spike TL (шип.)</name>
<tiretype>Легковая</tiretype>

Nitto</brand>
<model>Therma Spike</model>
<width>265</width>
<height>60</height>
<diameter>R18</diameter>
<diametr_out>0</diametr_out>
<design>R</design>
<speed_index>T</speed_index>
<load_index>114</load_index>
<thorn>Да</thorn>
<season>Зимняя</season>
</tires>
<tires>
<cae>100A1574</cae>
<price_sk3>4510</price_sk3>
<price_sk3_rozn>5002</price_sk3_rozn>
<name>225/50R16 96W Champiro UHP1</name>
<tiretype>Легковая</tiretype>

GT Radial</brand>
<model>Champiro UHP1</model>
<width>225</width>
<height>50</height>
<diameter>R16</diameter>
<diametr_out>0</diametr_out>
<design>R</design>
<speed_index>W</speed_index>
<load_index>96</load_index>
<season>Летняя</season>
</tires>
<camera>
<cae>125603</cae>
<price_mkrs>271</price_mkrs>

Michelin</brand>
<name>Michelin Chambre Scooter</name>
</camera>
<camera>
<cae>733003</cae>
<price_mkrs>244</price_mkrs>

Michelin</brand>
<name>Michelin Chambre Scooter</name>
</camera>
<camera>
<cae>788345</cae>
<price_mkrs>261</price_mkrs>

Michelin</brand>
<name>Michelin Chambre Road</name>
</camera>
<rims>
<cae>WHS140401</cae>
<price_sk3>6678</price_sk3>
<price_sk3_rozn>7528</price_sk3_rozn>
<name>8x19/5x120 ET30 D72,6 MODEL-58 B+R</name>
Читаю файл так
Процедура КнопкаВыполнитьНажатие(Кнопка)
    
    ЧтениеXML = Новый ЧтениеXML;
    ЧтениеXML.ОткрытьФайл("F:\OLD_DISK_C\1C\M13714small.xml");
    Имя = ЧтениеXML.Имя;
    Массив = Новый Структура(Имя);                                                    
    Пока ЧтениеXML.Прочитать() Цикл                  
        ПолучитьXMLТип(ЧтениеXML);
        Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента  Тогда
                        
            Имя = ЧтениеXML.Имя;
            
            Сообщить("Начало " + ЧтениеXML.Имя);
            Пока ЧтениеXML.ПрочитатьАтрибут() Цикл
                Атрибут = ЧтениеXML.Значение;
                Сообщить("атрибут:" + ЧтениеXML.Имя + "=" + ЧтениеXML.Значение);
            КонецЦикла;
        КонецЕсли;
        
        Если ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
            Массив.Вставить(Имя,ЧтениеXML.Значение);
            Сообщить(ЧтениеXML.Значение);
        КонецЕсли;
    
        Если ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
            Если ЧтениеXML.Имя = "data" Тогда
            ДобавитьЭлемент(Массив);
            КонецЕсли;
            Сообщить("Конец " + ЧтениеXML.Имя);
        КонецЕсли;
    КонецЦикла;
    КонецПроцедуры
Читает, но когда переходит к созданию Документа
Процедура СоздатьДокУстЦен(Массив)
    
    Документ = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
    Документ.Дата = ТекущаяДата();
    Документ.Ответственный = Пользователи.ТекущийПользователь();
        Для Каждого СтрокаДанных Из Массив Цикл
        артикул = СтрокаДанных.cae;
        НоваяСтрока = Документ.Товары.Добавить();
        НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоРеквизиту("артикул",артикул);
        НоваяСтрока.ТипЦен      = Справочники.ТипыЦенНоменклатуры.НайтиПоКоду("000000002");
        НоваяСтрока.Цена         = Массив.price;
        Документ.Товары.Свернуть("Номенклатура, ТипЦен, Цена");
           КонецЦикла;
    Документ.Записать();    
    
КонецПроцедуры
Получаю "Поле объекта не обнаружено (cae)". Хотя это реквизит из файла, и читается он первой частью правильно. Что я упускаю?
1 Fram
 
28.08.17
03:49
Может сначала лучше у отладчика спросить?
2 Fram
 
28.08.17
03:52
Читай с помощью ДОМ лучше. Будет меньше кода и понятнее
3 slavabatov
 
28.08.17
13:31
Процедура КнопкаВыполнитьНажатие(Кнопка)
    
    ЧтениеXML = Новый ЧтениеXML;
    ЧтениеXML.ОткрытьФайл("F:\OLD_DISK_C\1C\M13714small.xml");
    ПостроительDOM = Новый ПостроительDOM;
    ДомументDOM = ПостроительDOM.Прочитать(ЧтениеXML);
    ТекстУзла = ЧтениеXML.Значение;
    
    //
    
    РезультатРазборки = Новый Массив;
    
    Для Каждого ЭлементУстановкаЦенНоменклатуры Из  ДомументDOM.ЭлементДокумента.ДочерниеУзлы Цикл
        Если НЕ (ЭлементУстановкаЦенНоменклатуры.ТипУзла = ТипУзлаDOM.Элемент И ЭлементУстановкаЦенНоменклатуры.ИмяУзла = "data") Тогда
            Продолжить;
        КонецЕсли;
        
        ДокументУстановкаЦенНоменклатуры = Новый Структура ("data");
        
        Для Каждого ЭлементРеквизит Из ЭлементУстановкаЦенНоменклатуры.ДочерниеУзлы Цикл
            Если ЭлементРеквизит.ТипУзла <> ТипУзлаDOM.Элемент Тогда
                Продолжить;
            КонецЕсли;
            
            Если ЭлементРеквизит.ИмяУзла = "data" Тогда
                ДокументУстановкаЦенНоменклатуры.data = Новый Массив;
                Для Каждого Строкаdata Из ЭлементРеквизит.ДочерниеУзлы Цикл
                    Если Строкаdata.ТипУзла <> ТипУзлаDOM.Элемент Тогда
                        Продолжить;
                    КонецЕсли;
                    
            СтрокаdataСтруктура = Новый Структура("cae, price_sk3, name");
            Для Каждого СтрокаdataРеквизиты Из Строкаdata.ДочерниеУзлы Цикл
                Если СтрокаdataРеквизиты.ТипУзла <> ТипУзлаDOM.Элемент Тогда
                Продолжить;
            КонецЕсли;
            
            Если СтрокаdataРеквизиты.ИмяУзла = "name" Тогда
                СтрокаdataСтруктура.Номенклатура = ТекстУзла(СтрокаdataРеквизиты);
            ИначеЕсли СтрокаdataРеквизиты.ИмяУзла = "price_sk3" Тогда
                СтрокаdataСтруктура.Цена = XMLЗначение(Тип("Число"),ТекстУзла(СтрокаdataРеквизиты));
            КонецЕсли;
        КонецЦикла;
        ДокументУстановкаЦенНоменклатуры.data.Добавить(СтрокаdataСтруктура);
    КонецЦикла;
    
КонецЕсли;
КонецЦикла;
    РезультатРазборки.Добавить(ДокументУстановкаЦенНоменклатуры);
    
КонецЦикла;
    Тест = РезультатРазборки;
    
КонецПроцедуры

И как оказалось, что я брал за пример, это для УФ, как адаптировать под Обычное?
4 Лефмихалыч
 
28.08.17
13:52
(3) это будет работать в режиме обычного приложения как есть, без каких-либо изменений.
А вот в управляемом - только на сервере.
5 slavabatov
 
28.08.17
14:02
(4) В том виде требует создание Процедуры или Функции ТекстУзла. Если создаёшь процедуру то говорит нельзя к ней обращаться в Обычном приложении, с Функцией всё без ошибок, но я вообще не понимаю, чем её наполнять, вроде и так всё прописал. И вообще я стал метаться от варианта 1 к варианту 2 и уже в этой каше начал тупить ещё сильнее.
Вариант 1
Процедура СоздатьДокУстЦен(Массив)
    
    Документ = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
    Документ.Дата = ТекущаяДата();
    Документ.Ответственный = Пользователи.ТекущийПользователь();
    строкацена = Документ.Товары.Добавить();
    строкацена.ТипЦен = Справочники.ТипыЦенНоменклатуры.НайтиПоНаименованию("Оптовая");
    артикул = Массив.cae;
    Для Каждого СтрокаДанных Из Массив Цикл
        НоваяСтрока = Документ.Товары.Добавить();
        НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоРеквизиту("артикул",артикул);
        НоваяСтрока.ТипЦен      = Справочники.ТипыЦенНоменклатуры.НайтиПоКоду("000000002");
        НоваяСтрока.Цена         = Массив.price_sk3;
        Документ.Товары.Свернуть("Номенклатура, ТипЦен, Цена");
        Документ.Товары.Свернуть("Номенклатура,,");
        Документ.Записать();
        
//        Отказ = Истина;
           КонецЦикла;
        
КонецПроцедуры
Создаёт документ, но почему то не заполняет его, хотя по отладчику видно, что Артикул получает.
6 rozer76
 
28.08.17
14:02
(0) вот читай универсально в дерево через dxto

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

&НаКлиенте
Процедура ПриВыбореФайла(Результат, ДопПараметры) Экспорт
    Если НЕ Результат = Неопределено Тогда
        Тхт = Новый ТекстовыйДокумент;
        тхт.Прочитать(Результат[0]);
        ПоместитьВДерево(тхт.ПолучитьТекст());
    КонецЕсли;
КонецПроцедуры

Процедура ПоместитьВДерево(Текст)
    Чтение = Новый ЧтениеXML;
    Чтение.УстановитьСтроку(Текст);
    Об = ФабрикаXDTO.ПрочитатьXML(Чтение);
    
    Строка = Дерево.ПолучитьЭлементы().Добавить();
    Строка.Узел = "Корневой узел";
    ПрочитатьУзел(Об, Строка);
КонецПроцедуры

Процедура ПрочитатьУзел(Об, лДерево)
    Если ТипЗнч(Об) = Тип("СписокXDTO") Тогда
        Для Каждого Ст ИЗ Об Цикл
            Строка = лДерево.ПолучитьЭлементы().Добавить();
            Строка.Узел = Об.ВладеющееСвойство;
            Если ТипЗнч(Ст) = Тип("СписокXDTO") ИЛИ ТипЗнч(Ст) = Тип("ОбъектXDTO") Тогда
                ПрочитатьУзел(Ст, Строка);
            Иначе
                Строка.Элемент = Ст;
            КонецЕсли;
        КонецЦикла;
    Иначе
        Для Каждого Ст ИЗ Об.Свойства() Цикл
            Строка = лДерево.ПолучитьЭлементы().Добавить();
            Строка.Узел = Ст.Имя;
            Если ТипЗнч(Об[Ст.Имя]) = Тип("СписокXDTO") ИЛИ ТипЗнч(Об[Ст.Имя]) = Тип("ОбъектXDTO") Тогда
                ПрочитатьУзел(Об[Ст.Имя], Строка);
            Иначе
                Строка.Элемент = Об[Ст.Имя];
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры
7 slavabatov
 
28.08.17
14:22
(6) Читать вариантов несколько, а вот как пометить в документ УстановкаЦен?
8 rozer76
 
28.08.17
15:39
(7) ну берем дерево из (6) и обходим и заполняем доки
9 Лефмихалыч
 
28.08.17
16:15
(5) функцию создай, а не процедуру
10 slavabatov
 
28.08.17
17:02
Процедура КнопкаВыполнитьНажатие(Кнопка)  
      
       ТипЦен = Справочники.ТипыЦенНоменклатуры.НайтиПоНаименованию("Оптовая");
//        ВидВалюты = Справочники.Валюты.НайтиПоНаименованию("руб.");
        ЕдиницаИзм = Справочники.ЕдиницыИзмерения.НайтиПоНаименованию("шт");
      
        ЧтениеXML = Новый ЧтениеXML;
        ЧтениеXML.ОткрытьФайл("F:\4P\M13714small.xml");
        Имя = ЧтениеXML.Имя;
        Массив = Новый Структура(Имя);

        Документ = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
        Документ.Дата = ТекущаяДата();
        Документ.Ответственный = Пользователи.ТекущийПользователь();
//        Документ.мВалютаУправленческогоУчета = Справочники.Валюты.НайтиПоНаименованию("руб.");
      
        строкатиповцен = Документ.ТипыЦен.Добавить();
        строкатиповцен.ТипЦен= ТипЦен;
                                                          
    Пока ЧтениеXML.Прочитать() Цикл                  
        ПолучитьXMLТип(ЧтениеXML);
        Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента  Тогда
                      
            Имя = ЧтениеXML.Имя;
          
            Пока ЧтениеXML.ПрочитатьАтрибут() Цикл
                Атрибут = ЧтениеXML.Значение;
            КонецЦикла;
        КонецЕсли;
      
        Если ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
            Массив.Вставить(Имя,ЧтениеXML.Значение);            
        КонецЕсли;
  
        Если ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
            Если ЧтениеXML.Имя = "data" Тогда
                Для Каждого Атрибут Из Массив Цикл
            Цена = Массив.price_sk3;
            Арт = Массив.cae;
                КонецЦикла;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;  
          
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    Номенклатура.Артикул,
        |    Номенклатура.Ссылка,
        |    Номенклатура.ЕдиницаХраненияОстатков КАК Ед,
        |    Номенклатура.ЕдиницаХраненияОстатков.Коэффициент КАК К
        |ИЗ
        |    Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |    Номенклатура.Артикул = &Артикул";

    Запрос.УстановитьПараметр("Артикул", Арт);

    Результат = Запрос.Выполнить();

    Если  НЕ Результат.Пустой() Тогда
    ВыборкаДетальныеЗаписи = Результат.Выбрать();

    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
      
        Строка = Номенклатура.Добавить();
        Строка.Артикул = Арт;
        Строка.Цена = Цена;

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

    строкацена.Цена = Строка.Цена;

КонецЦикла;
Иначе
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    Номенклатура.Наименование,
        |    Номенклатура.Ссылка,
        |    Номенклатура.ЕдиницаХраненияОстатков КАК Ед,
        |    Номенклатура.ЕдиницаХраненияОстатков.Коэффициент   КАК К
        |ИЗ
        |    Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |    Номенклатура.Наименование = &Наименование";

    Запрос.УстановитьПараметр("Наименование",);

    Результат = Запрос.Выполнить();

    ВыборкаДетальныеЗаписи = Результат.Выбрать();

    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        Строка = Номенклатура.Добавить();
        Строка.Артикул = Арт;
        Строка.Цена = Цена;

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

    КонецЦикла;

    КонецЕсли;  
                      
        Документ.ПолучитьФорму("ФормаДокумента").Открыть();      
  
КонецПроцедуры
Переделал всё вот так. Заполняет ТипЦен. Добавляет Номенклатуру, но не могу понять как правильно переделать Цикл, что бы попадала вся имеющаяся номенклатура.
11 Лефмихалыч
 
28.08.17
17:04
12 Fram
 
28.08.17
21:18
(10) слушай, харе уже методом тыка программировать. сделай одолжение себе, заказчику и нам - брось это. не только эту задачу, но и программирование в принципе
13 slavabatov
 
28.08.17
21:31
(12) очередной "ценный совет". сделай себе одолжение, не мучайся. в браузере, в верхней части этой страницы, есть "крестик", смотри не перепутай с буквой "х". нажми на него и твои страдания закончатся. снобизм не красит человека.
14 Fram
 
28.08.17
22:48
(13) согласен, немного резко получилось. сорри.
хотя, я вполне серьезно - ну, не твое это. отсутствует у тебя ген программирования. тут один товарищ выкладывал ссылку на логический тест. не поленись, пройди, и сразу станет понятно.
например, вот эти куски зачем?
...
Имя = ЧтениеXML.Имя;
Массив = Новый Структура(Имя);
...
ПолучитьXMLТип(ЧтениеXML);
...
Для Каждого Атрибут Из Массив Цикл
Цена = Массив.price_sk3;
Арт = Массив.cae;
КонецЦикла;
...
ты же не понимаешь что пишешь
15 Garykom
 
гуру
28.08.17
23:18
(14) Зачем понимать, некогда, деньгу зашибать надо!
16 slavabatov
 
29.08.17
01:25
(14) тест пройду, матчасть подтяну, с программированием завяжу)) (15) уважаемый, вот зачем эти не правильные умозаключения? как уже мной говорилось, я не 1с программист. это не заказ за деньги, это безвозмездная попытка помочь. запомните: "молчание - золото!"