Здравствуйте.
1С:Предприятие 8.2 (8.2.19.130)
Альфа-Авто: А+А, украинская версия 4.1.19.01
Подскажите пожалуйста, возможно-ли перестроить первичный ключ справочника (Например Номенклатура).
Могу ошибиться в формулировках, поэтому попробую описать чего нужно добиться.
Имеется оригинальный товар с определенным артикулом например 26300-35505 производитель у оригинала допустим MOBIS
Также есть другой аналог от другого производителя (MANDO) со своим артикулом MOF4459.
Но при появлении аналога, не имеющего своего артикула приводит к тому, что в справочник нельзя добавить два одинаковых артикула из-за их неуникальности, т.к. Альфа проверяет уникальность товара по Артикулу.
Т.е. полу Производитель не несет никакой задачи, контролирующей уникальность, кроме как чисто информационную.
Можно-ли сделать составной ключ по двум полям Артикул+Производитель и выполнять проверку уникальности через такую связку, или сама Платформа/Конфигурация не позволяет такое делать?
Спрашивал у Рарус, они сказали, что контроль уникальности по Артикулу можно отключить, а по составному ключу (Артикул+Производитель) такого в Альфе нет и нет даже в планах. Больше технической информации у них получить мне не удалось, т.к. поддержка такую консультацию не оказывает.
Благодарю.
То о чем вы говорите - это не первичный ключ справочника. Это бизнес логика конкретной конфигурации. Поменять это можно. Найти в коде где происходит проверка и описать свою логику.
Vofka @ Сегодня, 16:23
,
Я правильно понимаю, что это должно быть где-то в модулях справочника Номенклатура или это может находится в любом месте конфигурации, включая и закрытые модули?
В ПолучитьОбязательныеРеквизиты отключаете уникальность. В ПередЗаписью пишете свой блек-джек.
Подумайте над тем, чтобы просто отключить уникальность по артикулу. Вдруг будет ситуация когда у одного производителя будут абсолютно разные запчасти без артикулов - ключ Производитель+Артикул также окажется неуникальным
Макс1С @ Вчера, 18:03
,
Спросил у Рарус, как отключить контроль уникальности и вот что они ответили:
//
Если обПраво("НомерПоКаталогуУникальный",Права) Тогда
ОбязательныеРеквизиты.Вставить("Артикул",3); // Это нужно закомментировать ?
КонецЕсли;
// Проверка на уникальность строк в табличной части "Состав набора".
Если (ВидНоменклатуры=Перечисления.ВидыНоменклатуры.Комплект) ИЛИ (ВидНоменклатуры=Перечисления.ВидыНоменклатуры.Набор) Тогда
ОбязательныеТовары = Новый Структура();
ОбязательныеТовары.Вставить("Номенклатура", 3); // Это нужно закомментировать ?
ОбязательныеТовары.Вставить("ХарактеристикаНоменклатуры", 2);
ОбязательныеРеквизиты.Вставить("СоставНабора", ОбязательныеТовары);
КонецЕсли;
bizisoft @ Today, 13:09
,
Закоментировать необходимо только первый фрагмент.
Petre @ Сегодня, 14:52
,
Я уже не удержался так и поступил.
А ПерезЗаписью добавил:
//--- перед записью нового элемента
Если (НЕ ЭтоГруппа) И (ЭтоНовый()) Тогда
ТекАртикул = Артикул;
ТекПроизводитель = Производитель;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Артикул,
| Номенклатура.Наименование,
| Номенклатура.Производитель
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Артикул = &Артикул
| И Номенклатура.Производитель = &Производитель";
Запрос.УстановитьПараметр("Артикул", ТекАртикул);
Запрос.УстановитьПараметр("Производитель", ТекПроизводитель);
Результат = Запрос.Выполнить();
ТЗПоиск = Результат.Выгрузить();
Если ТЗПоиск.Количество() > 0 Тогда
Предупреждение("Товар: "+Строка(ТекАртикул)+" ( "+Строка(ТекПроизводитель)+" ) уже существует");
Отказ = Истина;
КонецЕсли;
КонецЕсли;
//--- перед записью после при редактировании имеющейся записи
Если (НЕ ЭтоГруппа) Тогда
ТекАртикул = Артикул;
ТекПроизводитель = Производитель;
ТекКод = Код;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Артикул КАК Артикул,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Производитель КАК Производитель,
| Номенклатура.Код КАК Код
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Артикул = &Артикул
| И Номенклатура.Производитель = &Производитель
| И Номенклатура.Код <> &Код";
Запрос.УстановитьПараметр("Артикул", ТекАртикул);
Запрос.УстановитьПараметр("Производитель", ТекПроизводитель);
Запрос.УстановитьПараметр("Код", ТекКод);
Результат = Запрос.Выполнить();
ТЗПоиск = Результат.Выгрузить();
Если ТЗПоиск.Количество() > 0 Тогда
Предупреждение("Недопустимая операция для: "+Строка(ТекАртикул)+" ( "+Строка(ТекПроизводитель)+" ) [ "+Строка(ТекКод)+" ] уже существует."+Символы.ПС+"Вероятно был изменен Артикул или Производитель");
Отказ = Истина;
КонецЕсли;
КонецЕсли;
bizisoft @ Сегодня, 14:46
,
в целях оптимизации можете оставить только второй запрос-проверку, он будет покрывать и первый случай. единственное - я бы изменил условие на ссылку вместо кода
| И Номенклатура.Ссылка <> &Ссылка";
Запрос.УстановитьПараметр("Артикул", ТекАртикул);
Запрос.УстановитьПараметр("Производитель", ТекПроизводитель);
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Макс1С @ Вчера, 16:42
,
Нашел в модуле документа
Функция ПолучитьОбязательныеРеквизиты() Экспорт
// Обязательные поля таблицы товаров
ОбязательныеТовары=Новый Структура();
// ОбязательныеТовары.Вставить("Номенклатура",3); // <<<==========
ОбязательныеТовары.Вставить("Количество",1);
ОбязательныеТовары.Вставить("ЕдиницаИзмерения",3);
ОбязательныеТовары.Вставить("Коэффициент",1);
ОбязательныеТовары.Вставить("ХарактеристикаНоменклатуры",2);
// Обязательные реквизиты документа
ОбязательныеРеквизиты=Новый Структура();
ОбязательныеРеквизиты.Вставить("Организация",1);
ОбязательныеРеквизиты.Вставить("ПодразделениеКомпании",1);
ОбязательныеРеквизиты.Вставить("Автор",1);
ОбязательныеРеквизиты.Вставить("ВалютаДокумента",1);
ОбязательныеРеквизиты.Вставить("КурсДокумента",1);
Если ХозОперация <> Справочники.ХозОперации.УслугиСтороннихОрганизаций Тогда
ОбязательныеРеквизиты.Вставить("СкладКомпании",1);
КонецЕсли;
ОбязательныеРеквизиты.Вставить("Контрагент",1);
ОбязательныеРеквизиты.Вставить("ТипЦен",1);
ОбязательныеРеквизиты.Вставить("ХозОперация",1);
ОбязательныеРеквизиты.Вставить("ДоговорВзаиморасчетов",1);
ОбязательныеРеквизиты.Вставить("Товары",ОбязательныеТовары);
Возврат ОбязательныеРеквизиты;
КонецФункции // ПолучитьОбязательныеРеквизиты()
Petre @ Сегодня, 10:22
,
Для начала хотел обкатать это в Поступление товаров, т.к. бывает, что от поставщика в одном приходе приходит одинаковый товар (один артикул, одного производителя), но с разной ценой
Например:
54651-2Е000 Mobis 10 100.00
54651-2Е000 Mobis 20 150.00
Соответственно если есть подобный приход, то возможно может быть случай, когда на сайте клиент заказывает одинаковый товар, но с разных складов (допустим ему нужно 4 шт, а есть по 2 на разных складах), склады могут быть как Продавца, так и его поставщика.
Исходя из этого, то получается сюда подпадает и ЗаказПокупателя, РеализацияТоваров, возможно СчетНаОплату и вероятно и НалоговаяНакладная.
Вопрос модератору: В ходе решения проверки уникальности в номенклатуре, возник второстепенный вопрос, но т.к. в правилах написано Новый вопрос = Новая тема, можно-ли его задать в этой теме или все же создать по нему свою тему?
А вот собственно сам вопрос:
Т.к. получилось сделать проверку уникальности по Арт+Бренд и решить следующую аналогичную проблему с добавлением Аналогов (также не разрешало одинаковый Арт), в форме подбора номенклатуры в ТабличномПоле списка аналогов нарушилась механика (как обозвать то) "навигации", т.е. если в списке Аналогов дблКлик по строке аналога, то он должен быть найден и спозиционирован на соответствующем элементе списка номенклатуры.
Но в связи с тем, что поиск происходит через Найти(), в которой в качестве аргумента передается значение Артикул, то для товаров с одинаковым артикулом, но разными производителями, то поиск и позиционирование происходит не так как раньше, позиционирование происходит рандомно.
В метод Найти() как я понял нельзя добавить еще один аргумент, чтобы искал по Арт+Бренд.
Пробовал НайтиСтроки()
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Артикул", ВыбраннаяСтрока.Артикул);
ПараметрыОтбора.Вставить("Бренд", ВыбраннаяСтрока.Бренд);
НайденныеСтроки = АналогиОбъединеное1.НайтиСтроки(ПараметрыОтбора);
ЭлементыФормы.АналогиОбъединеное1.ТекущаяСтрока = НайденныеСтроки[0]
Если ВыбраннаяСтрока=Неопределено Тогда Возврат; КонецЕсли;
НайденныйАналог=Справочники.Номенклатура.НайтиПоРеквизиту("АртБренд",ВыбраннаяСтрока.АртБренд); //НайтиПоРеквизиту("Артикул",ВыбраннаяСтрока.Артикул);
Если обЗначениеНеЗаполнено(НайденныйАналог) Тогда Возврат; КонецЕсли;
СтандартнаяОбработка=Ложь;
// Позиционирование в списке номенклатуры
ЭлементыФормы.Список.ТекущаяСтрока=НайденныйАналог;
// позиционирование в списке аналогов
ЭлементыФормы.АналогиОбъединеное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);
ОбязательныеРеквизиты.Вставить("Организация",1);
ОбязательныеРеквизиты.Вставить("ПодразделениеКомпании",1);
ОбязательныеРеквизиты.Вставить("ВалютаДокумента",1);
ОбязательныеРеквизиты.Вставить("КурсДокумента",1);
ОбязательныеРеквизиты.Вставить("Контрагент",1);
ОбязательныеРеквизиты.Вставить("ТипЦен",1);
ОбязательныеРеквизиты.Вставить("ХозОперация",1);
ОбязательныеРеквизиты.Вставить("ДоговорВзаиморасчетов",1);
ОбязательныеРеквизиты.Вставить("СрокПоставки",1);
ОбязательныеРеквизиты.Вставить("Товары",ОбязательныеТовары);
ОбязательныеРеквизиты.Вставить("РаспределениеЗаказа",ОбязательныеРаспределение);
Возврат ОбязательныеРеквизиты;
КонецФункции // ПолучитьОбязательныеРеквизиты()
Кое что удалось найти.
В модуле общем модуле дкДокументы в функции дкПроверитьКорректность(.....) закомментировал строку Результат = Ложь; и вроде теперь можно добавлять две одинаковые строки в ТЧ документов, при этом я еще убрал комментирование со строк из постов выше.
// необходимо исключить проверку уникальности для сотовых платежей
Если НЕ ЭтоПлатеж Тогда
// поищем строки удовлетворяющие структуре отбора
НайденныеСтроки = ТабличнаяЧасть.НайтиСтроки(СтруктураОтбора);
// если нашли и их больше 1, то строки не уникальные
Если НайденныеСтроки.Количество() > 1 Тогда
// добавим строку в список найденных дублей, что бы не сообщать о ней еще раз
// ===> Результат = Ложь;
ДублирующиесяСтроки = "";
// выведем строку сообщения...
Для каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ДублирующиесяСтроки = ДублирующиесяСтроки + "," + СокрЛП(НайденнаяСтрока.НомерСтроки);
// добавим строку в список найденных дублей, что бы не сообщать о ней еще раз
СписокНайденныхДублей.Добавить(НайденнаяСтрока);
КонецЦикла;
СтрокаРеквизитов = "";
Для каждого РеквизитТаблицы Из СтруктураОтбора Цикл
СтрокаРеквизитов = СтрокаРеквизитов + ?(ПустаяСтрока(СтрокаРеквизитов),"",",") + РеквизитТаблицы.Ключ;
КонецЦикла;
дкДобавитьОшибку(Ошибки,"Таблица < " + обПолучитьСинонимРеквизита(ЭтотОбъектМетаданные,,Реквизит.Ключ) + " > значения колон" + ?(СтруктураОтбора.Количество() > 1,"ок","ки") + " < " + СтрокаРеквизитов + " > не уникальны ! Строки: " + Сред(ДублирующиесяСтроки,2));
КонецЕсли;
КонецЕсли;
bizisoft @ Today, 16:22
,
На отсутствии дублей номенклатуры в тч построены многие механизмы, в т. ч. партионное списание. Так что просто меняйте методику, чтобы не использовать дубли в тч.
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua