Как реализовать быстрый поиск номенклатуры и характеристики по короткому коду в УТ 11?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

В практической работе оптовых и розничных торговых компаний часто возникает задача максимального ускорения ввода данных в документы. Менеджеры, работающие с постоянным или ограниченным ассортиментом, наизусть знают внутренние короткие коды товаров. В конфигурации «1С:Управление торговлей 11» при использовании характеристик стандартный поиск может требовать от пользователя сначала выбрать номенклатуру, а затем во всплывающем окне искать нужную характеристику. Это существенно замедляет процесс работы.

Рассмотрим, как реализовать удобный механизм, при котором ввод короткого трехзначного кода в документе (например, в «Заказе клиента» или «Реализации товаров и услуг») будет автоматически заполнять и Номенклатуру, и Характеристику. Мы проанализируем различные архитектурные варианты решения этой задачи, оценим их плюсы и минусы, а также разберем примеры программного кода для реализации.

В зависимости от бизнес-логики предприятия и требований к уникальности кодов можно выделить четыре основных метода реализации этой задачи.

---

Вариант 1. Использование дополнительного реквизита в справочнике «Характеристики»

Этот вариант является одним из самых простых и логичных с точки зрения структуры метаданных. Поскольку характеристика в системе 1С всегда подчинена конкретной номенклатуре (или виду номенклатуры), то, найдя конкретную характеристику, мы автоматически получаем и ее владельца — номенклатуру. Таким образом, нам достаточно хранить короткий код в самой характеристике.

Проанализируем шаги по реализации этого механизма:

  1. Добавление реквизита: Расширим справочник ХарактеристикиНоменклатуры (или добавим через механизм дополнительных реквизитов и сведений, либо через расширение конфигурации) новым реквизитом Шифр (тип: Строка, длина 3–5 символов).
  2. Индексация реквизита: Для обеспечения высокой скорости поиска обязательно установим свойство Индексировать для нового реквизита в значение "Индексировать" или "Индексировать с доп. упорядочиванием".
  3. Перехват ввода на форме: В форме документа, в обработчике события поля ввода номенклатуры или в специализированном поле, будем производить поиск характеристики по введенному коду.

Рассмотрим пример кода, который выполняет поиск характеристики по введенному шифру и заполняет строку табличной части документа. Данный код целесообразно разместить в модуле формы документа (или в расширении формы):


&НаСервереБезКонтекста
Функция НайтиНоменклатуруИХарактеристикуПоШифру(Знач ВведенныйШифр)
	
	РезультатПоиска = Новый Структура("Номенклатура, Характеристика, Найдено", Неопределено, Неопределено, Ложь);
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 2
		|	Характеристики.Владелец КАК Номенклатура,
		|	Характеристики.Ссылка КАК Характеристика
		|ИЗ
		|	Справочник.ХарактеристикиНоменклатуры КАК Характеристики
		|ГДЕ
		|	Характеристики.Шифр = &Шифр";
		
	Запрос.УстановитьПараметр("Шифр", СокрЛП(ВведенныйШифр));
	
	Выборка = Запрос.Выполнить().Выбрать();
	Если Выборка.Количество() = 1 Тогда
		Выборка.Следующий();
		РезультатПоиска.Номенклатура = Выборка.Номенклатура;
		РезультатПоиска.Характеристика = Выборка.Характеристика;
		РезультатПоиска.Найдено = Истина;
	ИначеЕсли Выборка.Количество() > 1 Тогда
		// Код не уникален, требуется интерактивный выбор пользователя (обработаем отдельно)
		РезультатПоиска.Найдено = Ложь;
	КонецЕсли;
	
	Возврат РезультатПоиска;
	
КонецФункции

Преимущества метода: Простота реализации, данные хранятся непосредственно внутри объектов справочника характеристик. При удалении характеристики автоматически очищается и её шифр.

Недостатки: Если характеристики используются общие для вида номенклатуры, то шифр будет жестко привязан к характеристике в рамках всего вида. Если в рамках разных номенклатур одного вида должны быть одинаковые шифры для разных физических позиций — возникнет коллизия неуникальности.

---

Вариант 2. Использование регистра сведений для хранения ассоциаций

Если короткие коды могут быть неуникальными в рамках всей базы данных (например, уникальность должна соблюдаться только внутри определенной коллекции, сезона или группы товаров), или если характеристики назначены общими для видов номенклатуры, оптимальным решением будет создание отдельного регистра сведений.

Создадим новый независимый регистр сведений _КороткиеКодыНоменклатуры со следующей структурой:

Для реализации ввода переопределим поведение ячейки ввода номенклатуры в табличной части «Товары». Для этого используем событие ТоварыНоменклатураОкончаниеВводаТекста:


&НаКлиенте
Процедура ТоварыНоменклатураОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, СтандартнаяОбработка)
	
	// Если введен текст похожий на наш короткий код (например, длина до 4 символов и состоит из цифр)
	Если СтрДлина(СокрЛП(Текст)) <= 4 Тогда
		
		СтандартнаяОбработка = Ложь;
		ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
		
		Если ТекущаяСтрока = Неопределено Тогда
			Возврат;
		КонецЕсли;
		
		// Вызываем серверный поиск по регистру
		ДанныеКода = ПолучитьДанныеПоКороткомуКоду(Текст);
		
		Если ДанныеКода.Найдено Тогда
			ТекущаяСтрока.Номенклатура = ДанныеКода.Номенклатура;
			
			// Программно вызываем обработчик изменения номенклатуры для заполнения цен, ставок НДС и т.д.
			ТоварыНоменклатураПриИзмененииНаСервере(ТекущаяСтрока.ПолучитьИдентификатор());
			
			// Устанавливаем характеристику
			ТекущаяСтрока.Характеристика = ДанныеКода.Характеристика;
			ТоварыХарактеристикаПриИзмененииНаСервере(ТекущаяСтрока.ПолучитьИдентификатор());
		Иначе
			ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Код не найден или найдено несколько совпадений!");
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

В серверной части формы реализуем функцию поиска, которая будет обращаться к нашему регистру сведений:


&НаСервереБезКонтекста
Функция ПолучитьДанныеПоКороткомуКоду(Знач ВведенныйКод)
	
	Результат = Новый Структура("Номенклатура, Характеристика, Найдено", Неопределено, Неопределено, Ложь);
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ РАЗРЕШЕННЫЕ
		|	Коды.Номенклатура КАК Номенклатура,
		|	Коды.Характеристика КАК Характеристика
		|ИЗ
		|	РегистрСведений._КороткиеКодыНоменклатуры КАК Коды
		|ГДЕ
		|	Коды.Код = &Код";
		
	Запрос.УстановитьПараметр("Код", СокрЛП(ВведенныйКод));
	
	Выборка = Запрос.Выполнить().Выбрать();
	Если Выборка.Количество() = 1 Тогда
		Выборка.Следующий();
		Результат.Номенклатура = Выборка.Номенклатура;
		Результат.Характеристика = Выборка.Характеристика;
		Результат.Найдено = Истина;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Важное примечание: Чтобы при программной установке номенклатуры в документе корректно заполнились все сопутствующие реквизиты строки (базовые единицы измерения, цены, ставки НДС, упаковки), необходимо обязательно вызывать встроенные процедуры пересчета строки, такие как ТоварыНоменклатураПриИзмененииСервер, перенося логику аналогично интерактивному выбору в типовой конфигурации.

---

Вариант 3. Адаптация штатного механизма работы со штрихкодами

Мало кто задумывается о том, что короткий трехзначный код — это по сути текстовое представление некоего штрихкода. В УТ 11 уже существует штатный регистр сведений ШтрихкодыНоменклатуры, который хранит связку штрихкода с номенклатурой и характеристикой. Он идеально оптимизирован для быстрого поиска.

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

  1. Регистрация кодов: В карточке номенклатуры (вкладка штрихкодов) регистрируем наши короткие трехзначные коды (например, "101", "102"). Программа позволяет записывать любые строки в качестве штрихкода (включая не соответствующие стандартам EAN).
  2. Использование формы ввода: В документах УТ 11 присутствует встроенная кнопка «Поиск по штрихкоду» (горячая клавиша F7). При нажатии на нее открывается окно ввода. Если пользователь введет туда "101" вручную и нажмет Enter, система автоматически отработает поиск по регистру штрихкодов, найдет сопоставленную номенклатуру и характеристику, добавит их в документ и произведет все необходимые калькуляции.

Если мы хотим избавиться от необходимости нажимать клавишу F7, мы можем перехватывать ввод непосредственно в колонке номенклатуры и программно передавать текстовое значение в процедуру обработки штрихкодов общего модуля конфигурации.

Проанализируем пример перехвата ввода в табличной части и вызова стандартного поиска:


&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
	
	ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
	Если ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	// Если пользователь ввел короткое цифровое значение в поле поиска номенклатуры
	ВведенныйТекст = Элемент.ВыделенныйТекст;
	Если СодержитТолькоЦифры(ВведенныйТекст) И СтрДлина(ВведенныйТекст) <= 3 Тогда
		
		// Вызываем штатный метод обработки штрихкода
		ДанныеШтрихкода = Новый Массив;
		ДанныеШтрихкода.Добавить(Новый Структура("Штрихкод", ВведенныйТекст));
		
		// Обрабатываем штрихкод стандартным механизмом УТ 11
		СтруктураПараметровКлиента = Новый Структура;
		ШтрихкодированиеНоменклатурыКлиент.ОбработатьШтрихкоды(ДанныеШтрихкода, ЭтотОбъект, СтруктураПараметровКлиента);
		
	КонецЕсли;
	
КонецПроцедуры

Преимущества: Использование 100% типовой бизнес-логики. Не нужно писать свои запросы поиска, алгоритмы добавления строк в табличную часть, расчеты скидок и цен — все это выполнит штатный общий модуль обработки штрихкодов УТ 11.

---

Вариант 4. Поле «Быстрого ввода» над табличной частью (Лучший UX/UI)

При вводе кодов непосредственно в строки табличной части пользователи часто жалуются на то, что сбивается фокус ввода, курсор скачет по колонкам, и приходится постоянно использовать мышь. Разберем альтернативное и максимально эргономичное решение — вынесение специального поля быстрого ввода над табличной частью «Товары».

Добавим на форму документа реквизит БыстрыйВводКода (тип: Строка) и разместим его на форме непосредственно над табличной частью товаров. Установим для него свойство КнопкаВыбора в значение Ложь, а для события ПриИзменении напишем обработчик.

Сценарий взаимодействия будет выглядеть следующим образом:

  1. Клавиатурный фокус всегда находится в поле «Быстрый ввод кода».
  2. Оператор набирает код, например, "105" и нажимает клавишу Enter.
  3. Система ищет товар по коду (через регистр ассоциаций или реквизит характеристики).
  4. Если товар найден: строка добавляется в конец табличной части (или увеличивается количество на 1, если такой товар уже был в документе).
  5. Поле ввода автоматически очищается, фокус ввода остается в нем же. Оператор сразу может вводить следующий код без лишних кликов.

Пример реализации обработчика изменения для поля быстрого ввода:


&НаКлиенте
Процедура БыстрыйВводКодаПриИзменении(Элемент)
	
	КодДляПоиска = СокрЛП(БыстрыйВводКода);
	Если ПустаяСтрока(КодДляПоиска) Тогда
		Возврат;
	КонецЕсли;
	
	// Очищаем поле ввода сразу, чтобы пользователь видел готовность к следующему вводу
	БыстрыйВводКода = "";
	
	// Выполняем поиск связки Номенклатура + Характеристика
	ДанныеТовара = НайтиНоменклатуруИХарактеристикуПоШифру(КодДляПоиска);
	
	Если ДанныеТовара.Найдено Тогда
		
		// Проверяем, есть ли уже такой товар в ТЧ, чтобы увеличить количество
		ПараметрыОтбора = Новый Структура("Номенклатура, Характеристика", ДанныеТовара.Номенклатура, ДанныеТовара.Характеристика);
		НайденныеСтроки = Объект.Товары.НайтиСтроки(ПараметрыОтбора);
		
		Если НайденныеСтроки.Количество() > 0 Тогда
			ТекущаяСтрока = НайденныеСтроки[0];
			ТекущаяСтрока.Количество = ТекущаяСтрока.Количество + 1;
			// Вызываем штатные процедуры пересчета суммы строки
			ОбработатьИзменениеКоличестваНаСервере(ТекущаяСтрока.ПолучитьИдентификатор());
		Иначе
			// Добавляем новую строку
			НоваяСтрока = Объект.Товары.Добавить();
			НоваяСтрока.Номенклатура = ДанныеТовара.Номенклатура;
			
			// Оповещаем серверную часть для инициализации строки
			ИнициализироватьНовуюСтрокуНаСервере(НоваяСтрока.ПолучитьИдентификатор());
			
			НоваяСтрока.Характеристика = ДанныеТовара.Характеристика;
			НоваяСтрока.Количество = 1;
			
			// Вызываем серверные процедуры расчета цен
			ОбработатьИзменениеХарактеристикиНаСервере(НоваяСтрока.ПолучитьИдентификатор());
		КонецЕсли;
		
	Иначе
		// Если найдено несколько позиций с таким кодом, откроем форму выбора
		ОткрытьФормуВыбораДляНеуникальногоКода(КодДляПоиска);
	КонецЕсли;
	
КонецПроцедуры

Преимущества метода: Это самый быстрый способ ввода с клавиатуры. Фокус ввода не теряется, пользователю не нужно перемещаться по строкам и колонкам. Данный метод широко используется на кассовых узлах и складах при ручной комплектации заказов.

---

Резюме и рекомендации

Мы проанализировали четыре различных подхода к реализации быстрого поиска номенклатуры и характеристики по короткому коду в УТ 11. Подводя итог, дадим следующие рекомендации разработчикам:

← На главную