Часть 1. Многабукаф
Кому лень читать - можно сразу скроллить вниз к обработке.
Итак, задача поставлена, и теперь нам нужно понять, являются ли входящие строки представлениями документов.
Тут на помощь приходят регулярные выражения и шикарная публикация: Регулярные выражения без внешних компонент? Легко!
Точка входа в самом низу ОбработатьДокументы(МассивПредставлений) ей мы отдаем массив строк представлений.
&НаКлиенте
Функция ПостроитьФабрикуXDTO(Фасет)
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(
"<Model xmlns=""http://v8.1c.ru/8.1/xdto"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:type=""Model"">
|<package targetNamespace=""sample-my-package"">
|<valueType name=""testtypes"" base=""xs:string"">
|<pattern>" + Фасет + "</pattern>
|</valueType>
|<objectType name=""TestObj"">
|<property xmlns:d4p1=""sample-my-package"" name=""TestItem"" type=""d4p1:testtypes""/>
|</objectType>
|</package>
|</Model>");
Модель = ФабрикаXDTO.ПрочитатьXML(Чтение);
МояФабрикаXDTO = Новый ФабрикаXDTO(Модель);
Пакет = МояФабрикаXDTO.Пакеты.Получить("sample-my-package");
Тест = МояФабрикаXDTO.Создать(Пакет.Получить("TestObj"));
Возврат Тест;
КонецФункции
&НаКлиенте
Функция ПроверитьСтроку(Фабрика, Строка)
Попытка
Фабрика.TestItem = Строка;
Возврат Истина;
Исключение
Возврат Ложь;
КонецПопытки;
КонецФункции
&НаКлиенте
Функция ПроверитьПредставление(Фабрика, ДокументСтрокой)
Возврат ПроверитьСтроку(Фабрика,ДокументСтрокой);
КонецФункции
&НаКлиенте
Функция ОбработатьДокументы(МассивПредставлений)
ДокументыКОбработке = Новый Массив;
Фабрика = ПостроитьФабрикуXDTO(".*\sот\s\d{2}\.\d{2}.\d{4}\s\d{1,2}:\d{2}:\d{2}");
Для Каждого ДокументСтрокой ИЗ МассивПредставлений Цикл
Если СокрЛП(ДокументСтрокой) = "" тогда
Продолжить;
КонецЕсли;
ДокументСтрокойСЛП = СокрЛП(ДокументСтрокой);
Если ПроверитьПредставление(Фабрика,ДокументСтрокойСЛП) тогда
ДокументыКОбработке.Добавить(ДокументСтрокойСЛП);
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Строка """+ДокументСтрокойСЛП+""" не выглядит как представление документа";
Сообщение.Сообщить();
КонецЕсли;
КонецЦикла;
Результат = ОбработатьДокументыСервер(ДокументыКОбработке);
Возврат Результат;
КонецФункции
Как вы знаете, строка документа состоит из синонима документа, номера и даты. Для определения вида документа по синониму построим список синонимов документов конфигурации:
&НаСервере
Функция ПолучитьТЗМетаданныхДокументов()
КвалификаторыСтроки = Новый КвалификаторыСтроки(250);
ОписаниеСтроки = Новый ОписаниеТипов("Строка", ,КвалификаторыСтроки);
КвалификаторыЧисла = Новый КвалификаторыЧисла(3, 0, ДопустимыйЗнак.Неотрицательный);
ОписаниеЧисла = Новый ОписаниеТипов("Число", КвалификаторыЧисла);
ТЗМетаданные = Новый ТаблицаЗначений;
ТЗМетаданные.Колонки.Добавить("Имя", ОписаниеСтроки);
ТЗМетаданные.Колонки.Добавить("Синоним", ОписаниеСтроки);
ТЗМетаданные.Колонки.Добавить("Вес", ОписаниеЧисла);
Для Каждого ЭлементМетаданных ИЗ Метаданные.Документы Цикл
НС = ТЗМетаданные.Добавить();
ЗаполнитьЗначенияСвойств(НС,ЭлементМетаданных);
НС.Вес = СтрДлина(ЭлементМетаданных.Синоним);
Если ЗначениеЗаполнено(ЭлементМетаданных.ПредставлениеОбъекта) Тогда
НС.Синоним = ЭлементМетаданных.ПредставлениеОбъекта;
КонецЕсли;
КонецЦикла;
ТЗМетаданные.Сортировать("Вес Убыв,Синоним");
Возврат ТЗМетаданные;
КонецФункции
Тут всё просто - пробежались по метаданным документов, собрали все синонимы и имена документов и отсортировали по убыванию длины строки. Большой соблазн сразу разбить строку представления по " от ", но бывают синонимы документов, которые содержат " от " в своем тексте, например "Приход товаров от поставщика 1 от 03.05.2018 00:00:00". Поэтому искать будем от максимальной длины строки. Кто-то может захотеть искать последний " от " в представлении, но мне захотелось так.
Ну и, наконец, собираем всё в кучку:
//Возвращает документ по имени, номеру и дате
&НаСервере
Функция ВернутьДок(Имя,НомерДок,ДатаДок)
Возврат Документы[Имя].НайтиПоНомеру(НомерДок,ДатаДок);
КонецФункции
&НаСервере
Функция ОбработатьДокументыСервер(СписокПредставлений)
//Построили ТЗ синонимов и имен документов
ТЗМетаданных = ПолучитьТЗМетаданныхДокументов();
МассивСсылок = Новый Массив; ///Пустой массив результата
//Для каждой строки из списка представлений
Для Каждого ПредставлениеДок ИЗ СписокПредставлений Цикл
//Пробегаем по имеющимся синонимам метаданных от самых длинных
//Тут, конечно, можно покопаться с грязной строкой и не бегать
//по ТЗ синонимов, а получить просто отбором, но мне лень
Для Каждого ШаблонПоиска ИЗ ТЗМетаданных Цикл
//и прикладываем к имеющейся "грязной" строке документа
Если Найти(ПредставлениеДок,ШаблонПоиска.Синоним) Тогда
//Если нашли - исключаем из неё синоним,
//Теперь нужно получить из хвоста номер и дату
СтрокаНомерДата = СокрЛП(СтрЗаменить(ПредставлениеДок,ШаблонПоиска.Синоним,""));
//Разбили по " от " хвост. В первом элементе массива номер - во втором дата
МассивНомерДата = СтрокаВМассивСтрок(СтрокаНомердата," от ");
НомерДок = СокрЛП(МассивНомерДата[0]);
//Пересоберем дату строкой к типу Дата 1С
СтрокаДата = СокрЛП(МассивНомерДата[1]);
ДатаПоЭлементам = СтрЗаменить(СтрЗаменить(СтрокаДата," ",":"),".",":");
МассивЭлементовДаты = СтрокаВМассивСтрок(ДатаПоЭлементам,":");
//02.06.2017 16:02:44
// 0 1 2 3 4 5
ДатаДок = Дата(МассивЭлементовДаты[2],МассивЭлементовДаты[1],МассивЭлементовДаты[0],
МассивЭлементовДаты[3],МассивЭлементовДаты[4],МассивЭлементовДаты[5]);
//Получим нужный документ
НайденныйДок = ВернутьДок(ШаблонПоиска.Имя,НомерДок,ДатаДок);
Если ЗначениеЗаполнено(НайденныйДок) Тогда
//Нашли и добавили в массив ссылок
МассивСсылок.Добавить(НайденныйДок);
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Документ """+ПредставлениеДок+""" не найден";
Сообщение.Сообщить();
КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат МассивСсылок;
КонецФункции
Ну вот, вкратце, так. Вы можете использовать куски кода и написать свою обработку, а можете скачать за 1$m нижеописанную обработку, чем порадуете меня и сэкономите свое время.
Часть 2. Обработка
Итак, для ленивых, и тех, кто просто хочет поделиться $m.
Так как обычно я нищенствую, я не знаю, чем обработка отличается от других, присутствующих на инфостарте, ибо я их не скачивал.
Тестировалась на платформах: 8.2.19+, 8.3.11
Эта обработка была создана, чтобы искать ссылки на документы по текстовому представлению, допустим из сообщений или отчетов, и:
- в разных позах перепроводить найденные документы;
- сдвигать выбранные документы на заданное количество секунд вместе с движениями, что иногда бывает полезно при выстраивании правильных последовательностей. Эта часть функционала работает так, как Пакетный сдвиг документов по дате, со всеми вытекающими последствиями и предупреждениями, почитайте, пожалуйста, и загляните в код, чтобы вы понимали что именно она делает с вашими движениями.