Имя: Пароль:
1C
1С v8
Обработка Свойств номенклатуры
0 neGODnic
 
19.11.16
01:17
В общем досталась одна обработка. В 1с не силен. Помогите допилить до ума, буду премного благодарен. УТ 10,3. Вот код:

Процедура ЗаписатьСвойстваНоменлатуры(ТекущаяСтрокаТаблицы, ТекНом)
    // ПартНомер
    Если ЗначениеЗаполнено(КолонкаПартНомер) Тогда
        Если ЗначениеЗаполнено(ТекущаяСтрокаТаблицы[КолонкаПартНомер]) Тогда
            
            ЗначениеСвойства = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию(ТекущаяСтрокаТаблицы[КолонкаПартНомер]);
            Если ЗначениеСвойства.Пустая() Тогда
                НовЗначСв = Справочники.ЗначенияСвойствОбъектов.СоздатьЭлемент();
                НовЗначСв.Владелец = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Код производителя, MPN");    
                НовЗначСв.Наименование = ТекущаяСтрокаТаблицы[КолонкаПартНомер];
                НовЗначСв.Записать();
                ЗначениеСвойства = НовЗначСв.Ссылка;
            КонецЕсли;            
                                    
            Запись = НаборЗаписейЗначенияСвойств.Добавить();            
            Запись.Объект   = ТекНом;
            Запись.Свойство = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Код производителя, MPN");    
            Запись.Значение = ЗначениеСвойства;
            
        КонецЕсли;
    КонецЕсли;
    
    НаборЗаписейЗначенияСвойств.Отбор.Объект.Установить(ТекНом);
    Попытка
        НаборЗаписейЗначенияСвойств.Записать();
    Исключение
    КонецПопытки;
    
КонецПроцедуры

http://savepic.ru/12265563.jpg
Суть обработки...
Наименование колонки - загружает столбы из EXCEL
Назначение - куда эти данные пишем.
Данные из ПартНомер, должны загружаться в Свойство номенклатуры, которое называется "Код производителя, MPN" без кавычек.
В итоге ничего не пишется... Помогите решить вопрос. ОЧЕНЬ НУЖНО.

Задача из EXCEL выгружать различные данные - именно в свойства номенклатуры. Вес, объем, габариты и пр.
1 neGODnic
 
19.11.16
01:23
меня смущает, что это вроде в характеристики грузится, а не в свойства. Или я не прав?
2 Torquader
 
19.11.16
02:28
Херня здесь написана!
Справочник "ЗначенияСвойствОбъектов" используется, когда мы хотим, чтобы значение свойства было одним из перечисленных в списке значений.
В данном случае, они туда пихают код производителя - спрашивается - зачем.
Единственное, что будет при этом - это возможность искать по коду быстрее, чем полным перебором (не забываем, что регистр у нас без индексации по значениям).
Но, искать по наименованию нужно в подчинении нашему свойству, а то есть вероятность найти похожее значение в соседнем свойстве, после чего будет попытка записи в регист неуникального значения или установки свойства, которое не будет отображаться.

Если нужно выгружать свойства, то этот пример не для вас, так как вес в справочник никто не грузит.

Во-первых, мы должны в плане видов характеристик под наши свойства создать элементы.
Во-вторых, мы у этих элементов устанавливаем ограничение типа в число (вес, объём) или строка (габариты).

Далее, чтобы записать свойств в регистр нужно получить ссылку на элемент, к которому мы привязываемся, ссылку на свойство (которое там ищут как НайтиПоНаименованию) - лучше его найти при старте обработки, чтобы если его нет ничего и не начинать.
Если при записи поставить Замещать для замещения значений, то проверять наличие не придётся.

МенЗап=РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьМенеджерЗаписи();
МенЗап.Объект=ССылкаНаЭлемент;
МенЗап.Свойство=СсылкаНаСвойствоИзПВХ;
МенЗап.Значение=ВесКакЧисло;
МенЗап.Записать(ИСТИНА);
3 neGODnic
 
19.11.16
03:22
Все... криминальный ступор... В старой базе из архива, пол года ей, все работает, и выгружается.

В обновленной, нет.
Версия 1с, и версия базы одинаковые... что в старой версии, что в новой...
куда копать?
4 neGODnic
 
19.11.16
03:37
Доработки были, но какие я уже знать не могу. Обработка ни каких ошибок не выдает.
Что делать?
Могу скинуть дампы баз. если есть желание помочь в решении.
5 neGODnic
 
19.11.16
04:01
Методом проб и ошибок выяснил... что в обработке при создании новой позиции, создает поле свойство с правильных параметром, а вот если данная номенклатура уже есть. То не обновляет поле.
6 neGODnic
 
19.11.16
04:15
(2) Данная обработка работает, ТОЛЬКО на создание новых позиции номенклатуры. Проверил на всех имеющихся версиях.

Что и куда необходимо добавить, что бы она проверяла перед записью, если значение, совпадает, тогда ничего не меняем, если отличается, тогда перезаписывала имеющееся значение.
7 Chameleon1980
 
19.11.16
07:35
ИМХО, последует вопрос
сколько?
8 Torquader
 
19.11.16
13:06
Тебе в (2) написали, как свойства устанавливаются, если (2) не помогает, то должно помочь (7)
Просто, у меня, например, загрузка из Excel только для розницы 2.Х написана, так как там со свойствами проще работать пользователям.
9 neGODnic
 
20.11.16
00:38
Короче записывает значения только если создается новая номенклатура. Если номенклатура уже существует, то не обновляет свойство.
Помогите правильно составить код.
Вот что сейчас у меня есть.

Процедура ЗаписатьСвойстваНоменлатуры(ТекущаяСтрокаТаблицы, ТекНом)
    
    НаборЗаписейЗначенияСвойств = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьНаборЗаписей();
    // Производитель
    Если ЗначениеЗаполнено(КолонкаПроизводитель) Тогда
        Если ЗначениеЗаполнено(ТекущаяСтрокаТаблицы[КолонкаПроизводитель]) Тогда
            
            ЗначениеСвойства = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию(ТекущаяСтрокаТаблицы[КолонкаПроизводитель]);
            Если ЗначениеСвойства.Пустая() Тогда
                НовЗначСв = Справочники.ЗначенияСвойствОбъектов.СоздатьЭлемент();
                НовЗначСв.Владелец = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Производитель");    
                НовЗначСв.Наименование = ТекущаяСтрокаТаблицы[КолонкаПроизводитель];
                НовЗначСв.Записать();
                ЗначениеСвойства = НовЗначСв.Ссылка;
            КонецЕсли;            
            
                        
            Запись = НаборЗаписейЗначенияСвойств.Добавить();            
            Запись.Объект   = ТекНом;
            Запись.Свойство = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Производитель");    
            Запись.Значение = ЗначениеСвойства;
            
        КонецЕсли;
    КонецЕсли;
    
    // ПартНомер
    Если ЗначениеЗаполнено(КолонкаПартНомер) Тогда
        Если ЗначениеЗаполнено(ТекущаяСтрокаТаблицы[КолонкаПартНомер]) Тогда
            
            ЗначениеСвойства = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию(ТекущаяСтрокаТаблицы[КолонкаПартНомер]);
            Если ЗначениеСвойства.Пустая() Тогда
                НовЗначСв = Справочники.ЗначенияСвойствОбъектов.СоздатьЭлемент();
                НовЗначСв.Владелец = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Код производителя, MPN");    
                НовЗначСв.Наименование = ТекущаяСтрокаТаблицы[КолонкаПартНомер];
                НовЗначСв.Записать();
                ЗначениеСвойства = НовЗначСв.Ссылка;
            КонецЕсли;            
                                    
            Запись = НаборЗаписейЗначенияСвойств.Добавить();            
            Запись.Объект   = ТекНом;
            Запись.Свойство = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Код производителя, MPN");    
            Запись.Значение = ЗначениеСвойства;
            
        КонецЕсли;
    КонецЕсли;
    
    НаборЗаписейЗначенияСвойств.Отбор.Объект.Установить(ТекНом);
    Попытка
        НаборЗаписейЗначенияСвойств.Записать();
    Исключение
    КонецПопытки;
    
КонецПроцедуры
10 Garykom
 
гуру
20.11.16
00:44
Продам СП. Дорого.

РегистрСведенийНаборЗаписей.<Имя регистра сведений> (InformationRegisterRecordSet.<Имя регистра сведений>)
Записать (Write)
Синтаксис:

Записать(<Замещать>)
Параметры:

<Замещать> (необязательный)

Тип: Булево.
Определяет режим замещения существующей записи в соответствии с текущими установками отбора. Истина - перед записью существующие записи будут удалены. Ложь - записи будут дописаны к уже существующим в информационной базе записям.
Значение по умолчанию: Истина.
Описание:

Записывает набор записей в базу данных. В зависимости от переданного параметра, может быть выполнено добавление записей или их замещение.

Доступность:

Сервер, толстый клиент, внешнее соединение, мобильное приложение(сервер).
Примечание:

Для регистров сведений, подчиненных регистратору, при вызове с параметром <Замещать> равным Ложь после записи в информационную базу набор записей очищается (удаляются записи из набора).
Пример:

НаборКурсов.Записать();
11 Torquader
 
20.11.16
00:45
// чтобы заменялись текущие значения
НаборЗаписейЗначенияСвойств.Записать(ИСТИНА);

Ну и между Исключение и КонецПопыки вставить:
Сообщить("Караул!У меня регистр не записался, потому что:"+ОписаниеОшибки());
12 Garykom
 
гуру
20.11.16
00:46
(11) ))
13 Torquader
 
20.11.16
00:46
(10) Ты выше посмотри - он код как элемент справочника пишет.
Причём, при поиске по наименованию - он владельца не указывает - мало ли чего там найдётся.
14 Garykom
 
гуру
20.11.16
00:47
Кстати что "Значение по умолчанию: Истина. " оно в разных версиях платформы было по разному?
15 Torquader
 
20.11.16
00:50
Там итак и этак будет неправильно - если Истина, то он потрёт всё, что у этого элемента номенклатуры в свойствах было записано (чтобы так не делать - нужно по отбору прочитать то, что есть и исправить/добавить новое).
Если поставит ЛОЖЬ, то просто не перепишет то, что уже записано.
16 Garykom
 
гуру
20.11.16
00:58
(15) Дык про что и речь, что не увидел у ТС чтения из регистра по отбору, замещения нужных свойств и запись обратно.
17 Torquader
 
20.11.16
00:59
(16) Ну, можно писать через менеджер записи, тогда каждая запись будет отдельно записываться и замещаться.
Но, автору очень нравится писать через набор.
18 Garykom
 
гуру
20.11.16
01:01
(17) Через менеджер он случайно легко грохнет все ))
19 Torquader
 
20.11.16
01:03
(18) Через набор проще - создать и записать.
20 Torquader
 
20.11.16
01:09
Вот если в его коде строку с отбором закомментировать - все свойства отправятся коду под хвост.
Поэтому - по умолчанию логично было бы в методе Записать предполагать параметр ЛОЖЬ.
21 neGODnic
 
20.11.16
01:16
Запутали меня еще больше, почему то думал, что решается данный вопрос как-то элементарно.
Если у кого есть желание помочь, могу обработку куда-нибудь скинуть целиком. Если что, с меня потом какая-нибудь компенсация за потраченное время.
22 Torquader
 
20.11.16
01:31
Во-первых, производитель в УТ10 пишется в справочник контрагенты и там у товара есть даже одноимённое поле, правда, заполняется оно только для алкоголя.

Длина строки свойства 50 символов. В справочнике тоже будет 50 символов - так что писать его в справочник нет смысла - можно писать просто в строку.

Что касается артикула поставщика или номера партии, то он также пишется как строка - зачем его писать в справочник (в вашем случае, в справочнике будут и мухи и котлеты).

Функция ЗаписатьДополнительныеСвойстваНоменклатуры(ЭлементНоменклатуры,СтрокаПроизводитель,СтрокаПартия)
Если ЭлементНоменклатуры.Пустая()Тогда
  Сообщить("Элемент не задан, писать нечего");
  Возврат ЛОЖЬ;
КонецЕсли;
Если ЭлементНоменклатуры.ЭтоГруппа Тогда
  Сообщить("У группы не может быть доп-свойств");
  Возврат ЛОЖЬ;
КонецЕсли;
Если НЕ ПустаяСтрока(СтрокаПроизводитель)Тогда
  ХарактеристикаПроизводитель=ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Производитель");
  Если(ХарактеристикаПроизводитель=НЕОПРЕДЕЛЕНО)ИЛИ(ХарактеристикаПроизводитель.Пустая())Тогда
   Сообщить("Не удалось найти свойство для производителя");
   Возврат ЛОЖЬ;
  КонецЕсли;
  НашМенеджер=РегистрыСведений.СвойстваОбъектов.СоздатьМенеджерЗаписи();
  НашМенеджер.Объект=ЭлементНоменклатуры;
  НашМенеджер.Свойство=ХарактеристикаПроизводитель;
  НашМенеджер.Значение=СтрокаПроизводитель;
  Попытка
   НашМенеджер.Записать(ИСТИНА);
  Исключение
   Сообщить("Не удалось записать производителя:"+ОписаниеОшибки());
   Возврат ЛОЖЬ;
  КонецПопытки;
КонецЕсли;
Если НЕ ПустаяСтрока(СтрокаПартия)Тогда
  ХарактеристикаПартия=ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Код производителя, MPN");
  Если(ХарактеристикаПартия=НЕОПРЕДЕЛЕНО)ИЛИ(ХарактеристикаПартия.Пустая())Тогда
   Сообщить("Не удалось найти свойство для партии");
   Возврат ЛОЖЬ;
  КонецЕсли;
  НашМенеджер=РегистрыСведений.СвойстваОбъектов.СоздатьМенеджерЗаписи();
  НашМенеджер.Объект=ЭлементНоменклатуры;
  НашМенеджер.Свойство=ХарактеристикаПартия;
  НашМенеджер.Значение=СтрокаПартия;
  Попытка
   НашМенеджер.Записать(ИСТИНА);
  Исключение
   Сообщить("Не удалось записать партию:"+ОписаниеОшибки());
   Возврат ЛОЖЬ;
  КонецПопытки;
КонецЕсли;
Возврат ИСТИНА;
КонецФункции
23 neGODnic
 
21.11.16
00:50
Спасибо большое. Изменил кое-что.
Но понял что проблема в итоге не в этом коде))
Он то свою роль выполняет на все 100% , по крайней мере в моем случае. А вот суть в том, что

Процедура ЗаписатьСвойстваНоменлатуры(ТекущаяСтрокаТаблицы, ТекНом)

Она уже работат в другой процедуре.

Процедура СоздаиеНоменклатурыИДокументовУстановкиЦен(ТаблицаДанных)
....
Процедура ЗаписатьСвойстваНоменлатуры(ТекущаяСтрокаТаблицы, ТекНом)
...
КонецПроцедуры

Как ее вынести в отдельно, чтобы она была не зависима от создания номенклатуры?
24 Torquader
 
21.11.16
00:54
Тебе написали процедуру, которой передаётся ссылка на уже созданный элемент номенклатуры и значения, которые устанавливаются в свойства - что ещё нужно для того, чтобы свойства записать ?
Независимо от того, куда вы едете — это в гору и против ветра!