Создать справочник 1С программно в прикладной задаче — значит добавить в него элемент или группу из кода: товары из прайса поставщика, клиентов с сайта, контрагентов по ИНН из заявки. Схема одна: Справочники.Имя.СоздатьЭлемент() или СоздатьГруппу(), заполнение реквизитов, Записать(). Ниже — готовые функции для платформы 8.3: от одного элемента с проверкой заполнения до массовой загрузки номенклатуры в транзакции с ОбменДанными.Загрузка.
Объекты справочников есть на сервере, в толстом клиенте и во внешнем соединении, но не в тонком и веб-клиенте. Код создания кладут в серверный общий модуль, модуль менеджера или объекта обработки, а форма вызывает его через сервер. До кода посмотрите в конфигураторе свойства справочника: «Вид иерархии», «Владельцы», «Серии кодов», «Контроль уникальности», «Автонумерация», у реквизитов — «Проверка заполнения».
Универсальная функция ниже позволяет создать элемент справочника программно по имени справочника. Первая структура — то, от чего зависят умолчания, вторая — остальные значения.
// Создаёт и записывает элемент справочника, возвращает ссылку на него.
// ИмяСправочника - Строка - имя из ветки «Справочники» конфигуратора, например "Номенклатура".
// Основные - Структура, Неопределено - реквизиты, от которых зависят умолчания: Владелец,
// ВидНоменклатуры, Партнер. Ставятся до Заполнить() и передаются в неё как данные заполнения.
// Реквизиты - Структура - остальные значения, в том числе Наименование и Родитель.
Функция СоздатьЭлементСправочника(ИмяСправочника, Основные, Реквизиты) Экспорт
НовыйЭлемент = Справочники[ИмяСправочника].СоздатьЭлемент();
Если Основные <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(НовыйЭлемент, Основные);
КонецЕсли;
// СоздатьЭлемент() не вызывает ОбработкаЗаполнения и не ставит «Значение заполнения»
НовыйЭлемент.Заполнить(Основные);
// Свои значения - после умолчаний, иначе заполнение их перезапишет
ЗаполнитьЗначенияСвойств(НовыйЭлемент, Реквизиты);
ПроверитьЗаполнениеЭлемента(НовыйЭлемент);
// Код при включённой автонумерации платформа назначит сама
НовыйЭлемент.Записать();
Возврат НовыйЭлемент.Ссылка;
КонецФункции
// Вызывает исключение с причинами, если не заполнены обязательные реквизиты.
// Записать() из кода ОбработкаПроверкиЗаполнения не вызывает: её запускают
// только форма объекта и метод ПроверитьЗаполнение().
Процедура ПроверитьЗаполнениеЭлемента(Элемент) Экспорт
Было = ПолучитьСообщенияПользователю().Количество();
Если Элемент.ПроверитьЗаполнение() Тогда
Возврат;
КонецЕсли;
// Причины лежат в очереди сообщений: в фоновом задании их иначе никто не увидит
Сообщения = ПолучитьСообщенияПользователю();
Причины = Новый Массив;
Для Номер = Было По Сообщения.ВГраница() Цикл
Причины.Добавить(Сообщения[Номер].Текст);
КонецЦикла;
Если Причины.Количество() = 0 Тогда
Причины.Добавить(НСтр("ru = 'не пройдена проверка заполнения'"));
КонецЕсли;
ВызватьИсключение СтрШаблон(НСтр("ru = 'Элемент «%1» справочника %2 не записан: %3'"),
Элемент.Наименование, Элемент.Метаданные().Имя, СтрСоединить(Причины, "; "));
КонецПроцедуры
Вызов для номенклатуры и подчинённого справочника:
// УТ 11.4: товар. Вид номенклатуры - в «Основные»: по нему ОбработкаЗаполнения
// заполнит тип номенклатуры, ставку НДС, единицу хранения и другие реквизиты вида.
Основные = Новый Структура("ВидНоменклатуры", ВидНоменклатуры);
Реквизиты = Новый Структура("Наименование, НаименованиеПолное, Артикул, Родитель",
"Чайник 1,7 л", "Чайник электрический 1,7 л", "KT-1702", ГруппаЧайники);
Товар = СоздатьЭлементСправочника("Номенклатура", Основные, Реквизиты);
// Подчинённый справочник: владелец - тоже в «Основные», без него запись не пройдёт
Контакт = СоздатьЭлементСправочника("КонтактныеЛицаПартнеров",
Новый Структура("Владелец", Партнер), Новый Структура("Наименование", ФИО));
СоздатьЭлемент() даёт объект в памяти: до Записать() в базе его нет, ссылка и код пустые.Заполнить() запускает ОбработкаЗаполнения и стандартное дозаполнение пустых реквизитов «Значением заполнения» из их свойств. Без него номенклатура УТ 11.4 не получит, например, качество «Новый» и реквизиты вида.Заполнить() → остальные» важен: у нового товара УТ 11.4 заполнение по виду заменяет единицу и ставку НДС значениями вида, если они там заданы.ЗаполнитьЗначенияСвойств молча пропускает ключи, которых у объекта нет: опечатка в имени реквизита ошибки не даст.Записать() из кода не вызывает ОбработкаПроверкиЗаполнения — это делают только форма и ПроверитьЗаполнение(). Зато он проверяет уникальность кода, назначает код при автонумерации и вызывает ПередЗаписью и ПриЗаписи; любой отказ — исключение.Программно записать изменения в существующий элемент справочника можно тем же Записать(), только объект берут из базы:
// Изменить существующий элемент: объект читается из базы, правится и записывается
ТоварОбъект = Товар.ПолучитьОбъект();
ТоварОбъект.Артикул = "KT-1702-W";
ТоварОбъект.Записать();
Что задать в коде, а что заполнят обработчики типовой (сверено по УТ 11.4.14):
| Справочник | Задать в коде | Заполнит типовая |
|---|---|---|
| Номенклатура | ВидНоменклатуры — до Заполнить(); Наименование; ЕдиницаИзмерения, если её нет в виде (услугам и работам не обязательна) | Заполнить(): тип, ставка НДС, единица, группа доступа и прочее из вида; ПередЗаписью: Код, КодДляПоиска |
| Партнеры | Наименование, НаименованиеПолное, ЮрФизЛицо, хотя бы один из флажков Клиент, Поставщик, Конкурент, ПрочиеОтношения; ГруппаДоступа — если включены группы доступа | Заполнить(): ОсновнойМенеджер, ДатаРегистрации; код — при записи |
| Контрагенты | Партнер — через Заполнить(); ЮрФизЛицо; ИНН и КПП | Заполнить(): наименования по партнёру; ПередЗаписью: ЮридическоеФизическоеЛицо, ГоловнойКонтрагент |
В ПередЗаписью номенклатуры УТ 11.4 есть и исключения: пустое и неуникальное рабочее наименование (второе — при включённой константе КонтролироватьУникальностьРабочегоНаименованияНоменклатурыИХарактеристик). В КА 2.5 у номенклатуры нет ОбработкаЗаполнения: после Заполнить() вызовите Справочники.Номенклатура.ЗаполнитьРеквизитыПоВидуНоменклатуры(Элемент) — эта экспортная процедура есть в обеих конфигурациях.
ЭтоГруппа только для чтения, поэтому группа создаётся одним способом — СоздатьГруппу(). Место в дереве задаёт Родитель, пустая ссылка — верхний уровень. При виде иерархии «Иерархия групп и элементов» родителем бывает только группа, при «Иерархии элементов» групп нет и родитель — другой элемент (так у партнёров УТ 11.4). Функция находит группу по пути из файла и создаёт недостающие уровни.
// Группа справочника по пути "Бытовая техника/Чайники": недостающие уровни создаются.
// Для справочников с видом иерархии «Иерархия групп и элементов», например Номенклатура.
Функция ГруппаПоПути(ИмяСправочника, Путь) Экспорт
Менеджер = Справочники[ИмяСправочника];
Родитель = Менеджер.ПустаяСсылка();
Для Каждого ЧастьПути Из СтрРазделить(Путь, "/", Ложь) Цикл
ИмяГруппы = СокрЛП(ЧастьПути);
Группа = НайтиГруппу(ИмяСправочника, ИмяГруппы, Родитель);
Если Группа = Неопределено Тогда
// ЭтоГруппа только для чтения: группу даёт только СоздатьГруппу()
НоваяГруппа = Менеджер.СоздатьГруппу();
НоваяГруппа.Наименование = ИмяГруппы;
НоваяГруппа.Родитель = Родитель;
НоваяГруппа.Записать();
Группа = НоваяГруппа.Ссылка;
КонецЕсли;
Родитель = Группа;
КонецЦикла;
Возврат Родитель;
КонецФункции
// Непомеченная группа с точным наименованием внутри родителя или Неопределено.
Функция НайтиГруппу(ИмяСправочника, Наименование, Родитель)
Запрос = Новый Запрос(
"ВЫБРАТЬ ПЕРВЫЕ 1
| Группы.Ссылка КАК Ссылка
|ИЗ
| Справочник." + ИмяСправочника + " КАК Группы
|ГДЕ
| Группы.ЭтоГруппа
| И Группы.Родитель = &Родитель
| И Группы.Наименование = &Наименование
| И НЕ Группы.ПометкаУдаления");
Запрос.УстановитьПараметр("Родитель", Родитель);
Запрос.УстановитьПараметр("Наименование", Наименование);
Выборка = Запрос.Выполнить().Выбрать();
Возврат ?(Выборка.Следующий(), Выборка.Ссылка, Неопределено);
КонецФункции
НайтиПоНаименованию() тут не годится: вернёт первый объект с таким наименованием — возможно, элемент или помеченную на удаление группу.
Элемент подчинённого справочника принадлежит владельцу, и без Владелец запись завершится ошибкой. В УТ 11.4 так устроены КонтактныеЛицаПартнеров (владелец — партнёр) и базовые единицы измерения — элементы УпаковкиЕдиницыИзмерения с владельцем НаборыУпаковок.БазовыеЕдиницыИзмерения. Новый элемент справочника программно ищут и создают в пределах владельца:
// УТ 11.4: контактное лицо партнёра. Справочник подчинён справочнику Партнеры,
// поэтому и поиск дубля, и новый элемент - в пределах владельца.
Функция КонтактноеЛицоПартнера(Партнер, ФИО, Должность = "") Экспорт
// Четвёртый параметр - владелец: у разных партнёров бывают контакты с одинаковыми ФИО
Найденный = Справочники.КонтактныеЛицаПартнеров.НайтиПоНаименованию(ФИО, Истина, , Партнер);
Если ЗначениеЗаполнено(Найденный) Тогда
Возврат Найденный;
КонецЕсли;
Контакт = Справочники.КонтактныеЛицаПартнеров.СоздатьЭлемент();
// ОбработкаЗаполнения типовой: ссылка на партнёра становится владельцем,
// автор - текущий пользователь, дата регистрации связи - текущая дата
Контакт.Заполнить(Партнер);
Контакт.Наименование = ФИО;
Контакт.ДолжностьПоВизитке = Должность;
ПроверитьЗаполнениеЭлемента(Контакт);
Контакт.Записать();
Возврат Контакт.Ссылка;
КонецФункции
НайтиПоКоду, НайтиПоНаименованию и НайтиПоРеквизиту принимают владельца последним параметром, без него ищут по всему справочнику. Подробнее — в статье как получить ссылку.
Код задавать не нужно: при включённой «Автонумерации» платформа назначит его при записи с учётом «Серий кодов» — во всём справочнике, в пределах подчинения или в пределах подчинения владельцу. Нужен код до записи — вызовите УстановитьНовыйКод(). Для строкового кода можно передать префикс: УстановитьНовыйКод("ИМ-") возьмёт следующий за максимальным кодом с этим префиксом. При «Контроле уникальности» повтор кода в серии не даст записать элемент.
В типовых на БСП к коду добавляется префикс базы: в УТ 11.4 номенклатуре и партнёрам его ставит подписка УстановитьПрефиксИнформационнойБазыКодуСправочника на ПриУстановкеНовогоКода. Поэтому чужие коды в Код не пишите — для них есть Артикул или свой реквизит, а GUID с сайта делают ссылкой нового элемента через УстановитьСсылкуНового().
Формы типовых ловят дубли, код — нет: в УТ 11.4 проверка «ИНН и КПП уже указаны для другого контрагента» сидит в ОбработкаПроверкиЗаполнения, и Записать() её не запускает. Прежде чем добавить в справочник программно, ищите сами: контрагента — по ИНН и КПП, товар — по артикулу, контакт — по наименованию у владельца. Наименование — худший ключ: «ООО Ромашка» и «Ромашка ООО» для базы разные строки.
// УТ 11.4: контрагент по ИНН и КПП. Есть в базе - возвращает его, нет - создаёт
// партнёра и контрагента. ГруппаДоступа нужна, если включены группы доступа партнёров.
Функция НайтиИлиСоздатьКонтрагента(ИНН, КПП, Наименование, ГруппаДоступа = Неопределено) Экспорт
Если ПустаяСтрока(ИНН) Тогда
// По пустому ИНН нашёлся бы любой контрагент без ИНН
ВызватьИсключение НСтр("ru = 'Не указан ИНН контрагента'");
КонецЕсли;
НачатьТранзакцию();
Попытка
// Второй сеанс с тем же ИНН дождётся конца транзакции и найдёт уже созданного
Блокировка = Новый БлокировкаДанных;
Блокировка.Добавить("Справочник.Контрагенты");
Блокировка.Заблокировать();
Контрагент = КонтрагентПоИНН(СокрЛП(ИНН), СокрЛП(КПП));
Если Контрагент = Неопределено Тогда
Контрагент = НовыйКонтрагент(СокрЛП(ИНН), СокрЛП(КПП), Наименование, ГруппаДоступа);
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
Возврат Контрагент;
КонецФункции
// Непомеченный контрагент с этим ИНН и КПП (пустой КПП - поиск только по ИНН),
// головной раньше обособленных подразделений. Неопределено - не нашли.
Функция КонтрагентПоИНН(ИНН, КПП)
Запрос = Новый Запрос(
"ВЫБРАТЬ ПЕРВЫЕ 1
| Контрагенты.Ссылка КАК Ссылка
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.ИНН = &ИНН
| И (Контрагенты.КПП = &КПП ИЛИ &КПП = """")
| И НЕ Контрагенты.ПометкаУдаления
|
|УПОРЯДОЧИТЬ ПО
| Контрагенты.ОбособленноеПодразделение");
Запрос.УстановитьПараметр("ИНН", ИНН);
Запрос.УстановитьПараметр("КПП", КПП);
Выборка = Запрос.Выполнить().Выбрать();
Возврат ?(Выборка.Следующий(), Выборка.Ссылка, Неопределено);
КонецФункции
// Партнёр и контрагент: 10 цифр ИНН - юрлицо, 12 - индивидуальный предприниматель.
Функция НовыйКонтрагент(ИНН, КПП, Наименование, ГруппаДоступа)
Партнер = Справочники.Партнеры.СоздатьЭлемент();
// ОбработкаЗаполнения: наименование из структуры, основной менеджер, дата регистрации
Партнер.Заполнить(Новый Структура("Наименование", Наименование));
Партнер.НаименованиеПолное = Наименование;
Партнер.ЮрФизЛицо = Перечисления.КомпанияЧастноеЛицо.Компания;
Партнер.Клиент = Истина; // хотя бы один вид отношений обязателен
Если ГруппаДоступа <> Неопределено Тогда
Партнер.ГруппаДоступа = ГруппаДоступа;
КонецЕсли;
ПроверитьЗаполнениеЭлемента(Партнер);
Партнер.Записать();
Контрагент = Справочники.Контрагенты.СоздатьЭлемент();
// По ключу Партнер обработка заполнения возьмёт наименования у партнёра
Контрагент.Заполнить(Новый Структура("Партнер", Партнер.Ссылка));
Контрагент.ЮрФизЛицо = ?(СтрДлина(ИНН) = 12,
Перечисления.ЮрФизЛицо.ИндивидуальныйПредприниматель, Перечисления.ЮрФизЛицо.ЮрЛицо);
Контрагент.ИНН = ИНН;
Контрагент.КПП = КПП;
ПроверитьЗаполнениеЭлемента(Контрагент); // здесь же типовая проверка дубля ИНН и КПП
// ЮридическоеФизическоеЛицо и ГоловнойКонтрагент заполнит ПередЗаписью типовой
Контрагент.Записать();
Возврат Контрагент.Ссылка;
КонецФункции
Ссылка и поля из свойства «Поля блокировки данных», а у контрагентов УТ 11.4 оно пустое. Внутри долгой транзакции функцию не вызывайте (см. конфликт блокировок).ПроверитьЗаполнениеЭлемента — из первого листинга; заодно сработает типовая проверка дубля ИНН и КПП.Если новый товар отличается от существующего парой реквизитов, его проще скопировать:
// Новый элемент по образцу: копия получает реквизиты и табличные части образца.
// Изменения - Структура - чем копия отличается: Наименование, Артикул и т. п.
Функция СоздатьПоОбразцу(Образец, Изменения) Экспорт
// При копировании вместо ОбработкаЗаполнения вызывается ПриКопировании:
// там типовые очищают то, что копия наследовать не должна
Копия = Образец.Скопировать();
ЗаполнитьЗначенияСвойств(Копия, Изменения);
// Код - новый, если его не передали явно: не полагаемся на то, что досталось от образца
МетаданныеСправочника = Копия.Метаданные();
Если МетаданныеСправочника.ДлинаКода > 0 И МетаданныеСправочника.Автонумерация
И Не Изменения.Свойство("Код") Тогда
Копия.УстановитьНовыйКод();
КонецЕсли;
ПроверитьЗаполнениеЭлемента(Копия);
Копия.Записать();
Возврат Копия.Ссылка;
КонецФункции
// Товар по образцу: другие наименования и артикул, остальное - как у образца
Изменения = Новый Структура("Наименование, НаименованиеПолное, Артикул",
"Чайник 1,5 л", "Чайник электрический 1,5 л", "KT-1502");
НовыйТовар = СоздатьПоОбразцу(Образец, Изменения);
Скопировать() есть у ссылки и у объекта и возвращает незаписанную копию с реквизитами и табличными частями, включая дополнительные реквизиты БСП.ОбработкаЗаполнения вызывается ПриКопировании: в УТ 11.4 партнёр там получает основным менеджером текущего пользователя и новую дату регистрации, а у контрагента очищается ГоловнойКонтрагент, если образец был головным сам себе.ШтрихкодыНоменклатуры, ЦеныНоменклатуры, ДополнительныеСведения), присоединённые файлы, упаковки и характеристики.Массовая запись справочника программно упирается в транзакции и режим загрузки. Флаг ОбменДанными.Загрузка = Истина означает «данные уже проверены, запиши как есть». Платформа делает минимум проверок, а по стандарту 1С обработчики ПередЗаписью, ПриЗаписи, ПередУдалением и подписки на них сразу выходят: бизнес-логика пропускается, за целостность данных отвечает вызывающий код. Режим уместен для данных из базы той же конфигурации или правки служебного реквизита у тысяч элементов. Для новых товаров из прайса — только если сделать за типовую пропущенное. В УТ 11.4 при загрузке:
КодДляПоиска из типового ПередЗаписью, шаблоны наименований не применяются, пустое и неуникальное рабочее наименование не проверяется;ЮридическоеФизическоеЛицо и ГоловнойКонтрагент;ИерархияПартнеров;ОтключитьМеханизмРегистрацииОбъектов.Функция создаёт номенклатуру из таблицы значений (её удобно получить загрузкой из Excel) порциями в транзакциях, режим загрузки — параметр.
// УТ 11.4: массовое создание номенклатуры из таблицы значений.
// Товары - ТаблицаЗначений: Наименование, Артикул, Группа (путь вида "Бытовая техника/Чайники").
// Настройки - Структура:
// ВидНоменклатуры - по нему типовая заполнит тип, ставку НДС, единицу хранения;
// ЕдиницаИзмерения - если в виде номенклатуры единица не задана;
// РежимЗагрузки - Истина: запись с ОбменДанными.Загрузка, без логики ПередЗаписью и ПриЗаписи;
// РазмерПорции - сколько элементов писать в одной транзакции.
// Возвращает структуру: Создано, Пропущено (пустой или занятый артикул), Ошибки (массив строк).
Функция СоздатьНоменклатуру(Товары, Настройки) Экспорт
Если ТранзакцияАктивна() Тогда
// После отката порции её строки пишутся заново - во внешней транзакции это невозможно
ВызватьИсключение НСтр("ru = 'СоздатьНоменклатуру нельзя вызывать внутри транзакции'");
КонецЕсли;
Итог = Новый Структура("Создано, Пропущено, Ошибки", 0, 0, Новый Массив);
Занятые = СуществующиеАртикулы(Товары.ВыгрузитьКолонку("Артикул"));
// Группы - заранее и вне транзакций порций: откат порции
// не должен оставить в кэше ссылки на группы, которых нет в базе
Группы = Новый Соответствие;
Для Каждого Путь Из Товары.ВыгрузитьКолонку("Группа") Цикл
Если ЗначениеЗаполнено(Путь) И Группы[Путь] = Неопределено Тогда
Группы.Вставить(Путь, ГруппаПоПути("Номенклатура", Путь));
КонецЕсли;
КонецЦикла;
Порция = Новый Массив;
Для Каждого Товар Из Товары Цикл
Ключ = ВРег(СокрЛП(Товар.Артикул));
Если ПустаяСтрока(Ключ) Или Занятые[Ключ] <> Неопределено Тогда
Итог.Пропущено = Итог.Пропущено + 1;
Продолжить;
КонецЕсли;
Занятые.Вставить(Ключ, Истина); // повтор артикула в самом файле тоже пропустим
Порция.Добавить(Товар);
Если Порция.Количество() = Настройки.РазмерПорции Тогда
ЗаписатьПорцию(Порция, Настройки, Группы, Итог);
Порция.Очистить();
КонецЕсли;
КонецЦикла;
ЗаписатьПорцию(Порция, Настройки, Группы, Итог);
Возврат Итог;
КонецФункции
// Порция пишется в одной транзакции. Если она откатилась - построчно:
// исправные строки сохранятся, ошибочные попадут в Итог.Ошибки.
Процедура ЗаписатьПорцию(Порция, Настройки, Группы, Итог)
Если Порция.Количество() = 0 Тогда
Возврат;
КонецЕсли;
НачатьТранзакцию();
Попытка
Для Каждого Товар Из Порция Цикл
ЗаписатьТовар(Товар, Настройки, Группы);
КонецЦикла;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
Для Каждого Товар Из Порция Цикл
Попытка
ЗаписатьТовар(Товар, Настройки, Группы);
Итог.Создано = Итог.Создано + 1;
Исключение
Итог.Ошибки.Добавить(СтрШаблон("%1: %2", Товар.Артикул,
ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке())));
КонецПопытки;
КонецЦикла;
Возврат;
КонецПопытки;
Итог.Создано = Итог.Создано + Порция.Количество();
КонецПроцедуры
Процедура ЗаписатьТовар(Товар, Настройки, Группы)
Элемент = Справочники.Номенклатура.СоздатьЭлемент();
Если ЗначениеЗаполнено(Товар.Группа) Тогда
Элемент.Родитель = Группы[Товар.Группа];
КонецЕсли;
Элемент.ВидНоменклатуры = Настройки.ВидНоменклатуры;
Элемент.Заполнить(Неопределено); // реквизиты по виду и «Значение заполнения»
Элемент.Наименование = СокрЛП(Товар.Наименование);
Элемент.НаименованиеПолное = Элемент.Наименование;
Элемент.Артикул = СокрЛП(Товар.Артикул);
Если Не ЗначениеЗаполнено(Элемент.ЕдиницаИзмерения) Тогда
Элемент.ЕдиницаИзмерения = Настройки.ЕдиницаИзмерения;
КонецЕсли;
// Загрузка отключает обработчики записи, а не проверку заполнения - проверяем всегда
ПроверитьЗаполнениеЭлемента(Элемент);
Если Настройки.РежимЗагрузки Тогда
// ПередЗаписью номенклатуры при загрузке сразу выходит: код и код для поиска - сами
Элемент.УстановитьНовыйКод();
Элемент.КодДляПоиска = ПрефиксацияОбъектовКлиентСервер.НомерНаПечать(Элемент.Код, Истина);
Элемент.ОбменДанными.Загрузка = Истина;
КонецЕсли;
Элемент.Записать();
КонецПроцедуры
// Занятые артикулы: Соответствие "АРТИКУЛ В ВЕРХНЕМ РЕГИСТРЕ" -> ссылка.
Функция СуществующиеАртикулы(Артикулы)
Очищенные = Новый Массив;
Для Каждого Артикул Из Артикулы Цикл
Очищенные.Добавить(СокрЛП(Артикул));
КонецЦикла;
Запрос = Новый Запрос(
"ВЫБРАТЬ
| Номенклатура.Артикул КАК Артикул,
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Артикул В (&Артикулы)
| И НЕ Номенклатура.ЭтоГруппа");
Запрос.УстановитьПараметр("Артикулы", Очищенные);
Результат = Новый Соответствие;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Результат.Вставить(ВРег(СокрЛП(Выборка.Артикул)), Выборка.Ссылка);
КонецЦикла;
Возврат Результат;
КонецФункции
// Вызов. Единица «шт» в УТ 11.4 - элемент УпаковкиЕдиницыИзмерения с владельцем
// НаборыУпаковок.БазовыеЕдиницыИзмерения (наименование - как в вашей базе)
Штука = Справочники.УпаковкиЕдиницыИзмерения.НайтиПоНаименованию("шт", Истина, ,
Справочники.НаборыУпаковок.БазовыеЕдиницыИзмерения);
Настройки = Новый Структура("ВидНоменклатуры, ЕдиницаИзмерения, РежимЗагрузки, РазмерПорции",
ВидНоменклатуры, Штука, Ложь, 100);
Итог = СоздатьНоменклатуру(Товары, Настройки);
НайтиПоРеквизиту на строку; Артикул в УТ 11.4 индексирован.Итог.Ошибки. Во внешней транзакции так нельзя — после ошибки её можно только откатить, отсюда проверка ТранзакцияАктивна(). Шаблон — в статье про транзакции.Загрузка отключает обработчики записи, а не ПроверитьЗаполнение(), поэтому проверка работает в обоих режимах. Код и КодДляПоиска при загрузке заполняются так же, как в типовом ПередЗаписью.&НаСервере или серверный общий модуль.Заполнить() или вид номенклатуры задан после него.ПроверитьЗаполнение() в УТ 11.4: у товара нет единицы, и в виде она не задана. Без проверки товар записался бы без единицы.ПередЗаписью номенклатуры УТ 11.4. Не обходите их через ОбменДанными.Загрузка — получите дубли.НайтиПоНаименованию() по умолчанию сравнивает начало наименования: «Чайник» найдёт «Чайник 1,7 л». Передавайте ТочноеСоответствие = Истина.ОбменДанными.Загрузка без дозаполнения: ошибок нет, данные неполные.Нет. Справочник — объект метаданных: его добавляют в конфигураторе (ветка «Справочники» → «Добавить») или в расширении и обновляют конфигурацию базы. Код 1С:Предприятия создаёт только данные — элементы и группы.
Через сервер: команда формы вызывает процедуру &НаСервере или общий модуль с флажком «Вызов сервера», передаёт строки, числа, ссылки и получает обратно ссылку на новый элемент.
Вызовите УстановитьНовыйКод(): код появится сразу, с учётом серии кодов, а в типовых на БСП — и префикса базы. Иначе при автонумерации его назначит Записать().
До записи назначьте ссылку: НовыйЭлемент.УстановитьСсылкуНового(Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID))). Повторная загрузка найдёт элемент по GUID, а не по наименованию. Подробнее — в статье про уникальный идентификатор.
Если справочники должны наполняться из прайсов поставщиков, сайта или маркетплейсов — с сопоставлением по артикулам и ИНН, группами, единицами и журналом ошибок, — это отдельная доработка с проверкой на копии базы. Такие задачи берут исполнители площадки: доработка 1С, обмен с сайтом, выгрузка на маркетплейсы. Разместите задачу бесплатно: оценка тоже бесплатная, ответ — в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.