Имя: Пароль:
1C
 
Поиск и замена значений - умеют ли такое самые продвинутые заменялки?
0 Гений 1С
 
гуру
06.08.20
21:30
Заменял дубли характеристик (по одинаковому владельцу) обработкой по замене дублей "ПоискИЗаменаДублирующихсяЭлементов_8.3 УФ от Тесла.epf" в Рознице 2.3.
Короче, что обнаружил - некоторые дубли не удаляются, т.к. нельзя записать одинаковые записи в регистр "Цены номенклатуры" и "Себестоимость".
Добавил вот такую затычку:

                    //Осипов 2020-08-06 корректировка
                    Если НаборЗаписей.Метаданные().Измерения.Найти("Номенклатура") <> Неопределено И
                        НаборЗаписей.Метаданные().Измерения.Найти("Характеристика") <> Неопределено
                    Тогда
                        //Удаляем дубли записей
                        Соо = Новый Соответствие();
                        КУдалению = Новый Массив();
                        Для Каждого МЗ ИЗ НаборЗаписей Цикл
                            КлючЗаписи = "" + МЗ.Номенклатура.УникальныйИдентификатор() + МЗ.Характеристика.УникальныйИдентификатор();
                            Если Соо[КлючЗаписи] <> Неопределено Тогда
                                КУдалению.Добавить(МЗ);
                            КонецЕсли;
                            Соо.Вставить(КлючЗаписи, истина);
                        КонецЦикла;
                        //Безжалостно удаляем дубли в регистрах сведений
                        Для Каждого МЗ ИЗ КУдалению Цикл
                            НаборЗаписей.Удалить(МЗ);
                        КонецЦикла;
                        
                    КонецЕсли;

Интересно, а мужики с таким сталкивались? И как решали?
1 Злопчинский
 
06.08.20
21:33
(0) учесть что
было
Товар1 123руб
Товар2 128руб

станет
Товар1 ??? руб
2 kofeinik
 
06.08.20
22:52
(1) Проще потом перезанести новые цены, поскольку дубли, как правило, старое и ненужное, так что пусть лучше так, чем никак.
3 acht
 
06.08.20
23:49
(0) > а мужики

А мужики с таким сталкивались. И сказали - ковыряйтесь вы сами с прикладными данными, которые в БП значат одно, а в ЗУП (особенно в перерасчете) - другое. Мужики данные не портят, а откуда в ЗУП "Номенклатура" им неведомо.

Физик? Ландау? Ебись.
4 TormozIT
 
гуру
07.08.20
00:16
ЕСть их у нас и причем уже давно http://devtool1c.ucoz.ru/index/poisk_dublej_i_zamena_ssylok/0-23

        ИначеЕсли ТипТаблицы = "РегистрСведений" И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда
            // Избавимся от неуникальных строк набора
            Если СтруктураНабораЗаписей.Данные.Количество() > 1 Тогда
                СтруктураКлюча = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ИмяТаблицыРегистра,,, Ложь);
                СтрокаПолейКлюча = "";
                Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
                    СтрокаПолейКлюча = СтрокаПолейКлюча + "," + КлючИЗначение.Ключ;
                КонецЦикла;
                СтрокаПолейКлюча = Сред(СтрокаПолейКлюча, 2);
                НеуникальныеКлючи = ирОбщий.НеуникальныеКлючиТаблицыЛкс(СтруктураНабораЗаписей.Данные, СтрокаПолейКлюча);
                Если НеуникальныеКлючи.Количество() > 0 Тогда
                    ТаблицаНабора = СтруктураНабораЗаписей.Методы.Выгрузить();
                    Для Каждого НеуникальныйКлюч Из НеуникальныеКлючи Цикл
                        СтрокиНеуникальногоКлюча = ТаблицаНабора.НайтиСтроки(НеуникальныйКлюч);
                        Для ИндексУдаляемойСтроки = 0 По СтрокиНеуникальногоКлюча.Количество() - 2 Цикл
                            ТаблицаНабора.Удалить(СтрокиНеуникальногоКлюча[ИндексУдаляемойСтроки]);
                        КонецЦикла;
                        ПредставлениеСтруктуры = ирОбщий.ПолучитьПредставлениеСтруктурыЛкс(НеуникальныйКлюч);
                        ирОбщий.СообщитьЛкс("Замещены неуникальные строки регистра сведений " + ОбъектМД.Имя + " по ключу " + ПредставлениеСтруктуры);
                    КонецЦикла;
                    СтруктураНабораЗаписей.Методы.Загрузить(ТаблицаНабора);
                КонецЕсли;
            КонецЕсли;
5 TormozIT
 
гуру
07.08.20
00:22
(4)+ Правда это не спасает от аналогичной ошибки при перепроведении документа, в котором соответствующая ТЧ тоже получила дубли по ключу. А в ТЧ универсально понять нужно ли сворачивать строки и по какому ключу - невозможно в общем случае.
6 acht
 
07.08.20
00:26
(4) > СообщитьЛкс("Замещены неуникальные строки регистра сведений

А вот это опасно, дядь Сереж.
Типовые обработки (особенно при немонопольном использовании) позволяют повторный запуск без порчи данных. Какую-то часть дублей убрали, какую-то не смогли. А твой код берет на себя ответственность о решении - дескать, там что-то было, я сделаль, теперь сами разбирайтесь (если чо, то из бэкапа восстановите). Учитывая общий уровень "разработчиков" - не надо так.
7 TormozIT
 
гуру
07.08.20
00:41
(6) Уже много лет этот код работает и сам его использовал много раз. С чего ты взял что у меня не работает повторный запуск? Пока я не понял о какой проблеме ты пишешь. Да, моя актуальная реализация для регистров сведений оставляет из группы конфликтующих первую одну строку. Когда то давно я предоставлял выбор пользователю для каждой группы конфликтующих записей оставить одну. Но реальность такова, что ковыряться с этим пользователи в 99% не хотят и потому это лишняя головная боль и сложности для неинтерактивного выполнения. И вот уже много лет такой молчаливый и более простой подход работает и все довольны.
8 TormozIT
 
гуру
07.08.20
00:44
Т.е. на начальном этапе развития инструмента я сделал максимально контролируемое разрешение таких конфликтов, но меня регулярно просили принести строгость в жертву практичности (частотным сценариям). После многочисленных обсуждений с пользователями, сначала я сделал старый полуручной режим опцией, а потом и вообще отключил.
9 Конструктор1С
 
07.08.20
04:56
(0) ты всегда такой кривой код пишешь?
10 Гений 1С
 
гуру
07.08.20
08:03
(2) А ты в теме, молодец. ;-)
(9) нет, только когда за деньги.
11 Бурза
 
07.08.20
08:16
(9) Да ладно, бывает намного хуже, это вполне сойдёт для сельской местности.
12 Гений 1С
 
гуру
07.08.20
09:16
(11) гггг.
13 Сияющий в темноте
 
07.08.20
09:39
На самом деле,пока искуственный интеллект не появитмя,все сложные ситуации будет разбирать пользователь.
в случае с ценой,можно посмотреть,какое значение было установлено ранее,даже не по последней записи,а по последнему изменению,но,может оказаться,что товары-то реально разные и пришли одновременно,например,из-за разницы партий поставщика они были у него в накладной с разными ценами.
поэтому,научить машину всему,что может быть,тут никакого бюджета не хватит.

в стандартной же обоаботке,предполагается,что пользователь саи залезет в регистр и там уничтожит дубль,то есть полуручной режии.
14 Конструктор1С
 
07.08.20
09:40
(11) согласен
15 DJ Anthon
 
07.08.20
09:49
Так же делал по регистру сведений. Остальные регистры пересчитываются потом, можно и удалять всю кривоту. Плюсом добавил возможность удаления связанных объектов, которые подобны выбранному. Например, если у номенклатуры помечен на удаление вид номенклатуры, чтобы долго не искать, нажимаем одну кнопку, и все номенклатуры, у которых этот же вид номенклатуры, помечаются на удаление. но это в обработке удаления, а не поиска. в поиске и замене я добавил функцию поиска вообще всех дублей, а так же полный игнор всех ошибок для особых случаев. такое бывает после кривого объединения двух и более баз.
16 DJ Anthon
 
07.08.20
09:51
поставил на ночь объединение, и наутро 99 процентов обработано, остальное ручками. чем раз в пять минут спотыкаться на каком-нибудь тупом регистре.
17 Гений 1С
 
гуру
07.08.20
11:22
Чтобы дважды не вставать, задам еще один вопрос.
Обычная замена идет по ссылающимся объекам и заменяет там дубли.
Оптимизированный вариант составляет реест объектов на замену и заменяет исходя из ссылающегося объекта.
т.е. в одном объекте может быть несколько замен.

Вы такое дорабатывали? Я лично как-то делал разок.

Серега, а твоя замена так работает или тупо по-простому?
18 TormozIT
 
гуру
07.08.20
12:07
(17) Конечно у меня работает оптимально - запись каждого ссылающегося объекта выполняется только один раз.
19 DJ Anthon
 
07.08.20
12:09
не делал, не было необходимости
20 Гений 1С
 
гуру
10.08.20
08:50
(18) это хорошо, а то медленно работает.
Единственное плохо в твоей разработке - сложная курва поставки так сказать.
Кстати, у тебя до сих пор конфа или уже переведено на расширение?
21 TormozIT
 
гуру
10.08.20
09:08
(20) 4 года назад появился вариант поставки "Расширение". Теперь он является основным. http://devtool1c.ucoz.ru/index/rasshirenie_variant/0-52
Есть очень простой способ установки:
1. Открываешь внешнюю обработку "Установщик варианта Расширение" http://devtool1c.ucoz.ru/load/osnovnye/ustanovshhik_varianta_rasshirenie/1-1-0-21
2. Нажимаешь "Установить" https://i.imgur.com/cXPMCjF.png
22 Вафель
 
10.08.20
09:23
(1) по идее должна остаться запись с изначально верной номенклатурой
23 TormozIT
 
гуру
10.08.20
09:31
(22) В моем опыте решения таких задач было предостаточно случаев, когда верная ссылка имела неверные данные в объекте, не говоря уже про связанные строки в регистрах, где в каждом регистре может быть своя правильность для каждой группы дублей.
24 Гений 1С
 
гуру
10.08.20
10:59
(21) ну что ж, отлично. Расширение - это хорошо.
25 Злопчинский
 
10.08.20
13:38
(23) Вот именно.
с моего мелкого опыта д.б. предприняты все возможные технические ухищрения для исходного недопущения возникновения дублей. все - отальное - это как лечить  кашель при гангрене.
26 Гений 1С
 
гуру
10.08.20
14:13
(25) ты живешь в идеальном мире. Это неплохо. Но иногда к нам, докторам 1С, приходят пациенты с просьбой замены дублей. И мы замеяем. Хотя знаем, что эта женщина потом опять придет на аборт. ;-)
27 Гений 1С
 
гуру
20.08.20
12:43
Каюсь, в моей обработке был косяк, она заменила и в регистрах накопления, так что правильный код такой:

                    //Осипов 2020-08-06 корректировка
                    //Только для регистров сведений, регистры накопления не трогаем
                    Если
                        Метаданные.РегистрыСведений.Содержит(НаборЗаписей.Метаданные()) И
                        НаборЗаписей.Метаданные().Измерения.Найти("Номенклатура") <> Неопределено И
                        НаборЗаписей.Метаданные().Измерения.Найти("Характеристика") <> Неопределено
                    Тогда
                        //Удаляем дубли записей
                        Соо = Новый Соответствие();
                        КУдалению = Новый Массив();
                        Для Каждого МЗ ИЗ НаборЗаписей Цикл
                            КлючЗаписи = "" + МЗ.Номенклатура.УникальныйИдентификатор() + МЗ.Характеристика.УникальныйИдентификатор();
                            Если Соо[КлючЗаписи] <> Неопределено Тогда
                                КУдалению.Добавить(МЗ);
                            КонецЕсли;
                            Соо.Вставить(КлючЗаписи, истина);
                        КонецЦикла;
                        //Безжалостно удаляем дубли в регистрах сведений
                        Для Каждого МЗ ИЗ КУдалению Цикл
                            НаборЗаписей.Удалить(МЗ);
                        КонецЦикла;
                        
                    КонецЕсли;
28 Конструктор1С
 
21.08.20
09:28
(27) я бы на твоём месте такой костылище говнокодный даже не выкладывал. Там ещё дофига косяков. На вскидку, чего ты тут наговнокодил:
- мусорные комментарии
- невнятные имена переменных
- 10 табуляций от края как бы намекают, что это действие происходит где-то в говнопроцедуре на тыщу строк. Т.е. декомпозиции никакой
- привязка в универсальном инструменте к конкретной бизнес-логике (номенклатура, характеристика)
- обращение к метаданным миллион раз, хотя это можно было сделать ещё на верхнем уровне декомпозиции (которой у тебя и нет)
- проверка только двух измерений без малейшей попытки проверить остальные измерения (привет непонятным ошибкам)


Это какой-то звиздец-звиздецкий. Ты чем 20 лет занимался, что твой код на уровне рукожопого стажера?
29 Гений 1С
 
гуру
31.08.20
13:35
(28) О, Гуру, у тебя какое место на инфостарте?
30 zak555
 
31.08.20
13:57
(0) используй ИР
31 Конструктор1С
 
02.09.20
05:20
(29) никакого. Меня там нет
2 + 2 = 3.9999999999999999999999999999999...