Имя: Пароль:
1C
1С v8
Заполнение регистра НоменклатураКонтрагентов из ТЧ. Проблема дублей!
0 Boudybuilder
 
22.11.12
15:18
В обработку в ТЧ получаю строки прайса Наименование , Код . Руками в каждой строке выставляем соответсвие по даному контрагенту Номенклатура и Характеристика. Далее записываем в типовый непериодический регистр сведений. Регистр переделал , добавил поле ответственного , чтобы видно было , кто выставлял соответствия , кто косячит... )))  Структура регистра Изм : контрагент , номенклатура , характеристикаНоменклатуры , остальное все измерения.

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

Но тут нашел я у себя косяк!

Вобщем , когда меняю значения номенклатуры или характеристики , то запись происходит , но не меняет старую , и получается дубль.
Тоесть Ном1 Хар1  -  НоменклатураПоставщика1 КодНоменклатурыПоставщика1
      Ном1 Хар2  -  НоменклатураПоставщика1 КодНоменклатурыПоставщика1
      Ном2 Хар2  -  НоменклатураПоставщика1 КодНоменклатурыПоставщика1

А надо , чтобы тока 1 запись была с НоменклатураПоставщика1 КодНоменклатурыПоставщика1.
Ведь это запись из прайса , которая указывает на конкретную единицу товара.




Вот процедура записи:


Для каждого Строка Из СписокНоменклатуры Цикл
               Если НЕ Строка.Номенклатура.Пустая() И НЕ Строка.Номенклатура.ЭтоГруппа Тогда
                   Запись = РегистрыСведений.НоменклатураКонтрагентов.СоздатьМенеджерЗаписи();
                   Запись.Контрагент                          = Контрагент;
                   Запись.Номенклатура                        = Строка.Номенклатура;
                   Запись.ХарактеристикаНоменклатуры          = Строка.ХарактеристикаНоменклатуры;
                   Запись.Прочитать();
                   Если
                       Запись.КодНоменклатурыКонтрагента          = СокрЛП(Строка.КодНоменклатурыКонтрагента) И
                       Запись.НаименованиеНоменклатурыКонтрагента = СокрЛП(Строка.НаименованиеНоменклатурыКонтрагента) Тогда
                   Иначе
                       Запись.Контрагент                          = Контрагент;
                       Запись.Номенклатура                        = Строка.Номенклатура;
                       Запись.ХарактеристикаНоменклатуры          = Строка.ХарактеристикаНоменклатуры;
                       Запись.КодНоменклатурыКонтрагента          = СокрЛП(Строка.КодНоменклатурыКонтрагента);
                       Запись.АртикулНоменклатурыКонтрагента      = СокрЛП(Строка.АртикулНоменклатурыКонтрагента);
                       Запись.НаименованиеНоменклатурыКонтрагента = СокрЛП(Строка.НаименованиеНоменклатурыКонтрагента);
                       Запись.ШтрихКодНоменклатурыКонтрагента     = СокрЛП(Строка.ШтрихКодНоменклатурыКонтрагента);
                       Запись.ЕдиницаНоменклатурыКонтрагента       = Строка.Номенклатура.БазоваяЕдиницаИзмерения;
                       Запись.Ответственный                       = Ответственный;
                       Запись.Дата                                = ТекущаяДата();
                       Запись.Записать();
                       СписокНоменклатуры.Удалить(Строка);
                   КонецЕсли;
               КонецЕсли;
           КонецЦикла;
1 Boudybuilder
 
22.11.12
15:19
Может удалять перед записью все остальные записи? или измерения местами менять?
2 mortes
 
22.11.12
15:32
Запись.Прочитать();
Поставьте перед изменением
3 Нуф-Нуф
 
22.11.12
15:34
Запись.Записать(ИСТИНА);
4 Boudybuilder
 
22.11.12
15:44
(3) А что это даст?
Замещение чего оно сделает? Все равно дубль запишет.
5 Boudybuilder
 
22.11.12
15:45
хотя...
6 mortes
 
22.11.12
15:45
Если сделать (2) и (3), то дубля не будет
7 Boudybuilder
 
22.11.12
15:57
(2) перед изменением поля ввода в табличном поле ?
8 Boudybuilder
 
22.11.12
16:02
Запись.Прочитать() можно устанавливать параметры только по измерениям? По реквизитам вроде нельзя?
9 mortes
 
22.11.12
16:08
Как-то странно ведется отбор по записям, там по моему по другому
10 mortes
 
22.11.12
16:10
НаборЗаписей = РегистрыСведений.ПаспортныеДанныеФизЛиц.СоздатьНаборЗаписей();
   НаборЗаписей.Отбор.ФизЛицо.Установить(ФЛ.Ссылка);
   НаборЗаписей.Прочитать();

действия, а потом

НаборЗаписей.Записать();
11 mortes
 
22.11.12
16:10
Ну только не Паспортные данные, а свое
12 Boudybuilder
 
22.11.12
16:31
(10) Я же так делаю:

Запись = РегистрыСведений.НоменклатураКонтрагентов.СоздатьМенеджерЗаписи();
                   Запись.Контрагент                          = Контрагент;
                   Запись.Номенклатура                        = Строка.Номенклатура;
                   Запись.ХарактеристикаНоменклатуры          = Строка.ХарактеристикаНоменклатуры;
                   Запись.Прочитать();
13 Boudybuilder
 
22.11.12
16:35
Я наверное сделаю дополнительную колонку и тч будет выглядеть так:

Номенклатура  НомСтарая Характеристика ХарСтарая

Менять буду тока видимые колонки Номенклатура и Характеристика.  НомСтарая и ХарСтарая будет невидима для пользователя.

И уже при записи буду читать по старым ;)


Как вам?
14 Boudybuilder
 
22.11.12
17:05
Для каждого Строка Из СписокНоменклатуры Цикл
               Если НЕ Строка.Номенклатура.Пустая() И НЕ Строка.Номенклатура.ЭтоГруппа Тогда
                   Запись = РегистрыСведений.НоменклатураКонтрагентов.СоздатьМенеджерЗаписи();
                   Запись.Контрагент                 = Контрагент;
                   Запись.Номенклатура               = Строка.НомОлд;
                   Запись.ХарактеристикаНоменклатуры = Строка.ХарОлд;
                   Запись.Прочитать();
                   Если
                       Строка.Номенклатура = Строка.НомОлд И
                       Строка.ХарактеристикаНоменклатуры = Строка.ХарОлд Тогда
                   Иначе
                       Запись.Контрагент                          = Контрагент;
                       Запись.Номенклатура                        = Строка.Номенклатура;
                       Запись.ХарактеристикаНоменклатуры          = Строка.ХарактеристикаНоменклатуры;
                       Запись.КодНоменклатурыКонтрагента          = СокрЛП(Строка.КодНоменклатурыКонтрагента);
                       Запись.АртикулНоменклатурыКонтрагента      = СокрЛП(Строка.АртикулНоменклатурыКонтрагента);
                       Запись.НаименованиеНоменклатурыКонтрагента = СокрЛП(Строка.НаименованиеНоменклатурыКонтрагента);
                       Запись.ШтрихКодНоменклатурыКонтрагента     = СокрЛП(Строка.ШтрихКодНоменклатурыКонтрагента);
                       Запись.ЕдиницаНоменклатурыКонтрагента       = Строка.Номенклатура.БазоваяЕдиницаИзмерения;
                       Запись.Ответственный                       = Ответственный;
                       Запись.Дата                                = ТекущаяДата();
                       Запись.Записать(Истина);
                       СписокНоменклатуры.Удалить(Строка);
                   КонецЕсли;
               КонецЕсли;
           КонецЦикла;        






Вот так пойдет? )
15 mortes
 
22.11.12
17:18
(14) Тебе проще проверить! Запусти и посмотри, что выйдет.
Но на мой взгляд не выйдет, строки не отобраны
16 Boudybuilder
 
22.11.12
23:38
Ладно , дубли решил вроде таким способом (14).

после записи у меня ТЧ очищается. А я хотел бы удалять только записи которые прошли запись.  

но тут я уже вобще запутался правильно ли я отбираю все строки и записываю.

Моя процедура такова:

Если СписокНоменклатуры.Количество() > 0 Тогда
       Ответ = Вопрос ("Установить "+СписокНоменклатуры.Количество()+" соостветствия для контрагента "+Контрагент+"?",РежимДиалогаВопрос.ДаНет);
       Если Ответ = КодВозвратаДиалога.Нет Тогда
           Возврат
       Иначе
           Для каждого Строка Из СписокНоменклатуры Цикл
               Если НЕ Строка.Номенклатура.Пустая() И НЕ Строка.Номенклатура.ЭтоГруппа Тогда
                   Запись = РегистрыСведений.НоменклатураКонтрагентов.СоздатьМенеджерЗаписи();
                   Запись.Контрагент                 = Контрагент;
                   Запись.Номенклатура               = Строка.НомОлд;
                   Запись.ХарактеристикаНоменклатуры = Строка.ХарОлд;
                   Запись.Прочитать();
                   Если
                       Строка.Номенклатура = Строка.НомОлд И
                       Строка.ХарактеристикаНоменклатуры = Строка.ХарОлд Тогда
                   Иначе
                       Запись.Контрагент                          = Контрагент;
                       Запись.Номенклатура                        = Строка.Номенклатура;
                       Запись.ХарактеристикаНоменклатуры          = Строка.ХарактеристикаНоменклатуры;
                       Запись.КодНоменклатурыКонтрагента          = СокрЛП(Строка.КодНоменклатурыКонтрагента);
                       Запись.АртикулНоменклатурыКонтрагента      = СокрЛП(Строка.АртикулНоменклатурыКонтрагента);
                       Запись.НаименованиеНоменклатурыКонтрагента = СокрЛП(Строка.НаименованиеНоменклатурыКонтрагента);
                       Запись.ШтрихКодНоменклатурыКонтрагента     = СокрЛП(Строка.ШтрихКодНоменклатурыКонтрагента);
                       Запись.ЕдиницаНоменклатурыКонтрагента       = Строка.Номенклатура.БазоваяЕдиницаИзмерения;
                       Запись.Ответственный                       = Ответственный;
                       Запись.Дата                                = ТекущаяДата();
                       Запись.Записать(Истина);
                   КонецЕсли;
               КонецЕсли;
           КонецЦикла;
           СписокНоменклатуры.Очистить();
       КонецЕсли;
   КонецЕсли;



В конце цикла делаю еще один цикл с таким же условием:


Если
                       Строка.Номенклатура = Строка.НомОлд И
                       Строка.ХарактеристикаНоменклатуры = Строка.ХарОлд Тогда
                   Иначе
                       СписокНоменклатуры.Удалить(Строка);
                   КонецЕсли;


Но удаляет както не все строки которые прошли по тому же условию в предыдущем цикле. Почему?




А вот такие кнопки работают перфектно (удаляют то что надо) , но их делал не я:




//Отберем все строки где соответствия номенклатуры установлены
Процедура УдалитьСтрокиБезСоответствий(Кнопка)
   
   Массив = СписокНоменклатуры.НайтиСтроки(Новый Структура("Номенклатура" , Справочники.Номенклатура.ПустаяСсылка()));
   Для Каждого ЭлементМассива ИЗ Массив Цикл
       СписокНоменклатуры.Удалить(ЭлементМассива);
   КонецЦикла;
   
КонецПроцедуры
//Отберем все строки где соответствия номенклатуры не уствновлены
Процедура УдалитьСтрокиССоответствими(Кнопка)
   
   мВГраница = СписокНоменклатуры.Количество() - 1;
   Для Индекс = 0 по мВГраница Цикл
       ТС = СписокНоменклатуры[мВГраница - Индекс];
       Если ЗначениеЗаполнено(ТС.Номенклатура) Тогда
           СписокНоменклатуры.Удалить(ТС);
       КонецЕсли;
   КонецЦикла;
   
КонецПроцедуры
17 petrowsky
 
23.11.12
00:54
из (0) не совсем понятна структура регистра, но попробую подсказать
1. т.к. у тебя ключевые поля Номенклатура и ХарактеристикаНоменклатуры, то в измерениях должны быть только они, остальные переносятся в ресурсы, а такое поле как Ответсвенный вообще в реквизиты
тогда проблем с дублированием не будет

2. если структуру менять не хочешь, то лучше использовать набор записей, а не менеджер

Если НЕ Строка.Номенклатура.Пустая() И НЕ Строка.Номенклатура.ЭтоГруппа Тогда
   НаборЗаписей = РегистрыСведений.НоменклатураКонтрагентов.СоздатьНаборЗаписей();
   НаборЗаписей.Отбор.Номенклатура.Установить(Строка.Номенклатура);
   НаборЗаписей.Отбор.ХарактеристикаНоменклатуры.Установить(Строка.ХарактеристикаНоменклатуры);
   НаборЗаписей.Прочитать();

   Если НаборЗаписей.Количество() > 0 Тогда //есть такие записи
       НаборЗаписей.Очистить(); //очищаем прочитанное из набора
       
       //добавляем новую запись в набор
       Запись = НаборЗаписей.Добавить();
       Запись.Контрагент = Контрагент;
       Запись.Номенклатура = Строка.Номенклатура;
       Запись.ХарактеристикаНоменклатуры = Строка.ХарактеристикаНоменклатуры;
       Запись.КодНоменклатурыКонтрагента = СокрЛП(Строка.КодНоменклатурыКонтрагента);
       Запись.АртикулНоменклатурыКонтрагента = СокрЛП(Строка.АртикулНоменклатурыКонтрагента);
       Запись.НаименованиеНоменклатурыКонтрагента = СокрЛП(Строка.НаименованиеНоменклатурыКонтрагента);
       Запись.ШтрихКодНоменклатурыКонтрагента = СокрЛП(Строка.ШтрихКодНоменклатурыКонтрагента);
       Запись.ЕдиницаНоменклатурыКонтрагента = Строка.Номенклатура.БазоваяЕдиницаИзмерения;
       Запись.Ответственный = Ответственный;
       Запись.Дата = ТекущаяДата();
       НаборЗаписей.Записать(Истина); //записываем набор, т.к. там только 1 новая запись, то старые будут замещены ей
   
       СписокНоменклатуры.Удалить(Строка);
   КонецЕсли;
КонецЕсли;
18 Boudybuilder
 
23.11.12
04:33
(17)
Регистр типовый.

НоменклатураКонтрагентов
Изм:
-Контрагент
-Номенклатура
-ХарактеристикаНоменклатуры
Ресурсы:
-НаименованиеНоменклатурыКонтрагента (строка)
-КодНоменклатурыКонтрагента          (строка)
-АртикулНоменклатурыКонтрагента      (строка)
Реквизиты:
-Ответственный
-Дата

По данной структуре видно , что регистр не сможет иметь две одинаковые комбинации по измерениям. А ресурсы то могут повторяться. (Так ведь у непереодических РегСв?)

А для меня важно чтобы уникальность была по измерению Конрагент и Ресурсам КодНоменклатурыКонтрагента и НаименованиеНоменклатурыКонтрагента. Так как именно эти ресурсы указывают на номенклатуру в прайсе чьим владельцем является измерение Контрагент. Но переделывать регистр уже не хочется ,  он ведь типовый и вкрученый формы номенклатуры.
19 Boudybuilder
 
23.11.12
04:35
Потому записываю из ТЧ я вот таким циклом:


           Для каждого Строка Из СписокНоменклатуры Цикл
               Если НЕ Строка.Номенклатура.Пустая() И НЕ Строка.Номенклатура.ЭтоГруппа Тогда
                   Запись = РегистрыСведений.НоменклатураКонтрагентов.СоздатьМенеджерЗаписи();
                   Запись.Контрагент                 = Контрагент;
                   Запись.Номенклатура               = Строка.НомОлд;
                   Запись.ХарактеристикаНоменклатуры = Строка.ХарОлд;
                   Запись.Прочитать();
                   Если
                       Строка.Номенклатура = Строка.НомОлд И
                       Строка.ХарактеристикаНоменклатуры = Строка.ХарОлд Тогда
                   Иначе
                       Запись.Контрагент                          = Контрагент;
                       Запись.Номенклатура                        = Строка.Номенклатура;
                       Запись.ХарактеристикаНоменклатуры          = Строка.ХарактеристикаНоменклатуры;
                       Запись.КодНоменклатурыКонтрагента          = СокрЛП(Строка.КодНоменклатурыКонтрагента);
                       Запись.АртикулНоменклатурыКонтрагента      = СокрЛП(Строка.АртикулНоменклатурыКонтрагента);
                       Запись.НаименованиеНоменклатурыКонтрагента = СокрЛП(Строка.НаименованиеНоменклатурыКонтрагента);
                       Запись.ШтрихКодНоменклатурыКонтрагента     = СокрЛП(Строка.ШтрихКодНоменклатурыКонтрагента);
                       Запись.ЕдиницаНоменклатурыКонтрагента       = Строка.Номенклатура.БазоваяЕдиницаИзмерения;
                       Запись.Ответственный                       = Ответственный;
                       Запись.Дата                                = ТекущаяДата();
                       Запись.Записать(Истина);
                   КонецЕсли;
               КонецЕсли;
           КонецЦикла;



Затем этим удаляю:


   мВГраница = СписокНоменклатуры.Количество() - 1;
           Для Индекс = 0 по мВГраница Цикл
               ТС = СписокНоменклатуры[мВГраница - Индекс];
               Если ТС.Номенклатура = ТС.НомОлд И
                   ТС.ХарактеристикаНоменклатуры = ТС.ХарОлд Тогда
               Иначе
                   СписокНоменклатуры.Удалить(ТС);
               КонецЕсли;
           КонецЦикла;



Вроде работает.
Основная теорема систематики: Новые системы плодят новые проблемы.