Здравствуйте. 1С:Предприятие 8.2 (8.2.19.130) Альфа-Авто: А+А, украинская версия 4.1.19.01
Подскажите пожалуйста, возможно-ли перестроить первичный ключ справочника (Например Номенклатура). Могу ошибиться в формулировках, поэтому попробую описать чего нужно добиться.
Имеется оригинальный товар с определенным артикулом например 26300-35505 производитель у оригинала допустим MOBIS Также есть другой аналог от другого производителя (MANDO) со своим артикулом MOF4459. Но при появлении аналога, не имеющего своего артикула приводит к тому, что в справочник нельзя добавить два одинаковых артикула из-за их неуникальности, т.к. Альфа проверяет уникальность товара по Артикулу. Т.е. полу Производитель не несет никакой задачи, контролирующей уникальность, кроме как чисто информационную.
Можно-ли сделать составной ключ по двум полям Артикул+Производитель и выполнять проверку уникальности через такую связку, или сама Платформа/Конфигурация не позволяет такое делать?
Спрашивал у Рарус, они сказали, что контроль уникальности по Артикулу можно отключить, а по составному ключу (Артикул+Производитель) такого в Альфе нет и нет даже в планах. Больше технической информации у них получить мне не удалось, т.к. поддержка такую консультацию не оказывает.
Группа: Основатель
Сообщений: 13983
Из: Киев
Спасибо сказали: 4553 раз
Рейтинг: 3682.7
То о чем вы говорите - это не первичный ключ справочника. Это бизнес логика конкретной конфигурации. Поменять это можно. Найти в коде где происходит проверка и описать свою логику.
Vofka @ Сегодня, 16:23
, Я правильно понимаю, что это должно быть где-то в модулях справочника Номенклатура или это может находится в любом месте конфигурации, включая и закрытые модули?
Подумайте над тем, чтобы просто отключить уникальность по артикулу. Вдруг будет ситуация когда у одного производителя будут абсолютно разные запчасти без артикулов - ключ Производитель+Артикул также окажется неуникальным
Макс1С @ Вчера, 18:03
, Спросил у Рарус, как отключить контроль уникальности и вот что они ответили:
Цитата
В случае снятия контроля номера по каталогу, уникальность записей в справочнике контролироваться никак не будет. Можно завести множество идентичных записей номенклатуры. Снятие права "Проверка заполнения справочников и документов" позволит добавлять в документе одинаковые строки. Но оно также приведет к полному отключению контроля корректности заполнения базы данных. Отмену использования данного права мы не рекомендуем, т.к. результат может быть непредсказуемым, каким-угодно. Так сказать на ваш страх и риск.
Я попробовал отключить это правило и понял, что оно влияет не только на справочник Номенклатура, но и на все справочники абсолютно. Также это рушит всю бизнес-логику программы.
В ПолучитьОбязательныеРеквизиты отключаете уникальность. В ПередЗаписью пишете свой блек-джек.
Я нашел такие строки Это видимо для проверки уникальности по Артикулу?
// Если обПраво("НомерПоКаталогуУникальный",Права) Тогда ОбязательныеРеквизиты.Вставить("Артикул",3); // Это нужно закомментировать ? КонецЕсли;
А это проверка уникальности строк в ТЧ документа, чтобы можно было добавлять несколько одинаковых строк но например с разной ценой?
// Проверка на уникальность строк в табличной части "Состав набора". Если (ВидНоменклатуры=Перечисления.ВидыНоменклатуры.Комплект) ИЛИ (ВидНоменклатуры=Перечисления.ВидыНоменклатуры.Набор) Тогда ОбязательныеТовары = Новый Структура(); ОбязательныеТовары.Вставить("Номенклатура", 3); // Это нужно закомментировать ? ОбязательныеТовары.Вставить("ХарактеристикаНоменклатуры", 2); ОбязательныеРеквизиты.Вставить("СоставНабора", ОбязательныеТовары); КонецЕсли;
Я правильно понимаю, что если закоменнтировать эти строки, то отключится проверка по Артикулу в справочнике Номенклатура, а остальные правила проверки в других справочникат не будут отключены?
Я уже не удержался так и поступил. А ПерезЗаписью добавил:
//--- перед записью нового элемента Если (НЕ ЭтоГруппа) И (ЭтоНовый()) Тогда ТекАртикул = Артикул; ТекПроизводитель = Производитель; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Номенклатура.Ссылка, | Номенклатура.Артикул, | Номенклатура.Наименование, | Номенклатура.Производитель |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Артикул = &Артикул | И Номенклатура.Производитель = &Производитель";
Запрос.УстановитьПараметр("Артикул", ТекАртикул); Запрос.УстановитьПараметр("Производитель", ТекПроизводитель); Результат = Запрос.Выполнить(); ТЗПоиск = Результат.Выгрузить(); Если ТЗПоиск.Количество() > 0 Тогда Предупреждение("Товар: "+Строка(ТекАртикул)+" ( "+Строка(ТекПроизводитель)+" ) уже существует"); Отказ = Истина; КонецЕсли; КонецЕсли;
А чуть ниже добавил еще такую проверку так сказать от дураков - если кто-то решит в существующей записи изменить допустим производителя, тем самым получив дубль
//--- перед записью после при редактировании имеющейся записи Если (НЕ ЭтоГруппа) Тогда ТекАртикул = Артикул; ТекПроизводитель = Производитель; ТекКод = Код; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Номенклатура.Ссылка, | Номенклатура.Артикул КАК Артикул, | Номенклатура.Наименование КАК Наименование, | Номенклатура.Производитель КАК Производитель, | Номенклатура.Код КАК Код |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Артикул = &Артикул | И Номенклатура.Производитель = &Производитель | И Номенклатура.Код <> &Код";
Результат = Запрос.Выполнить(); ТЗПоиск = Результат.Выгрузить(); Если ТЗПоиск.Количество() > 0 Тогда Предупреждение("Недопустимая операция для: "+Строка(ТекАртикул)+" ( "+Строка(ТекПроизводитель)+" ) [ "+Строка(ТекКод)+" ] уже существует."+Символы.ПС+"Вероятно был изменен Артикул или Производитель"); Отказ = Истина; КонецЕсли; КонецЕсли;
Отключить ограничение по добавлению в ТЧ документа нескольких одинаковых строк (Артикулов), но с разными ценами выполняется также в модуле документа или здесь подход другой?
bizisoft @ Сегодня, 14:46
, в целях оптимизации можете оставить только второй запрос-проверку, он будет покрывать и первый случай. единственное - я бы изменил условие на ссылку вместо кода
По ограничению в ТЧ: точно не помню, но в АА есть и ТЧ Товары и ТЧ Наборы, судя по комментарию в стандартном коде - это проверка для ТЧ Наборы, нужно поискать в другом мместе
Закомментировал строку ОбязательныеТовары.Вставить("Номенклатура",3); - но это не дало никакого результата, т.е. по аналогии с номенклатурой не прокатило. Где еще можно покопать?
Для начала хотел обкатать это в Поступление товаров, т.к. бывает, что от поставщика в одном приходе приходит одинаковый товар (один артикул, одного производителя), но с разной ценой Например: 54651-2Е000 Mobis 10 100.00 54651-2Е000 Mobis 20 150.00
Соответственно если есть подобный приход, то возможно может быть случай, когда на сайте клиент заказывает одинаковый товар, но с разных складов (допустим ему нужно 4 шт, а есть по 2 на разных складах), склады могут быть как Продавца, так и его поставщика. Исходя из этого, то получается сюда подпадает и ЗаказПокупателя, РеализацияТоваров, возможно СчетНаОплату и вероятно и НалоговаяНакладная.
Вопрос модератору: В ходе решения проверки уникальности в номенклатуре, возник второстепенный вопрос, но т.к. в правилах написано Новый вопрос = Новая тема, можно-ли его задать в этой теме или все же создать по нему свою тему?
А вот собственно сам вопрос: Т.к. получилось сделать проверку уникальности по Арт+Бренд и решить следующую аналогичную проблему с добавлением Аналогов (также не разрешало одинаковый Арт), в форме подбора номенклатуры в ТабличномПоле списка аналогов нарушилась механика (как обозвать то) "навигации", т.е. если в списке Аналогов дблКлик по строке аналога, то он должен быть найден и спозиционирован на соответствующем элементе списка номенклатуры. Но в связи с тем, что поиск происходит через Найти(), в которой в качестве аргумента передается значение Артикул, то для товаров с одинаковым артикулом, но разными производителями, то поиск и позиционирование происходит не так как раньше, позиционирование происходит рандомно. В метод Найти() как я понял нельзя добавить еще один аргумент, чтобы искал по Арт+Бренд. Пробовал НайтиСтроки()
Это также не работает. Может кто знает, как можно решить данную проблему.
У меня есть одна идея, но насколько она работоспособна и оптимальна пока не знаю. Идея такая в номенклатуру добавить поле АртБренд, куда записывать значения <Номенклатура.Артикул>+<Производитель.Код> Например: 2630035505_ЦБ00123 (думал сначала Производитель.Наименование, но наименование могут изменить). И тогда можно будет продолжить использование метода Найти(ВыбранаяСтрока.Артикул, ), только заменил в нем ВыбранаяСтрока.Артикул на ВыбранаяСтрока.АртБренд.
Если ВыбраннаяСтрока=Неопределено Тогда Возврат; КонецЕсли; НайденныйАналог=Справочники.Номенклатура.НайтиПоРеквизиту("АртБренд",ВыбраннаяСтрока.АртБренд); //НайтиПоРеквизиту("Артикул",ВыбраннаяСтрока.Артикул); Если обЗначениеНеЗаполнено(НайденныйАналог) Тогда Возврат; КонецЕсли; СтандартнаяОбработка=Ложь; // Позиционирование в списке номенклатуры ЭлементыФормы.Список.ТекущаяСтрока=НайденныйАналог; // позиционирование в списке аналогов ЭлементыФормы.АналогиОбъединеное1.ТекущаяСтрока = АналогиОбъединеное1.Найти(ВыбраннаяСтрока.АртБренд,"АртБренд"); //Найти(ВыбраннаяСтрока.Артикул,"Артикул")
Как думаете, такое сработает или это как чесать левое ухо правой рукой тянувшись через затылок?
bizisoft @ Сегодня, 12:39
, Как вариант добавьте реквизит в номенклатуру, например "Номер артикула", а в стандартное поле артикул записывайте программно <Номенклатура.НомерАртикула>+<Производитель.Код> при изменении этих полей на форме. Таким образом вы получите поле с нужной вам уникальностью в стандартном реквизите и не нужно будет переписывать во всех местах поиск и т.п. При необходимости можно добавить ещё какой-то разрез без сильных доработок И еще можно будет раскоментить уникальность артикула )
Как вариант добавьте реквизит в номенклатуру, например "Номер артикула", а в стандартное поле артикул записывайте программно <Номенклатура.НомерАртикула>+<Производитель.Код> при изменении этих полей на форме.
А вот об этом я и не подумал. Интересная идея. Вот только тогда придется переделывать другое, например (пришло первое на ум) это документы, а именно отображение вместо реквизита Артикул другой реквизит, чтобы в документах выводились нормальные значения. Наверное все таки проще оставить Артикул как есть и добавить АртБренд.
Воспользовался вариантом от Макс1С. Добавил реквизит тАртикул длиной как у Артикул. У реквизита Артикул увеличил длину на длину Кода поставщика. "Пробежался" и скопировал значение Артикул в тАртикул. Еще разок, но уже скопировал в Артикул конкатенацию строк <тАртикул>+<"_">+<Производитель.Код>, чтобы получилось 26300-35503_ЦБ012345.
При этом покрошились все прописанные Аналоги, которые пришлось восстановить, так сказать по оставшимся следам. "Пробежался" по РегиструСведений ГруппыАналогов, брал в нем Артикул (то что осталось) и производил поиск по Номенклатуре но уже по добавленному реквизиту тАртикул, если находило, то менял значение Артикул в регистре сведений на значение из справочника Номенклатура.Артикул, т.е. в РС было 26300-35503 менялось на 26300-35503_ЦБ012345. Т.о. получилось восстановить все связи по Аналогам, и чтобы два раза не ходить заодно были проставлены в регистре реквизиты/измерения Производитель и Наименование для записей, которые пользователи не заполнили, то ли в спешке, то ли по :%№"№";%.
В итоге, теперь можно создавать карточки товара с одинаковым артикулом, но разным производителем. Осталась только косметика - в ТЧ документа добавить поле тАртикул ну и в печатных формах подменить вывод на тАртикул.
//--- добавлено через 25 мин. А вот со снятием ограничения на добавление в ТЧ документа более одной строки одинакового товара (например с разной ценой) пока не выходит. Нашел в модуле соответствующего документа процедуру, в которой закомментировал пару строк, как по аналогии с Номенклатурой.
// Возвращает структуру обязательных / уникальных реквизитов документа // Возвращаемая структура содержит строковые идентификаторы реквизитов или вложенные структуры для табличных частей // Для реквизита значение структуры содержит число 1-Обязательный, 2-Уникальный, 3-Уникальный и обязательный Функция ПолучитьОбязательныеРеквизиты() Экспорт // Обязательные поля таблицы товаров ОбязательныеТовары=Новый Структура(); //ОбязательныеТовары.Вставить("Номенклатура",3); <<=========== эту ОбязательныеТовары.Вставить("Количество",1); ОбязательныеТовары.Вставить("ЕдиницаИзмерения",3); ОбязательныеТовары.Вставить("Коэффициент",1); ОбязательныеТовары.Вставить("ХарактеристикаНоменклатуры",2);
// Обязательные поля таблицы распределения заказов ОбязательныеРаспределение=Новый Структура(); // ОбязательныеРаспределение.Вставить("Номенклатура",3); <<=========== эту ОбязательныеРаспределение.Вставить("Количество",1); ОбязательныеРаспределение.Вставить("ЕдиницаИзмерения",3); ОбязательныеРаспределение.Вставить("Коэффициент",1); ОбязательныеРаспределение.Вставить("ХарактеристикаНоменклатуры",2); ОбязательныеРаспределение.Вставить("ЗаказПокупателя",3);
// Для реквизита значение структуры содержит число 1-Обязательный, 2-Уникальный, 3-Уникальный и обязательный
Можно попробовать поставить вторым параметром "1", то что Номенклатура должна быть заполнена нам подходит, но уникальной быть не должна. Но в рабочую базу не спешите такое добавлять , крутиться у меня в памяти, что сделано это неспроста и другие механизмы рассчитаны на уникальность номенклатуры в документе... что-то с партиями..
Кое что удалось найти. В модуле общем модуле дкДокументы в функции дкПроверитьКорректность(.....) закомментировал строку Результат = Ложь; и вроде теперь можно добавлять две одинаковые строки в ТЧ документов, при этом я еще убрал комментирование со строк из постов выше.
// необходимо исключить проверку уникальности для сотовых платежей Если НЕ ЭтоПлатеж Тогда // поищем строки удовлетворяющие структуре отбора НайденныеСтроки = ТабличнаяЧасть.НайтиСтроки(СтруктураОтбора); // если нашли и их больше 1, то строки не уникальные Если НайденныеСтроки.Количество() > 1 Тогда // добавим строку в список найденных дублей, что бы не сообщать о ней еще раз // ===> Результат = Ложь; ДублирующиесяСтроки = ""; // выведем строку сообщения... Для каждого НайденнаяСтрока Из НайденныеСтроки Цикл ДублирующиесяСтроки = ДублирующиесяСтроки + "," + СокрЛП(НайденнаяСтрока.НомерСтроки); // добавим строку в список найденных дублей, что бы не сообщать о ней еще раз СписокНайденныхДублей.Добавить(НайденнаяСтрока); КонецЦикла; СтрокаРеквизитов = ""; Для каждого РеквизитТаблицы Из СтруктураОтбора Цикл СтрокаРеквизитов = СтрокаРеквизитов + ?(ПустаяСтрока(СтрокаРеквизитов),"",",") + РеквизитТаблицы.Ключ; КонецЦикла; дкДобавитьОшибку(Ошибки,"Таблица < " + обПолучитьСинонимРеквизита(ЭтотОбъектМетаданные,,Реквизит.Ключ) + " > значения колон" + ?(СтруктураОтбора.Количество() > 1,"ок","ки") + " < " + СтрокаРеквизитов + " > не уникальны ! Строки: " + Сред(ДублирующиесяСтроки,2)); КонецЕсли; КонецЕсли;
Вот теперь бы понять, на что кроме дублирование строк в ТЧ частях, влияет данный парамметр. Есть способ это узнать или только в процессе работы, когда-нибудь всплывет?
Группа: Местный
Сообщений: 2908
Из: Київ, Україна
Спасибо сказали: 1159 раз
Рейтинг: 1244.5
bizisoft @ Today, 16:22
, На отсутствии дублей номенклатуры в тч построены многие механизмы, в т. ч. партионное списание. Так что просто меняйте методику, чтобы не использовать дубли в тч.
Допрацьовую: - "Бухгалтерія для України 2.1"; - "Альфа-Авто: Автосалон+Автосервіс+Автозапчастини, українська версія".
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!