Как перенести информацию из текстового поля в поля ссылочного типа

05.10.23

Интеграция - Перенос данных 1C

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

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

Программный код написан на встроенном языке 1С, однако данный алгоритм можно адаптировать для любых программных сред, ведь главное принцип.

Ситуация, когда какая-то информация в базе данных хранится не в виде структуры полей, а в произвольном виде, знакома многим программистам. Это может быть адрес, наименование предприятия, название поставщиков, покупателей или подрядчиков. И рано или поздно наступает момент, когда всю эту информацию необходимо перенести в структуру справочников.

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

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

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

ОАО «Астра»

ОАО «Астра»

ОАО«Астра»

ОАО «Астра»

ОАО«Астра»

Общество с огранич.отв. «Астра»

Общество с огранич.отв. «Астра»

ООО «Космодесант»

ООО «Космодесант»

Создадим в конфигурации справочник Контрагенты. Создадим в документе оплаты реквизит Контрагент и установим тип реквизита как СправочникСсылка.Контрагенты.

Выведем поле для заполнения реквизита на форму документа. При этом поле с текстовым названием контрагента удалять не будем, оно содержит информацию о контрагентах, которую мы будем переносить.

Создадим еще один справочник СоответствиеКонтрагентов с реквизитами: Контрагент (тип реквизита установим как СправочникСсылка.Контрагенты) и ТекстКонтрагент (тип реквизита установим как Строка неограниченной длины, или же можно поставить такую же длину, как и у текстового поля Контрагенты в документе Оплаты). В этот справочник мы занесем соответствие между текстовой информацией из текстового поля документа Оплаты и записью из справочника Контрагенты.

Следующий этап - заполнение справочника СоответствиеКонтрагентов.

Выберем с помощью запроса все значения текстового поля Контрагенты из документа Оплаты. Значения будем выбирать без повторений. Мы исходим из того, что как правило, каждый пользователь заносит текстовую информацию в базу данных по определенному шаблону. Например, кто-то напишет название контрагента как ОАО «Астра» - после ООО всегда ставит пробел и кавычки, кто-то может написать Общество с огранич.отв. «Астра», кто-то ОАО«Астра» без пробелов после ОАО. Таким образом, первый пользователь в документах, заполненных им, будет указывать название контрагента как ОАО «Астра» и таких документов может быть несколько сотен, второй пользователь будет в большинстве случаев заносить название контрагента как Общество с огранич.отв. «Астра», и таких документов тоже может быть несколько сотен. Наша задача отобрать и занести в справочник СоответствиеКонтрагентов все возможные случаи написания названий контрагентов и указать каждому из этих вариантов написания ссылку на контрагента из справочника Контрагенты. При этом нельзя вносить изменения в поле с текстовым названием контрагента, так как в дальнейшем по этому полю мы программно заполним поле Контрагент в документе Оплаты.

Итак, создадим запрос и выберем все возможные варианты написания из текстового поля с названием контрагентов и заполним наш справочник СоответствиеКонтрагентов результатами этого запроса Заполнять будем только поле ТекстКотрагент, поле Контрагент ссылочного типа придется заполнять вручную. Однако заполнение вручную этого поля по трудоемкости гораздо меньше, чем перенос информации вручную из текстового поля в поле ссылочного типа.

Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ(ТекстКотрагент) КАК  ТекстКонтрагент
			| ИЗ Документ.Оплаты ";
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
	нэ = Справочники. СоответствиеКонтрагентов.СоздатьЭлемент();
	нэ.ТекстКонтрагент = Выборка.ТекстКонтрагент;
	нэ.Записать();
КонецЦикла;

Таким образом мы заполнили поле ТекстКонтрагент справочника СоответствиеКонтрагентов той информацией, которую вносил пользователь в базу данных в текстовом виде, но заполнили ее без повторений:

ОАО «Астра»

ОАО«Астра»

Общество с огранич.отв. «Астра»

ООО «Космодесант»

После заполнения поля ТекстКонтрагент справочника СоответствиеКонтрагентов, необходимо заполнить каждому элементу контрагента из справочника Контрагенты. Эту работу как раз и можно поручить пользователям, записей будет гораздо меньше, чем в первоначальном варианте заполнения и на выполнение этой работы у пользователей уйдет меньше времени.

Когда справочник СоответствиеКонтрагентов будет заполнен можно с помощью несложного кода заполнить поля документа Оплаты. Так как документы Оплаты вероятно были созданы в прошлые периоды, и эти периоды уже закрыты, то изменения в документах следует производить без движения данных документов по регистрам, для этого мы используем признак ОбменДанными:

СсылкаНаОбъект.ОбменДанными.Загрузка = Истина;

А при записи документа мы будем использовать режим записи Запись:

СсылкаНаОбъект.Записать(РежимЗаписиДокумента.Запись);

Выбираем запросом все документы Оплаты, у которых заполнено поле ТекстКонтрагент.

С помощью левого соединения соединяем эти документы с элементами справочника СоответствиеКонтрагентов, соединение будет происходить по текстовому полю ТекстКонтрагент. В качестве результата, возвращаемого запросом, выбираем поля ссылка на документ и ссылка на элемент справочника Контрагенты. Вот как это будет выглядеть в коде программы:


Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Док.Ссылка КАК СсылкаДокумент, 
			| Спр.Контрагент КАК Контрагент
			| ИЗ Документ.Оплаты КАК Док
			| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.СоответствиеКонтрагентов КАК Спр
			| ПО Док.ТекстКонтрагент = Спр.ТекстКонтрагент
			|
			| ГДЕ Док.ТекстКонтрагент<>"""" 
			|";
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
	СсылкаНаОбъект = Выборка.СсылкаДокумент.ПолучитьОбъект();
	СсылкаНаОбъект.ОбменДанными.Загрузка = Истина;
	СсылкаНаОбъект.Контрагент = Выборка.Контрагент;
	СсылкаНаОбъект.Записать(РежимЗаписиДокумента.Запись);
КонецЦикла;


 

Теперь рассмотрим пример, когда нам надо перенести информацию из текстового поля ТекстАдрес в структуру полей Населенный пункт, Улица, Дом, Корпус, Квартира.

В этом случае нам предстоит провести более сложный анализ хранящейся в текстовом поле ТекстАдрес информации. В качестве элементов, определяющих где заканчивается тот или иной элемент адреса (под элементами адреса мы имеем в виду населенный пункт, улицу, дом, корпус и квартиру) мы будем использовать разделители, которые в тексте использовал пользователь — пробел, запятая. Для выделения из текстовой строки дома, корпуса и квартиры мы будем использовать разделители вида «/», «\», «к.», «корп.», «дом.», «дом », «д.», «д. » и так далее. Состав этих разделителей мы определим по мере заполнения структуры полей.

Итак, для начала нам необходимо создать справочники для хранения адресной информации, это справочник НаселенныеПункты, справочник Улицы и справочник Дома. Справочник НаселенныеПункты будет являться Владельцем справочника Улицы, а справочник Улицы в свою очередь будет являться Владельцем справочника Дома. Для структурных единиц адреса Корпус и Квартира создавать отдельные справочники не будем, Корпус будет указан не как отдельный номер корпуса, а как элемент справочника Дома, то есть например, для дома номер 3 и дома номер 3 корпус 2 в справочнике Дома будут созданы два элемента: 3 и 3корпус2. Информацию о номере квартиры мы будем хранить в виде реквизита строкового типа в тех справочниках, в которых необходимо использовать номер квартиры.

После создания всех необходимых справочников для хранения адресной информации создадим еще один справочник СоответствиеАдресов. Это временный справочник и после разделения адресной информации мы его удалим из конфигурации. Создадим реквизиты справочника СоответствиеАдресов:

ТекстАдрес — строковый тип, используется для хранения адреса в текстовом виде, в котором он хранится в базе в данный момент.

ТекстАдресПодстрока — строковый тип, сюда будем записывать остаток необработанной строки.

ТекстНаселенныйПункт — строковый тип

ТекстУлица — строковый тип

ТекстДом — строковый тип

ТекстКвартира — строковый тип

НаселенныйПункт — тип СправочникСсылка.НаселенныеПункты

Улица - тип СправочникСсылка.Улицы

Дом — тип тип СправочникСсылка.Дома

Квартира — строка

 

Так же создадим еще четыре вспомогательных справочника СоответствиеНаселенныхПунктов, СоответствиеУлиц, СоответствиеДомов и СоответствиеКвартир.

 

Алгоритм разделения текстовой строки одинаков для всех справочников:

1). Определяем первое вхождение разделителя (может быть несколько видов разделителей);

2). Отсекаем подстроку от начала строки до разделителя;

3). Записываем отсеченную строку во вспомогательный справочник СоответствиеАдресов в соответствующее текстовое поле;

4). Выбираем с помощью запроса значения отсеченной подстроки без повторений и записываем результаты запроса в соответствующий вспомогательный справочник;

5) Во вспомогательных справочниках в поле ссылочного типа заполнить значения из справочников адресной структуры. Эту работу можно поручить пользователям;

ВАЖНО! - не корректировать значения вспомогательных справочников в текстовых полях. Если в текстовом поле находится информация, которой нельзя подобрать соответствие из справочников адресной структуры, то следует такие поля оставлять пустыми, и в последствии заполнить строки в справочнике СоответствиеАдресов вручную.

6) Заполнить программно поля ссылочного типа в справочнике СоответствиеАдресов;

7) Заполнить программно поля адресной структуры в документах или справочниках базы данных, используя справочник СоответствиеАдресов.

 

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

 

Разберем на небольшом примере разбор адресной строки. Предположим, в текстовом поле АдресТекст находится информация об адресе вот в таком виде:

 

1

Комсомольск-на-Амуре, Ленина 7/2-12

2

Комсомольск-на-Амуре пр-т Мира д.8 кв.18

3

Комсомольск-н\А улица Мира дом 14/2 кв 22

4

Ленина 4-3

5

г.Комс. пр.Мира 45-3

6

Комсомольск-на-Амуре, Октябрьский 12/2-12

7

Комсомольск-н\А проспект Октябрьский дом 1 кв 20

 

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

Запрос = Новый Запрос;  

Запрос.Текст = " Выбрать ТекстАдрес
|ИЗ Справочник.СоответствиеАдресов
|";
ТЗ = Запрос.Выполнить().Выгрузить();

Для каждого стр из ТЗ Цикл 
	ЧастьАдреса = "";

//Для корректной выборки названия населенного пункта нам необходимо //предварительно заменть в строке адреса «г.К» на «К»
	СтрокаДляПоиска = СтрЗаменить(стр.ТекстАдрес, "г.К", "К");
	НомерРазделителя1 = СтрНайти(СтрокаДляПоиска, ",");
	НомерРазделителя2 = СтрНайти(СтрокаДляПоиска, " ");
	
	Если НомерРазделителя1<НомерРазделителя2 Тогда
		НомерРазделителя = НомерРазделителя1; 
		Если  НомерРазделителя = 0 Тогда 
			НомерРазделителя= НомерРазделителя2;
		КонецЕсли;
	Иначе
		НомерРазделителя = НомерРазделителя2;
	КонецЕсли;
	
	Если НомерРазделителя>0 Тогда
		ЧастьАдреса =сред(СтрокаДляПоиска,1,НомерРазделителя);
	КонецЕсли;
	
	Если  ЧастьАдреса<> "" Тогда
		ТекстАдресПодстрока = СокрЛП(Прав(СтрокаДляПоиска,СтрДлина(СтрокаДляПоиска)-НомерРазделителя));
			
		Об = стр.Ссылка.ПолучитьОбъект();
		Об.ТекстНаселенныйПункт = ЧастьАдреса; 
		//запишем необработанную часть строки с улицей, домом и корпусом
		Об.ТекстАдресПодстрока = Прав(СтрокаДляПоиска,СтрДлина(СтрокаДляПоиска)-НомерРазделителя);
		Об.Записать();
	КонецЕсли;
КонецЦикла;

В результате получим такое разделение текстовой строки на населенный пункт и остальную часть строки:

 

ТекстНаселенныйПункт

ТекстАдресПодстрока

Комсомольск-на-Амуре,

Ленина 7/2-12

Комсомольск-на-Амуре

пр-т Мира д.8 кв.18

Комсомольск-н\А

улица Мира дом 14/2 кв 22

Ленина

4-3

Комс.

пр.Мира 45-3

Комсомольск-на-Амуре,

Октябрьский 12/2-12

Комсомольск-н\А

проспект Октябрьский дом 1 кв 20

 

Заполняем справочник СоответствиеНаселенныхПунктов

Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ(Текст) КАК Текст
|ИЗ Справочник. СоответствиеАдресов
|
|";
ТЗ = Запрос.Выполнить().Выгрузить();
Для каждого стр из ТЗ Цикл
	нс = Справочники.СоответствиеНаселенныхПунктов.Добавить();
	нс.Текст = стр.Текст;
	нс.Записать();
КонецЦикла;

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

Комсомольск-на-Амуре,

Комсомольск-н\А

Комсомольск-на-Амуре

Ленина

Комс.

Аналогичным образом заполняем улицу, но уже поиск будем проводить по полю ТекстАдресПодстрока. В коде из строки поиска необходимо предварительно убрать наименования улиц и проспектов «пр-т», «ул.», «ул » и т. п.

разбор текстовой строки

См. также

SALE! 20%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Россия Платные (руб)

Правила в универсальном формате обмена для ERP 2.5, КА 2.5, УТ 11.5, БП 3.0, Розница, УНФ, для последних версий конфигураций. Ссылки на другие конфигурации в описании публикации. Правила совместимы со всеми другими версиями конфигураций новыми и старыми, поддерживающими обмен и синхронизацию в формате EnterpriseData. Не требуется синхронного обновления правил после обновления другой конфигурации, участвующей в обмене. Типовой обмен через планы обмена кнопкой Синхронизация вручную или автоматически по расписанию, или вручную обработкой.

26280 22338 руб.

12.06.2017    141453    798    297    

419

SALE! 10%

Перенос данных 1C Программист Платформа 1С v8.3 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос документов, начальных остатков и справочной информации из УПП 1.3 в ERP 2 | из УПП 1.3 в УТ 11 | из УПП в КА 2 | Правила конвертации (КД 2) | Более 360 предприятий выполнили переход с использованием этого продукта! | Сэкономьте время - используйте готовое решение для перехода! | Позволяет перенести из УПП 1.3 в ERP / УТ 11 / КА 2 всю возможную информацию | В переносе есть фильтр по организации и множество других опциональных параметров выгрузки | Есть несколько алгоритмов выгрузки остатков на выбор

55778 50200 руб.

04.08.2015    166416    332    277    

373

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УПП 1.3 (1.3.234.x) и БП 3.0 (3.0.161.x). Правила подходят для версии ПРОФ и КОРП.

35000 31500 руб.

15.12.2021    23981    169    51    

127

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 Оперативный учет 1С:Управление торговлей 10 Россия Управленческий учет Платные (руб)

Перенос данных из 1С:Управление торговлей 10.3 в 1С:Управление торговлей 11.5 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УТ 10.3 (10.3.88.x) и УТ 11.5 (11.5.19.x).

35000 31500 руб.

23.07.2020    51170    228    69    

184

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из ERP в ЗУП 3 | из КА 2 в ЗУП | Готовые правила конвертации данных (КД 2) для переноса остатков, документов с движениями и справочной информации 3 | Есть перенос начальной задолженности по зарплате и начальной штатной расстановки на выбранную дату | Обороты за прошлые годы (данные для расчета среднего) переносятся свернуто в документ "Перенос данных" | Есть фильтр по организациям | Документы за текущий период переносятся сразу с движениями, поэтому не потребуется делать перерасчеты | Перенос можно проверить перед покупкой, обращайтесь!

53111 47800 руб.

03.12.2020    36563    94    66    

89

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена | Можно выполнить переход с УПП на БП 3 или запускать выгрузку данных за выбранный период времени | Переносятся документы, начальные остатки и вся справочная информация | Есть фильтр по организации и множество других параметров выгрузки | Поддерживается несколько сценариев работы: как первичный полный перенос, так и перенос только новых документов | Перенос данных возможен в "1С: Бухгалтерия 3.0" версии ПРОФ, КОРП или базовую | Переход с "1С: УПП1.3" / "1С:КА 1.1" на "1С:БП3.0" с помощью правил конвертации будет максимально комфортным! | Можно бесплатно проверить перенос на вашем сервере!

48278 43450 руб.

25.02.2015    171151    303    257    

378

SALE! 15%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 Платформа 1C v8.2 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Управление производственным предприятием Россия Платные (руб)

Регулярный обмен, выгрузка, перенос из КА 1.1, УПП 1.3, УТ 10.3 для обмена с любыми конфигурациями, поддерживающими обмен в формате EnterpriseData (КД3) - БП 3.0, ERP, КА 2, УТ 11, Розница 2, УНФ 1.6 и другими. Правила для старых и доработанных конфигураций не требуют синхронного обновления и совместимы с новыми и будущими конфигурациями. Обмен по расписанию, через папку, FTP, почту.

15300 13005 руб.

18.02.2016    186850    589    509    

526

Перенос данных 1C Программист Бухгалтер Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет НДФЛ ФОМС, ЕФС Платные (руб)

Обработки для быстрого перехода с конфигураций «КАМИН:Расчет заработной платы 3.0», «КАМИН:Зарплата для бизнеса 4.0» и «КАМИН:Зарплата 5.0» на конфигурацию «Зарплата и управление персоналом» версии 3.1.

12000 руб.

25.09.2016    80625    312    250    

264
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. butters 06.10.23 10:23 Сейчас в теме
А в чем особенность данного алгоритма? Похоже на нетленку написанную на коленке за вечер, но выдаваемую как новаторский подход к сопоставлению данных
оggghhhiiu; +1 Ответить
2. оggghhhiiu 17 07.10.23 06:03 Сейчас в теме
(1) так оно и есть)
user773200; +1 Ответить
3. kamisov 216 09.10.23 07:53 Сейчас в теме
4. user773200 10 18.04.24 03:16 Сейчас в теме
как рабочий костыль) А какие варианты еще могут быть при разборе текстовой информации произвольного вида?
Оставьте свое сообщение