новое событие
Информационный поток
Задания вакансии материалы разработки сообщения форума

Интеллектуальная загрузка данных и нечеткий поиск.

  • Добавить свою публикацию
  • для этого требуется регистрация

 

Практически в каждой организации в один прекрасный день начальнику приходит в голову  мысль облегчить жизнь простым кладовщикам. Они, бедные набивают приходные накладные, в то время как их присылают нам по почте в электронном виде. И озадачивают штатного или  внештатного программиста  задачей сделать загрузку приходных накладных автоматической. Программист берется за дело и решает ее в короткий срок, что может быть проще взять файл (как правило, это документ екселя) и пробежаться по колонкам определяя  колонку с наименованием номенклатуры, количеством, ценой. Как правило  делают простую проверку – нашли номенклатуру по наименованию – выбрали,  если не нашли номенклатуру - создаем новую автоматически и плевать что отличие только в запятой, все равно это новая номенклатура. Это приводит к тому, что справочник номенклатуры раздувается, и  у нас появляются множество дублей номенклатуры, выбрать правильную становится труднее и начинаются проблемы с пересортицей, инвентаризацией и прочим. Если программист более опытный он выведет форму диалога, где предложит пользователю, который загружает данные, выбрать правильную номенклатуру или создать новую. Идеально если поиск при этом будет интеллектуальным и предложит  варианты, которые имеют незначительные отклонения в названии номенклатуры. Давайте попробуем создать нечто подобное.

Сначала создадим обработку в ней нашу основную форму, на которой  Поле табличного документа в первую колонку мы буде вносить наименование товара,  а во вторую количество, цена будет жить в третей колонке.

 

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

  1. Сначала ищем точное соответствие наименования
  2. если не нашли, ищем по таблице соответствий (данная таблица будет содержать две колонки в первой наименование номенклатуры поставщика во второй номенклатура из нашей базы.
  3. в случае неудачи предыдущих пунктов задействуем нечеткий поиск, если нашли и пользователь выбрал один из предложенных вариантов то соответствие «название поставщика» - «номенклатура выбранная пользователем» заносится в  таблицу соответствий. Таким чином у нас получается система с элементами самообучения.
  4. Не следует забывать также о возможности создания новой номенклатуры.

 

Общая структура обработки такая:

 Изображение

 

Основная форма выглядит так:

 Изображение

И имеет следующий код:

Процедура КоманднаяПанель1Настройки(Кнопка)
	    // Вставить содержимое обработчика.
	    форма = получитьформу("ФормаСохраненнихРешений");
	    форма.Открыть();
КонецПроцедуры
 
Процедура КнопкаВыполнитьНажатие(Кнопка)
	    // Вставить содержимое обработчика.
	   
	    КоличествоЭлементов = этаформа.ЭлементыФормы.ПолеТабличногоДокумента1.ВысотаТаблицы ;
	    //Если КоличествоЭлементов <= 0 Тогда
	    Предупреждение(КоличествоЭлементов);
	    Для К = 2 По КоличествоЭлементов Цикл
	    	    сообщить(этаформа.ЭлементыФормы.ПолеТабличногоДокумента1.Область("R"+Формат(к,"ЧГ=")+"C"+Формат(1,"ЧГ=")).Текст);
	    	    названиеТМЦ=этаформа.ЭлементыФормы.ПолеТабличногоДокумента1.Область("R"+Формат(к,"ЧГ=")+"C"+Формат(1,"ЧГ=")).Текст;	   
	    	    КоличествоТМЦ=этаформа.ЭлементыФормы.ПолеТабличногоДокумента1.Область("R"+Формат(к,"ЧГ=")+"C"+Формат(2,"ЧГ=")).Текст;
	    	    ЦенаТМЦ=этаформа.ЭлементыФормы.ПолеТабличногоДокумента1.Область("R"+Формат(к,"ЧГ=")+"C"+Формат(3,"ЧГ=")).Текст;
			   
	    Сообщить(найтиТМЦ(названиеТМЦ));
			   
			   
	    конеццикла;  
	   
	     
	   
КонецПроцедуры
 
функция найтиТМЦ (наименованиеТМЦ)
	    перем ТаблицаСоответствий;
	    // данная функция ищет номенклатуру
	    // сначала по наименованию
	    // если не нашла по таблице соответствий
	    // и в последнюю очередь задействует нечеткий поиск
	    ТаблицаСоответствий = ВосстановитьЗначение("тс");
			   
	    ТМЦ =	    справочники.Номенклатура;
	    //ищем по точное соответствие наименованию
	    ТмцСсылка=ТМЦ.НайтиПоНаименованию(наименованиеТМЦ,истина);
	    если ТмцСсылка = ТМЦ.ПустаяСсылка() тогда
			   
			    // точное соответствие  по наименованию не найдено
			    // включаем поиск по таблице соответствий
			     
			    НайденнаяСтрока = ТаблицаСоответствий.Найти(наименованиеТМЦ, "Наименование");
			    Если НайденнаяСтрока = Неопределено Тогда
				  
				  
				  
				  
				   // опять ничего не найдено нужно задействовать нечеткий поиск
				   // тут все что разбирали в предыдущих примерах
				   МассивОтбор = Новый Массив();
				   МассивОтбор.Добавить(Метаданные.Справочники.Номенклатура);
				  
				  
				   Если Не ПолнотекстовыйПоиск.ИндексАктуален() Тогда
						   Попытка
							   Предупреждение("Пробуем обновить индекс. Это может занять некоторое время");
							   ПолнотекстовыйПоиск.ОбновитьИндекс(Истина, Ложь);
							   Предупреждение("Все хорошо индекс обновлен!");
	    				   Исключение
							   Предупреждение(("Упс! Ошибка при обновлении индекса!") + ОписаниеОшибки());
						   КонецПопытки;
				   КонецЕсли;
				  
				  
				   СписокПоиска = ПолнотекстовыйПоиск.СоздатьСписок("", 10); // первый параметр строка поиска, второй размер списка
				  
	    			    // указываем, в каких объектах искать строку
				   СписокПоиска.ОбластьПоиска = МассивОтбор;
				  
				   СписокПоиска.ПолучатьОписание = Истина;
				  
				   ПоказыватьОписания = Истина;
				   СписокПоиска.ПорогНечеткости = 25;  //процент нечеткости для слова из 4 букв, одна может быть неправильной
				  
				  
				   СписокПоиска.СтрокаПоиска = наименованиеТМЦ; // текст поиска можно задать и так
				   СписокПоиска.РазмерПорции = 10; // а ето, сколько стандартно будет вывожится результатов
				   СписокПоиска.ПерваяЧасть();
				   Колво = СписокПоиска.ПолноеКоличество();
				   Если СписокПоиска.ПолноеКоличество() = 0 Тогда
						   Предупреждение("Начего не найдено!" );
						   Если СписокПоиска.СлишкомМногоРезультатов() Тогда
							   Предупреждение("Найдено слишком много результатов!");
						   КонецЕсли;
				   КонецЕсли;
				   // теперь мы получаем в списке поиска массив объектов номенклатуры
				   // которые в могут соответствовать названию номенклатуры
				   // даже если найден только один объект пользователь должен
				   // согласится с предложенным выбором
				  
				   // для начала очистим список выбора
				  
				   Списоквыбора.Очистить();
				   Для х =  1 По мин(СписокПоиска.ПолноеКоличество(),10) Цикл
						   ВыбраннаяСтрока = списокПоиска[х-1];
						   списоквыбора.Добавить(ВыбраннаяСтрока.Значение);
						  
				   КонецЦикла;
				   НазваниеТМЦ=наименованиеТМЦ ;  // общий реквищит чтобы отобразился в форме выбора
				   форма = получитьформу("ФормаВыбораВариантов");
				   ТмцСсылка = форма.ОткрытьМодально();
				   если ( ТмцСсылка = неопределено) тогда
						   Сообщить("Вы ничего не выбрали, данная строка не импортируется!");	
				   иначе
						   // если пользователь выбрал какую-то номенклатуру
						   // соответствие наименование - номенклатура нужно занести в таблицу соответствий
						  
						   НоваяСтрока = ТаблицаСоответствий.Добавить() ;
						   сООБЩИТЬ(ТмцСсылка);
						   НоваяСтрока.ТМЦ =ТмцСсылка;
						   НоваяСтрока.наименование =наименованиеТМЦ;
	    	    СохранитьЗначение("тс", ТаблицаСоответствий);	 
						   возврат ТмцСсылка;
   				    Конецесли;
				  
				  
			    Иначе
				   ТмцСсылка = НайденнаяСтрока.тмц;
				   возврат ТмцСсылка;
			    КонецЕсли;
	    	   
			   
			   
	    иначе
			    возврат ТмцСсылка;
	    конецесли;
 
 
конецфункции;

 

 

 

Как видите ми не создаем никакого документа мы просто  выводим найденную номенклатуру в виде сообщений.

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

 Изображение

 

 

 Код  модуля простой:

 

 

Процедура КнопкаВыполнитьНажатие(Кнопка)
	    ОповеститьОВыборе(ЭлементыФормы.СписокТМЦ.ТекущаяСтрока.ЗНАЧЕНИЕ)
КонецПроцедуры

 

 

 

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

 Изображение

Если при следующей загрузке  попадется наименование Футболка (кол. т.195) SXXL номенклатура Футболка (кол. т.195) S-XXL будет выбрана автоматически, таким чином у нас будет  система, которая запоминает выбор пользователя и потом поступает аналогично.

И конечно код модуля:

 

 

 

Процедура ПриОткрытии()
	    перем тс;
// Востанавливаем значение из таблицы  
тс=ВосстановитьЗначение("тс");
если тс=неопределено  	   тогда
	    иначе
ТаблицаСоответствий.Загрузить(тс );
 
конецесли;
КонецПроцедуры
 
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
	    //сохраняем таблицу
	    перем тс;
	    тс= ТаблицаСоответствий.Выгрузить() ;
	    СохранитьЗначение("тс", тс);
КонецПроцедуры

 

 

 

Файл обработки выложу в рубрике разработки. Ссылка

 
0
Читайте также
(V 7.7) Справка по работе с метаданными (с примерами)
Получение метаданных в программе 1С 7.7 происходит через объект "Метаданные"
Автоматическая архивация данных 1C c помощью WinRAR
"Как настроить автоматическую архивацию данных"
Разработки
Налоги, начисленные с ФОТ. Бухгалтериия 7.7. типовая
Данные по начислению зарплаты и сведения о налоге на доходы физических лиц, пенсионный и пр.
Копирование объектов
Обработка для копирования одного типа документа в другой
Загрузка данных из Excel
Обработка для загрузки данных из Эксель
Еще от автора
≡ к списку статей