Как по строке найти метаданные

Как получить объект по строке?

Я
   svent0vit

07.05.09 – 09:54

Есть строка: “Документ Отчет ККМ о продажах 00004901 от 13.04.2009 16:26:23”

Как получить ссылку на документ?

   butterbean

1 – 07.05.09 – 09:55

(0) извращенец??

поробуй номер и дату вытащить и по номеру искать

   Sadovnikov

2 – 07.05.09 – 09:55

(0) Откуда строку взял?

   Широкий

3 – 07.05.09 – 09:56

выделяем из данной строки представление документа, номера и даты – и по этим 3 пкнуктам ищем документ

   svent0vit

4 – 07.05.09 – 09:58

Шо, кроме как строку парсить, вариантов нету?

   wPa

5 – 07.05.09 – 09:58

(4) А сам то как думаешь

   svent0vit

6 – 07.05.09 – 09:59

(5), мало ли

   H A D G E H O G s

7 – 07.05.09 – 10:00

(2) Думаю что примерно так 🙂

Текстарь.ДобавитьСтроку(Выборка.Ссылка);

   73

8 – 07.05.09 – 10:00

(6) Ответь на (2) – может и варианты появятся.

   svent0vit

9 – 07.05.09 – 10:02

(8), да там без вариантов. Только строка.

   svent0vit

10 – 07.05.09 – 10:02

(7) ацке остроумно

   mikecool

11 – 07.05.09 – 10:03

сообщения из панели комментариев скорее всего…

   eklmn

12 – 07.05.09 – 10:04

(9) Где там? конкретней, откуда взял строку?

   wPa

13 – 07.05.09 – 10:04

(9) Баз вариантом может можно ГУИД получить?

   svent0vit

14 – 07.05.09 – 10:05

Слушайте, умники, это текстовый файл, результаты перепроведения

   Stepa86

15 – 07.05.09 – 10:07

(14) то есть (7) был прав =)  вообщем только (3)

   mikecool

16 – 07.05.09 – 10:08

я телепать :))

   Aprobator

17 – 07.05.09 – 10:09

Сваяй запрос – получи ссылку и представление документа.

   Rie

18 – 07.05.09 – 10:10

(4) А что трудного распарсить строку? Найти слово “от”, перед ним – номер, после него – дата.

   svent0vit

19 – 07.05.09 – 10:11

Лучше подскажите как номер из строки выделить.

ЗНАЮ ЧТО БАЯН! 🙂

   Rie

20 – 07.05.09 – 10:12

(19) Перед ним пробел, после него – ” от”.

   Aprobator

21 – 07.05.09 – 10:12

(19) у тя документ одного вида? Перепроведение наверняка за какой-то период.
В запросе получаешь ссылку и представление документа. Дальше дело техники.

   eklmn

22 – 07.05.09 – 10:13

Я бы сделал так:

“Документ ” уже есть, отсекаем его

Далее читаем до первой цифры.

Все что прочитали, убираем пробелы.

Получим имя документа, потом Выполнить(“док = Документы.”+ОбработанаяСтрока);

   Aprobator

23 – 07.05.09 – 10:20

(+21) единственно только в твоей строки придется слово “Документ” вычистить. Но это делается секунды.

Пример запроса:
   “ВЫБРАТЬ
   |    ЗаказПоставщику.Ссылка КАК СсылкаНаДокумент,
   |    ЗаказПоставщику.Представление КАК представлениеДокумента
   |ИЗ
   |    Документ.ЗаказПоставщику КАК ЗаказПоставщику
   |ГДЕ
   |    ЗаказПоставщику.Дата МЕЖДУ &Дата1 И &Дата2″;

   Genius

24 – 07.05.09 – 10:23

млин, тока неделю назад на собеседовании из строки вытаскивал и сортировал числа :))) …

   Aprobator

25 – 07.05.09 – 10:31

(24) а че их вытаскивать – то? Тупо
ЧтоЭто = КодСимвола(СтрокаПоискаЧисла, ПроверяемаяПозиция);
Если 48 <= ЧтоЭто <= 57 Тогда
   // стопудова это цифра
КонецЕсли;

   Широкий

26 – 07.05.09 – 10:34

(22) Неверно.. надо разбирать с конца строки , т.к. номер может содержать префикс

   Terv

27 – 07.05.09 – 10:35

извращенцы

   Aprobator

28 – 07.05.09 – 10:37

(27) это да – наверняка сообщение выдается какой-нить обработкой. Пусть бы она сама и собирала ссылки документов 🙂

   Aprobator

29 – 07.05.09 – 10:42

(+28) тупо в текстовый файл дописать тоже самое ЗначениеВСтрокуВнутр(ПроводимыйОбъект) после какого-нибудь хитрого символа используемого в качестве указателя откуда все это считывать. А уж дальше получить ссылку дело 5 секунд. Непонятно только для чего все это?

   H A D G E H O G s

30 – 07.05.09 – 10:43

СписокИмен=Новый СписокЗначений;

Для Каждого Метаданное ИЗ Метаданные.Документы Цикл

СписокИмен.Добавить(Метаданное.Синоним);

КонецЦикла;

Для каждого ТекСтрока ИЗ Строки Цикл

ТекСтрока=СтрЗаменить(ТекСтрока,”Документ “,””);

Для Каждого ЭлементСЗ ИЗ СписокИмен Цикл

ВремСтрока=СтрЗаменить(ТекСтрока,ЭлементСЗ.Значение+” “,””);

Если ВремСтрока<>ТекСтрока Тогда

ТекСтрока=ВремСтрока;

Прервать;

КонецЕсли;

КонецЦикла;

КонецЦикла;

Получаем однозначно

<<Номер>> от <<Дата>>

   eklmn

31 – 07.05.09 – 10:50

(26) не наблюдаю префикса в (0)

   Aprobator

32 – 07.05.09 – 10:51

(31) ну дык – это частный случай.

   eklmn

33 – 07.05.09 – 10:55

(32) ну дык и подход такой же

   Широкий

34 – 07.05.09 – 11:09

Тестируй

Функция ПреобразоватьСтрокуВДату(СтрокаДата,РазделительДаты=”.”,РазделительВремени=”:”)
   ТекСтрока=СокрЛП(СтрокаДата);
   ТекСтрока=СтрЗаменить(ТекСтрока,РазделительДаты,”#”);
   ТекСтрока=СтрЗаменить(ТекСтрока,РазделительВремени,”#”);
   ТекСтрока=СтрЗаменить(ТекСтрока,” “,”#”);

       Список=глСтрокуВСписокСРазделителями(ТекСтрока,”#”);

       ТекГод=Список[2].Значение;
   ТекГод=Лев(“2000”,4-СтрДлина(ТекГод))+ТекГод;

       ТекМесяц=Список[1].Значение;
   ТекМесяц=Лев(“00”,2-СтрДлина(ТекМесяц))+ТекМесяц;

       ТекДень=Список[0].Значение;
   ТекДень=Лев(“00”,2-СтрДлина(ТекДень))+ТекДень;

       ТекЧас=”00″;
   ТекМинута=”00″;
   ТекСекунда=”00″;

       Если Список.Количество()>3 Тогда
       ТекЧас=Список[3].Значение;
       ТекЧас=Лев(“00”,2-СтрДлина(ТекЧас))+ТекЧас;

               ТекМинута=Список[4].Значение;
       ТекМинута=Лев(“00”,2-СтрДлина(ТекМинута))+ТекМинута;

               ТекСекунда=Список[5].Значение;
       ТекСекунда=Лев(“00”,2-СтрДлина(ТекСекунда))+ТекСекунда;
   КонецЕсли;

       Возврат Дата(ТекГод+ТекМесяц+ТекДень+ТекЧас+ТекМинута+ТекСекунда);
КонецФункции

Функция ВернутьСсылкуДокумента(ПредставлениеДокумента)
   МассивСтрок=СтрЗаменить(ПредставлениеДокумента,” “,Символы.ПС);
   КоличествоСтрок=СтрЧислоСтрок(МассивСтрок);
   Если КоличествоСтрок<4 Тогда
       Сообщить(“Неудачный разбор строки”,СтатусСообщения.Важное);
       Возврат Неопределено;
   КонецЕсли;    

       ПредставлениеДокументаСтр=””;
   Для сч=2 По КоличествоСтрок-4 Цикл
       ПредставлениеДокументаСтр=ПредставлениеДокументаСтр+” “+СтрПолучитьСтроку(МассивСтрок,сч);
   КонецЦикла;    

       ПредставлениеДокументаСтр=СокрЛП(ПредставлениеДокументаСтр);

       ИмяДокумента=””;
   Для Каждого МетаданныеДок Из Метаданные.Документы Цикл
       Если МетаданныеДок.Синоним=ПредставлениеДокументаСтр Тогда
           ИмяДокумента=МетаданныеДок.Имя;
           Прервать;
       КонецЕсли;    
   КонецЦикла;

   Если ИмяДокумента=”” Тогда
       Сообщить(“Неудачный разбор представления документа”,СтатусСообщения.Важное);
       Возврат Неопределено;
   КонецЕсли;    

       ДатаДокумента=ПреобразоватьСтрокуВДату(СтрПолучитьСтроку(МассивСтрок,КоличествоСтрок-1));
   Если Не ЗначениеЗаполнено(ДатаДокумента) Тогда
       Сообщить(“Неудачный разбор даты документа”,СтатусСообщения.Важное);
       Возврат Неопределено;
   КонецЕсли;    

           НомерДокументаСтр=СтрПолучитьСтроку(МассивСтрок,КоличествоСтрок-3);

       СсылкаДокумента=Документы[ИмяДокумента].НайтиПоНомеру(СтрПолучитьСтроку(МассивСтрок,КоличествоСтрок-3),ДатаДокумента);

       Возврат ?(ЗначениеЗаполнено(СсылкаДокумента),СсылкаДокумента,Неопределено);
КонецФункции

   Широкий

35 – 07.05.09 – 11:26

Исправленный вариант

Функция ПреобразоватьСтрокуВДату(ДатаСтр)
   ИтоговаяСтрокаДаты=””;

       СтрокаДляРазбора=ДатаСтр;

       ПозицияРазделителя=Найти(СтрокаДляРазбора,”.”);
   ТекДень=Лев(СтрокаДляРазбора,ПозицияРазделителя-1);
   ИтоговаяСтрокаДаты=Лев(“00”,2-СтрДлина(ТекДень))+ТекДень+ИтоговаяСтрокаДаты;

       СтрокаДляРазбора=Сред(СтрокаДляРазбора,ПозицияРазделителя+1);

       ПозицияРазделителя=Найти(СтрокаДляРазбора,”.”);
   ТекМесяц=Лев(СтрокаДляРазбора,ПозицияРазделителя-1);
   ИтоговаяСтрокаДаты=Лев(“00”,2-СтрДлина(ТекМесяц))+ТекМесяц+ИтоговаяСтрокаДаты;

       ТекГод=Сред(СтрокаДляРазбора,ПозицияРазделителя+1);
   ИтоговаяСтрокаДаты=Лев(“2000”,4-СтрДлина(ТекГод))+ТекГод+ИтоговаяСтрокаДаты;

       Попытка
       Возврат Дата(ИтоговаяСтрокаДаты);
   Исключение
       Возврат ТекущаяДата()
   КонецПопытки;
КонецФункции

Функция ВернутьСсылкуДокумента(ПредставлениеДокумента)
   МассивСтрок=СтрЗаменить(ПредставлениеДокумента,” “,Символы.ПС);
   КоличествоСтрок=СтрЧислоСтрок(МассивСтрок);
   Если КоличествоСтрок<4 Тогда
       Сообщить(“Неудачный разбор строки”,СтатусСообщения.Важное);
       Возврат Неопределено;
   КонецЕсли;    

       ПредставлениеДокументаСтр=””;
   Для сч=2 По КоличествоСтрок-4 Цикл
       ПредставлениеДокументаСтр=ПредставлениеДокументаСтр+” “+СтрПолучитьСтроку(МассивСтрок,сч);
   КонецЦикла;    

       ПредставлениеДокументаСтр=СокрЛП(ПредставлениеДокументаСтр);

       ИмяДокумента=””;
   Для Каждого МетаданныеДок Из Метаданные.Документы Цикл
       Если МетаданныеДок.Синоним=ПредставлениеДокументаСтр Тогда
           ИмяДокумента=МетаданныеДок.Имя;
           Прервать;
       КонецЕсли;    
   КонецЦикла;

       Если ИмяДокумента=”” Тогда
       Сообщить(“Неудачный разбор представления документа”,СтатусСообщения.Важное);
       Возврат Неопределено;
   КонецЕсли;    

       СсылкаДокумента=Документы[ИмяДокумента].НайтиПоНомеру(СтрПолучитьСтроку(МассивСтрок,КоличествоСтрок-3),ПреобразоватьСтрокуВДату(СтрПолучитьСтроку(МассивСтрок,КоличествоСтрок-1)));

       Возврат ?(ЗначениеЗаполнено(СсылкаДокумента),СсылкаДокумента,Неопределено);
КонецФункции

   hhhh

36 – 07.05.09 – 11:46

(35) тогда уж лучше так

ВЫБРАТЬ

  ОтчетККМОПродажах.Ссылка,

  ПРЕДСТАВЛЕНИЕ(ОтчетККМОПродажах.Ссылка) КАК ПредставлениеДокумента

ИЗ

  Документ.ОтчетККМОПродажах КАК ОтчетККМОПродажах

ТабПредст = Запрос.Выполнить().Выгрузить();

Для Каждого Строка Из ТекстовыеСтроки Цикл

  НайденнаяСтрока = ТабПредст.Найти(Сред(Строка, 10), “ПредтавлениеДокумента”);

  Если НайденнаяСтрока <> Неопределено Тогда

       Сообщить(“Ссылка ” + Строка + ” найдена”);

  КонецЕсли;

КонецЦикла;

   Serg_1960

37 – 07.05.09 – 11:47

Хочу еще варианты, продолжения – с попкорном сижу :))

Тогда уж лучше так:

Функция ПреобразоватьСтрокуВДату(ДатаСтр)

  СтрДата = СтрЗаменить(ДатаСтр, “.”, Символы.ПС);

  СтрДата = СтрЗаменить(ДатаСтр, “/”, Символы.ПС);

  Год = Число(СтрПолучитьСтроку(СтрДата,3));

  Возврат Дата( ?(Год<100, 2000, 0) + Год, Число(СтрПолучитьСтроку(СтрДата,2)), Число(СтрПолучитьСтроку(СтрДата,1)));

КонецФункции

   Широкий

38 – 07.05.09 – 11:49

(36) Совсем упал? Все документы перебирать?

   hhhh

39 – 07.05.09 – 11:52

(38) зачем все? Естественно какой-то там период у него за какой проводились документы и отбор

   Aprobator

40 – 07.05.09 – 11:54

он наверное имеет ввиду по виду документа.

   hhhh

41 – 07.05.09 – 11:56

(39)+ и у него там не одна строка, а много, так что будет выигрыш при поиске ссылок.

   Широкий

42 – 07.05.09 – 11:58

(41) Угу.. и по разным видам
(37) Нормально.. только в число конвертить не обязательно

   Serg_1960

43 – 07.05.09 – 12:07

(42) В функции токма ради универсализма строки с “/” и с анализом года 🙂

   Aprobator

44 – 07.05.09 – 12:18

Я как обычно с извращениями 🙂

Функция ПреобразоватьСтрокуВДату(ДатаСтр)
      ДатаБезВремени = Сред(ДатаСтр, 7, 4) + Сред(ДатаСтр,4, 2) + Лев(ДатаСтр, 2);
      ВремяВДате = Сред(ДатаСтр, 12, 2) + Сред(ДатаСтр, 15, 2) + Прав(ДатаСтр,2)
      СтрокаДляПолученияДаты = ДатаБезВремени + ВремяВДате;
      Возврат Дата(СтрокаДляПолученияДаты);
КонецФункции

   Aprobator

45 – 07.05.09 – 12:27

Продолжение будет? До полтиника немного осталось.

   Serg_1960

46 – 07.05.09 – 12:50

Будет 🙂 Слабо короче написать?

Функция ВернутьСсылкуДокумента(ДокументСтрока)

  Для Каждого МетаДок Из Метаданные.Документы Цикл

     Если Найти(ДокументСтрока, МетаДок.Синоним) Тогда

        ДокументСтрока = СтрЗаменить(ДокументСтрока, “Документ ” + МетаДок.Синоним + ” “,””);

        ДокументНомер = Лев(ДокументСтрока,Найти(ДокументСтрока, ” “)-1);

        Возврат Документы[МетаДок.Имя].НайтиПоНомеру(ДокументНомер, Дата(СтрЗаменить(ДокументСтрока, ДокументНомер + ” от “, “”)));

     КонецЕсли;    

  КонецЦикла;

  Возврат;

КонецФункции

   Широкий

47 – 07.05.09 – 12:55

(46) Не айс.
Ищем ПриходнаяНакладная.. а существует ПриходнаяНакладная и ПриходнаяНакладнаяСклад

ДокументНомер = Лев(ДокументСтрока,Найти(ДокументСтрока, ” “)-1) – даже на примере (0) не прокатит

   svent0vit

48 – 07.05.09 – 12:58

Не надоело еще?

   Aprobator

49 – 07.05.09 – 12:59

(48) тсс –  унас уже соревнование пошло 🙂

   Serg_1960

50 – 07.05.09 – 13:00

(47) Тогда жди продолжения – сейчас подправлю

   svent0vit

51 – 07.05.09 – 13:01

(46), не забываем про универсальность решения и нумерацию в пределах года

   Ленинград

52 – 07.05.09 – 13:02

пипец вы

   svent0vit

53 – 07.05.09 – 13:02

(51), сорри, невнимательно глянул

   svent0vit

54 – 07.05.09 – 13:02

кстати, на инфостарте как-то обработку видел именно для этого, интересно как там автор извратился

   Aprobator

55 – 07.05.09 – 13:03

(54) так документы проводятся за период?

   Aprobator

56 – 07.05.09 – 13:05

хм – кстати
Функция ПреобразоватьСтрокуВДату(ДатаСтр)
      Возврат Дата(ДатаСтр);
КонецФункции

тоже отрабатывает. В СП вроде это не описано.

   svent0vit

57 – 07.05.09 – 13:07

и еще кстати полная запись выглядит так:

Документ Перемещение товаров 00004901 от 13.04.2009 16:26:23, строка :21 Не списано по партиям 1шт. товар Сплит-система Samsung/AQ-07XLN(+XLX)=12350, х-ка: , серия: , склад:   xxxx, цена розн.: 11 615

так шта красота ваше пока взлетит 🙂

   svent0vit

58 – 07.05.09 – 13:07

*не взлетит

   Aprobator

59 – 07.05.09 – 13:08

(57) считать текст до первой запятой – без проблем

   Aprobator

60 – 07.05.09 – 13:08

(58) если про (56), то сам только что проверил.

   Широкий

61 – 07.05.09 – 13:11

(60) Какая строку конвертишь – у меня как то не получается

   svent0vit

62 – 07.05.09 – 13:11

Для Каждого МетаДок Из Метаданные.Документы Цикл

      Если Найти(ДокументСтрока, МетаДок.Синоним) Тогда

        ДокументСтрока = Сред(ДокументСтрока, 1, Найти(ДокументСтрока, “,”)-1);

        ДокументСтрока = СтрЗаменить(ДокументСтрока, “Документ ” + МетаДок.Синоним + ” “,””);

        ДокументНомер = Лев(ДокументСтрока,Найти(ДокументСтрока, ” “)-1);

        Документы[МетаДок.Имя].НайтиПоНомеру(ДокументНомер, Дата(СтрЗаменить(ДокументСтрока, ДокументНомер + ” от “, “”)));

     КонецЕсли;    

  КонецЦикла;

   Aprobator

63 – 07.05.09 – 13:12

У меня вот так взлетело Дата(“13.04.2009 00:00:00”)

   svent0vit

64 – 07.05.09 – 13:12

так работает

   Широкий

65 – 07.05.09 – 13:13

(63) Действительно работает.. раньше такого точно не было

   svent0vit

66 – 07.05.09 – 13:13

затру свое позорище нафиг 8)

   Aprobator

67 – 07.05.09 – 13:15

(65) дык о чем и речь.

   Lama12

68 – 07.05.09 – 13:22

Хе… а если бедут несколько документов с одинаковым номером и одинаковым временем, то как док найти?

   Широкий

69 – 07.05.09 – 13:23

(68) Тогда прогу гвоздь в голову за неправильную проектировку системы

   Aprobator

70 – 07.05.09 – 13:23

В разных базах что ли?

   Широкий

71 – 07.05.09 – 13:28

Тогда мой вариант с учетом (56)

Функция ВернутьСсылкуДокумента(ПредставлениеДокумента)
   МассивСтрок=СтрЗаменить(ПредставлениеДокумента,” “,Символы.ПС);

       КоличествоСтрок=СтрЧислоСтрок(МассивСтрок);
   Если КоличествоСтрок<4 Тогда
       Сообщить(“Неудачный разбор строки”,СтатусСообщения.Важное);
       Возврат Неопределено;
   КонецЕсли;    

       ПредставлениеДокументаСтр=””;
   Для сч=2 По КоличествоСтрок-4 Цикл
       ПредставлениеДокументаСтр=ПредставлениеДокументаСтр+” “+СтрПолучитьСтроку(МассивСтрок,сч);
   КонецЦикла;    

       ПредставлениеДокументаСтр=СокрЛП(ПредставлениеДокументаСтр);

       ИмяДокумента=””;
   Для Каждого МетаданныеДок Из Метаданные.Документы Цикл
       Если МетаданныеДок.Синоним=ПредставлениеДокументаСтр Тогда
           ИмяДокумента=МетаданныеДок.Имя;
           Прервать;
       КонецЕсли;    
   КонецЦикла;

       Если ИмяДокумента=”” Тогда
       Сообщить(“Неудачный разбор представления документа”,СтатусСообщения.Важное);
       Возврат Неопределено;
   КонецЕсли;    

       ДатаДокумента=Дата(СтрПолучитьСтроку(МассивСтрок,КоличествоСтрок-1)+” “+СтрПолучитьСтроку(МассивСтрок,КоличествоСтрок));
   НомерДокумента=СтрПолучитьСтроку(МассивСтрок,КоличествоСтрок-3);

       СсылкаДокумента=Документы[ИмяДокумента].НайтиПоНомеру(НомерДокумента,ДатаДокумента);

       Возврат ?(ЗначениеЗаполнено(СсылкаДокумента),СсылкаДокумента,Неопределено);
КонецФункции

   Serg_1960

72 – 07.05.09 – 13:32

Тогда мой вариант с учетом (47) :))

  Для Каждого МетаДок Из Метаданные.Документы Цикл

     ШирокийВредина = 0;

     Если Найти(ДокументСтрока, МетаДок.Синоним) И ШирокийВредина < СтрДлина(МетаДок.Синоним) Тогда

        ДокументСтр = СтрЗаменить(ДокументСтрока, “Документ ” + МетаДок.Синоним + ” “,””);

        ДокументИмя = МетаДок.Имя;

     КонецЕсли;

  КонецЦикла;

  ДокументНомер = Лев(ДокументСтр,Найти(ДокументСтр, ” “)-1);

  ДокументДата = Дата(Лев(СтрЗаменить(ДокументСтр, ДокументНомер + ” от “, “”),19));

  Возврат Документы[ДокументИмя].НайтиПоНомеру(ДокументНомер, ДокументДата);

   Serg_1960

73 – 07.05.09 – 13:33

Протестируйте, плиз, с учетом (57)

   Широкий

74 – 07.05.09 – 13:38

(72) Вообще фигню написал 🙂 Со своей переменной перемудрил

   Serg_1960

75 – 07.05.09 – 13:38

(72) + Блин, забыл добавить 🙁 В “Если… КонецЕсли” нужно добавить строку “ШирокийВредина = СтрДлина(МетаДок.Синоним);”

   Serg_1960

76 – 07.05.09 – 13:39

(74) Согласен 🙂 Имя переменной изменю на “Фигня” :))

   Широкий

77 – 07.05.09 – 13:41

(76) Я кстатит такой алгоритм уже рассматривал -не понравилось что приходится полностью все имена документов перебирать

   Serg_1960

78 – 07.05.09 – 13:47

(77) Теоретически (наверное!) можно и другой алгоритм написать – побыстрее…

И кстати: у меня нет таких документов, как Вы написали (ПриходнаяНакладная и ПриходнаяНакладнаяСклад)…

   Aprobator

79 – 07.05.09 – 13:49

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

   Широкий

80 – 07.05.09 – 13:51

(79) Причем тут соответствие? Посмотри еще раз алгоритм

   Aprobator

81 – 07.05.09 – 13:52

(80) щас – погодь немного.

   Serg_1960

82 – 07.05.09 – 13:52

(79) Мысль понял. Это “сработает” если анализируемых строк – множество. А если одна – то никакой выгоды.

   Aprobator

83 – 07.05.09 – 13:57

(82) ну дык я и рассчитывал на множество строк.

   Serg_1960

84 – 07.05.09 – 13:58

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

   php5

85 – 07.05.09 – 14:00

(0) На инфостарте поищи, кто-то выкладывал обработку на эту тему…

   php5

86 – 07.05.09 – 14:01

   Широкий

87 – 07.05.09 – 14:05

(86) Лажа.. там еще хуже чем в (23)

   Aprobator

88 – 07.05.09 – 14:05

лениво писать, а так можно было бы сделать запрос для каждого дока.
Типа – предварительно обойти метаданные и сделать соответствие как я описывал ранее.
Далее при обработке строки распарсить ее на представление документа и часть с ” Номер от дата”. По представлению проверить, а не делался ли запрос (скорее всего доки обрабатывались по периоду и можно использовать условие между). Запрос возвращает ссылки и представления. РезультатЗапроса тоже закатать куда нить чтоб его можно было потом использовать для доков с данным представлением (можно просто выгрузить в таблицу значений и в соответствие, где ключ – Представление без номера и даты). А там поиск представления без “Документ ” по колонке ТЗ.

   Aprobator

89 – 07.05.09 – 14:06

и вооще у шефа нынче ДР. так что ч пшел есть торты :))))

   Serg_1960

90 – 07.05.09 – 14:10

(86) Фи 🙁 Не цените Вы красоту и лаконичность :(: Так, как там написано (на сто строк) – мне писать заподло :)) Да и не далеко он от нас ушел:



       Для Каждого Документ Из Метаданные.Документы Цикл

           Если Документ.ДлинаНомера = 0 Тогда Продолжить; КонецЕсли;

           Синоним = Документ.Синоним;

           Если Найти(НазваниеДокумента, Синоним) <> 0 Тогда

           ТекстЗапроса = ТекстЗапроса + ?(ЗначениеЗаполнено(ТекстЗапроса),” ОБЪЕДИНИТЬ ВСЕ “, “”);

           ТекстЗапроса = ТекстЗапроса +    ”

           |ВЫБРАТЬ ” + Документ.Имя + “.Ссылка ИЗ Документ.” + Документ.Имя + ”

           |КАК ” +     Документ.Имя + ”

           |ГДЕ

           |    ” +     Документ.Имя + “.Дата = &Дата

           |    И ” +     Документ.Имя + “.Номер = &Номер “;

           КонецЕсли;

       КонецЦикла;

   Широкий

91 – 07.05.09 – 14:11

Провел тесты: 10000 прогонов функций, 17 видов документов:
Мой алгоритм 15 сек
Не мой алгоритм 23 сек

На УПП будет работать еще дольще

   Serg_1960

92 – 07.05.09 – 14:14

Теперь будем соревноваться на скорость? 🙂 Нет проблем. Я уже говорил: я могу и в запросе это все реализовать – мне неслабо… но лениво :))

   Широкий

93 – 07.05.09 – 14:17

(92) А чего соревноваться.. я все уже написал 🙂

   Serg_1960

94 – 07.05.09 – 14:20

Я тоже, что хотел, уже все сказал :))

   svent0vit

95 – 07.05.09 – 14:28

Че, до соточки даже не добъете? 🙂

   Широкий

96 – 07.05.09 – 14:30

Ну если только пофлудить

   Serg_1960

97 – 07.05.09 – 14:31

(95) А я думал что автор уже ушел 🙂 Как скажешь. Можно и продолжить. Начни первым.

   Aprobator

98 – 07.05.09 – 14:47

(90) это запрос с большим запасом. Т.е. могут быть подцеплены лишние виды доков.

   Широкий

99 – 07.05.09 – 15:01

99

   Широкий

100 – 07.05.09 – 15:01

Сотка..
все тему можно прикрыть

// Автор: Alexander Speshilov
// Рекрсивная функция, которая разворачивает строку вида "Метаданные.Справочники.*[Имя].Реквизиты.*.Тип"
// в массив строк, заменяя "*" или другой символ, задаваемый параметрами обходом всех элементов
// коллекции. Допускает выполнение функций встроенного языка (не стоит отдавать ввод параметров
// пользователям). При этом выражение, используемое для получения по умолчанию может быть задано в
// квадратных скобках или параметром функции.
//
// Параметры
// СтрокаОбхода - Строка - Разворачиваемая строка
// ЗаменяемоеЗначение - Строка - заменяемое значение
// ПредставлениеПоУмолчанию - Строка - выражение для получения представления
//
// Возвращаемое значение:
// Массив строк
//
Функция РазвернутьСтрокуОбходаМетаданных(СтрокаОбхода, ЗаменяемоеЗначение = "*", ПредставлениеПоУмолчанию = "")

Рез = Новый Массив;

ЧастиСтрокиОбхода = РазобратьСтрокуОбхода(СтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию);
Если ЧастиСтрокиОбхода = Неопределено тогда
Рез.Добавить(СтрокаОбхода); //фактически это ограничение рекурсии.
Иначе
ОбъектКоллекции = Вычислить(ЧастиСтрокиОбхода.СтрокаКоллекции);
РазвернутаяКоллекция = РазвернутьКоллекциюВПредставления(ОбъектКоллекции, ЧастиСтрокиОбхода.СтрокаПредставление);
Для каждого ЭлементРазвернутойКоллекции Из РазвернутаяКоллекция Цикл

// рекурсивный вызов
ТекущаяСтрокаОбхода = ЧастиСтрокиОбхода.СтрокаНачало + ЭлементРазвернутойКоллекции + ЧастиСтрокиОбхода.СтрокаКонец;
МассивЭлемента = РазвернутьСтрокуОбходаМетаданных(ТекущаяСтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию);

Для каждого ПримитивныйЭлементОбхода Из МассивЭлемента Цикл
Рез.Добавить(ПримитивныйЭлементОбхода);
КонецЦикла;

КонецЦикла;
КонецЕсли;

Возврат Рез;

КонецФункции // РазвернутьСтрокуОбходаМетаданных()

// Разбирает строку обхода на удобные для работы поля
//
// Параметры
// СтрокаОбхода - Строка - Разворачиваемая строка
// ЗаменяемоеЗначение - Строка - заменяемое значение
// ПредставлениеПоУмолчанию - Строка - выражение для получения представления
//
// Возвращаемое значение:
// Структура с полями ПозицияЗамены, СтрокаНачало, СтрокаКоллекции, СтрокаПредставление, СтрокаКонец
// или Неопределено (если строка не содержит ЗаменяемоеЗначение)
//
Функция РазобратьСтрокуОбхода(СтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию)

Если ПустаяСтрока(ЗаменяемоеЗначение) Тогда
ВызватьИсключение "Некорректное выражение заменяемого значения";
КонецЕсли;

ПозицияЗамены = Найти(СтрокаОбхода, ЗаменяемоеЗначение);

// Если не найдена строка - возвращаем неопределено, как индикатор
Если ПозицияЗамены = 0 Тогда
Возврат Неопределено;
КонецЕсли;

СтрокаНачало = Лев(СтрокаОбхода,ПозицияЗамены - 1);

//Получение строки для выражения-коллекции
СтрокаКоллекции = СтрокаНачало;
Если Прав(СтрокаКоллекции, 1) = "." Тогда
СтрокаКоллекции = Лев(СтрокаКоллекции,СтрДлина(СтрокаКоллекции) - 1);
КонецЕсли;

ПозицияОкончанияЗамены = ПозицияЗамены + СтрДлина(ЗаменяемоеЗначение);

ОстатокВыражения = Сред(СтрокаОбхода, ПозицияОкончанияЗамены);

//Обработка явного задания представления
ОткрывающаяСкобка = "[";
ЗакрывающаяСкобка = "]";
Если Найти(ОстатокВыражения, ОткрывающаяСкобка) = 1 Тогда
ОстатокВыражения = Сред(ОстатокВыражения, СтрДлина(ОткрывающаяСкобка) + 1);
ПозицияЗакрывающейСкобки = Найти(ОстатокВыражения, ЗакрывающаяСкобка);
Если ПозицияЗакрывающейСкобки = 0 Тогда
ВызватьИсключение "Синтаксическая ошибка разбора выражения";
КонецЕсли;
СтрокаПредставление = Лев(ОстатокВыражения, ПозицияЗакрывающейСкобки - 1);
ОстатокВыражения = Сред(ОстатокВыражения, ПозицияЗакрывающейСкобки + СтрДлина(ЗакрывающаяСкобка));
Иначе
СтрокаПредставление = ПредставлениеПоУмолчанию;
КонецЕсли;
СтрокаКонец = ОстатокВыражения;

Рез = Новый Структура("ПозицияЗамены, СтрокаНачало, СтрокаКоллекции, СтрокаПредставление, СтрокаКонец",
ПозицияЗамены, СтрокаНачало, СтрокаКоллекции, СтрокаПредставление, СтрокаКонец);

Возврат Рез;

КонецФункции // РазобратьСтрокуОбхода()

// Разворачивает объект коллекции в массив представления элементов
//
// Параметры
// Коллекция - Произвольный - Коллекция, которую можно обойти через "Для каждого"
// ПредставлениеЭлемента - Строка - необяз., свойство элементов коллекции, которое
// используется для получения представления.
//
// Возвращаемое значение:
// Массив - Массив представлений коллекции
//
Функция РазвернутьКоллекциюВПредставления(Коллекция, Знач ПредставлениеЭлемента = "")

//Проверка и подгонка параметров
Если не ПустаяСтрока(ПредставлениеЭлемента) Тогда
Если Найти(ПредставлениеЭлемента, ";")>0 Тогда
ВызватьИсключение "Некорректное выражение представления";
КонецЕсли;
ПредставлениеЭлемента = "." + ПредставлениеЭлемента;
КонецЕсли;

Рез = Новый Массив;
Для каждого ЭлементКоллекции Из Коллекция Цикл
ТекПредставление = Строка(Вычислить("ЭлементКоллекции" + ПредставлениеЭлемента));
Рез.Добавить(ТекПредставление);
КонецЦикла;
Возврат Рез;

КонецФункции // РазвернутьКоллекцию()

// Разворачивает массив строк через РазвернутьСтрокуОбходаМетаданных
//
// Параметры
// МассивСтрокОбхода - Массив - Массив разворачиваемых строк
// ЗаменяемоеЗначение - Строка - заменяемое значение
// ПредставлениеПоУмолчанию - Строка - выражение для получения представления
//
// Возвращаемое значение:
// Массив строк
//
Функция РазвернутьМассивСтрокОбходаМетаданных(МассивСтрокОбхода, ЗаменяемоеЗначение = "*", ПредставлениеПоУмолчанию = "Имя")

Рез = Новый Массив;

Для каждого СтрокаОбхода Из МассивСтрокОбхода Цикл

ДополнениеРезультата = РазвернутьСтрокуОбходаМетаданных(СтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию);
Для каждого ТекСтрока Из ДополнениеРезультата Цикл
Рез.Добавить(ТекСтрока);
КонецЦикла;

КонецЦикла;

Возврат Рез;

КонецФункции // РазвернутьМассивСтрокОбходаМетаданных()

// Преобразует строку в массив одиночных строк по разделителю Символы.ПС
//
// Параметры
// ПреобразуемаяСтрока - строка для преобразования
// ИгнорироватьПустые - Булево - Пропускать пустые строки
// СокращатьПробелы - Использовать СокрЛП
//
// Возвращаемое значение:
// Массив строк
//
Функция ПолучитьМассивСтрокМногострочнойСтроки(ПреобразуемаяСтрока, ИгнорироватьПустые = Истина, СокращатьПробелы = Истина)

Рез = Новый Массив;
ЧислоСтрок = СтрЧислоСтрок(ПреобразуемаяСтрока);

Для Сч = 1 По ЧислоСтрок Цикл

ТекСтрока = СтрПолучитьСтроку(ПреобразуемаяСтрока, Сч);
Если ИгнорироватьПустые и ПустаяСтрока(ТекСтрока) Тогда
Продолжить;
КонецЕсли;
Если СокращатьПробелы Тогда
ТекСтрока = СокрЛП(ТекСтрока);
КонецЕсли;
Рез.Добавить(ТекСтрока);

КонецЦикла;

Возврат Рез;

КонецФункции // ПолучитьМассивСтрокМногострочнойСтроки()

// Возвращает все реквизиты конфигурации, которые сохраняются в ИБ
//
// Параметры - Нет
//
// Возвращаемое значение:
// Массив объектов метаданных
//
Функция ПолучитьВсеХранимыеРеквизитыКонфигурации() Экспорт

СтрокаВсехРеквизитов =
"
|Метаданные.Константы.*
|Метаданные.ПланыОбмена.*.Реквизиты.*
|Метаданные.ПланыОбмена.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.Справочники.*.Реквизиты.*
|Метаданные.Справочники.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.Документы.*.Реквизиты.*
|Метаданные.Документы.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.Последовательности.*.Измерения.*
|Метаданные.ПланыВидовХарактеристик.*.Реквизиты.*
|Метаданные.ПланыВидовХарактеристик.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.ПланыСчетов.*.Реквизиты.*
|Метаданные.ПланыСчетов.*.ПризнакиУчета.*
|Метаданные.ПланыСчетов.*.ПризнакиУчетаСубконто.*
|Метаданные.ПланыСчетов.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.ПланыВидовРасчета.*.Реквизиты.*
|Метаданные.ПланыВидовРасчета.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.РегистрыСведений.*.Измерения.*
|Метаданные.РегистрыСведений.*.Ресурсы.*
|Метаданные.РегистрыСведений.*.Реквизиты.*
|Метаданные.РегистрыНакопления.*.Измерения.*
|Метаданные.РегистрыНакопления.*.Ресурсы.*
|Метаданные.РегистрыНакопления.*.Реквизиты.*
|Метаданные.РегистрыБухгалтерии.*.Измерения.*
|Метаданные.РегистрыБухгалтерии.*.Ресурсы.*
|Метаданные.РегистрыБухгалтерии.*.Реквизиты.*
|Метаданные.РегистрыРасчета.*.Измерения.*
|Метаданные.РегистрыРасчета.*.Ресурсы.*
|Метаданные.РегистрыРасчета.*.Реквизиты.*
|Метаданные.БизнесПроцессы.*.Реквизиты.*
|Метаданные.БизнесПроцессы.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.Задачи.*.Реквизиты.*
|Метаданные.Задачи.*.РеквизитыАдресации.*
|Метаданные.Задачи.*.ТабличныеЧасти.*.Реквизиты.*
|";
ВсеХранимыеРеквизитыКонфигурации = РазвернутьМассивСтрокОбходаМетаданных(ПолучитьМассивСтрокМногострочнойСтроки(СтрокаВсехРеквизитов));
Возврат ВсеХранимыеРеквизитыКонфигурации;

КонецФункции // ПолучитьВсеХранимыеРеквизитыКонфигурации()

// Возвращает все реквизиты конфигурации составного типа, которые сохраняются в ИБ
//
// Параметры - Нет
//
// Возвращаемое значение:
// ТаблицаЗначений
//
Функция ПолучитьВсеХранимыеРеквизитыКонфигурацииСоставногоТипа() Экспорт

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

Для каждого ТекРеквизит Из ВсеХранимыеРеквизитыКонфигурации Цикл

Реквизит = Вычислить(ТекРеквизит);
Тип = Реквизит.Тип;
КоличествоПростыхТипов = Тип.Типы().Количество();
Если КоличествоПростыхТипов<>1 Тогда
ТекСтрока = Рез.Добавить();
ТекСтрока.Имя = ТекРеквизит;
ТекСтрока.Тип = Тип;
ТекСтрока.КоличествоПростыхТипов = КоличествоПростыхТипов;
КонецЕсли;

КонецЦикла;

Возврат Рез;

КонецФункции // ПолучитьВсеХранимыеРеквизитыКонфигурации()

// Возвращает все формы конфигурации
//
// Параметры - Нет
//
// Возвращаемое значение:
// Массив объектов метаданных
//
Функция ПолучитьВсеФормыКонфигурации() Экспорт

СтрокаВсехРеквизитов =
"
|Метаданные.ПланыОбмена.*.Формы.*
|Метаданные.КритерииОтбора.*.Формы.*
|Метаданные.ОбщиеФормы.*
|Метаданные.Справочники.*.Формы.*
|Метаданные.Документы.*.Формы.*
|Метаданные.ЖурналыДокументов.*.Формы.*
|Метаданные.Перечисления.*.Формы.*
|Метаданные.Отчеты.*.Формы.*
|Метаданные.Обработки.*.Формы.*
|Метаданные.ПланыВидовХарактеристик.*.Формы.*
|Метаданные.ПланыСчетов.*.Формы.*
|Метаданные.ПланыВидовРасчета.*.Формы.*
|Метаданные.РегистрыСведений.*.Формы.*
|Метаданные.РегистрыНакопления.*.Формы.*
|Метаданные.РегистрыБухгалтерии.*.Формы.*
|Метаданные.РегистрыРасчета.*.Формы.*
|Метаданные.БизнесПроцессы.*.Формы.*
|Метаданные.Задачи.*.Формы.*
|";
ВсеФормыКонфигурации = РазвернутьМассивСтрокОбходаМетаданных(ПолучитьМассивСтрокМногострочнойСтроки(СтрокаВсехРеквизитов));
Возврат ВсеФормыКонфигурации;

КонецФункции // ПолучитьВсеФормыКонфигурации()

// Возвращает все макеты конфигурации
//
// Параметры - Нет
//
// Возвращаемое значение:
// Массив объектов метаданных
//
Функция ПолучитьВсеМакетыКонфигурации() Экспорт

СтрокаВсехРеквизитов =
"
|Метаданные.ПланыОбмена.*.Макеты.*
|Метаданные.ОбщиеМакеты.*
|Метаданные.Справочники.*.Макеты.*
|Метаданные.Документы.*.Макеты.*
|Метаданные.ЖурналыДокументов.*.Макеты.*
|Метаданные.Перечисления.*.Макеты.*
|Метаданные.Отчеты.*.Макеты.*
|Метаданные.Обработки.*.Макеты.*
|Метаданные.ПланыВидовХарактеристик.*.Макеты.*
|Метаданные.ПланыСчетов.*.Макеты.*
|Метаданные.ПланыВидовРасчета.*.Макеты.*
|Метаданные.РегистрыСведений.*.Макеты.*
|Метаданные.РегистрыНакопления.*.Макеты.*
|Метаданные.РегистрыБухгалтерии.*.Макеты.*
|Метаданные.РегистрыРасчета.*.Макеты.*
|Метаданные.БизнесПроцессы.*.Макеты.*
|Метаданные.Задачи.*.Макеты.*
|";
ВсеМакетыКонфигурации = РазвернутьМассивСтрокОбходаМетаданных(ПолучитьМассивСтрокМногострочнойСтроки(СтрокаВсехРеквизитов));
Возврат ВсеМакетыКонфигурации;

КонецФункции // ПолучитьВсеМакетыКонфигурации()

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

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

Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
 
 СтандартнаяОбработка = Ложь;
 
 СписокПоиска = ПолнотекстовыйПоиск.СоздатьСписок(Параметры.СтрокаПоиска, 50);
 ОбластьПоиска = Новый Массив;
 ОбластьПоиска.Добавить(Метаданные.Справочники.Номенклатура);
 СписокПоиска.ОбластьПоиска = ОбластьПоиска;
 СписокПоиска.ПерваяЧасть();
 
 Если СписокПоиска.Количество() Тогда
  ДанныеВыбора = Новый СписокЗначений;
  Для Каждого ЭлементПоиска Из СписокПоиска Цикл
   ЗаполнитьЗначенияСвойств(ДанныеВыбора.Добавить(), ЭлементПоиска);
  КонецЦикла;
 КонецЕсли;
 
КонецПроцедуры

Проверяем работу кода. Добавляем описание товара, не забываем обновить индекс полнотекстового поиска.

Выполняем ввод по строке в документе:

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

Свойство Значение Тип
ЭлементПоиска ЭлементСпискаПолнотекстовогоПоиска ЭлементСпискаПолнотекстовогоПоиска
Значение Стол журнальный СправочникСсылка.Номенклатура
Метаданные Список товаров ОбъектМетаданных
Описание “Описание товара: Стекло, дуб, ковка” Строка
Представление “Стол журнальный” Строка

Перепишем заполнение элементов списка, представление элемента списка формируем из свойств “Представление” и “Описание”.

Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
 
 СтандартнаяОбработка = Ложь;
 
 СписокПоиска = ПолнотекстовыйПоиск.СоздатьСписок(Параметры.СтрокаПоиска, 50);
 СписокПоиска.ОбластьПоиска.Добавить(Метаданные.Справочники.Номенклатура);   
 СписокПоиска.ПерваяЧасть();
 
 Если СписокПоиска.Количество() Тогда
  
  ДанныеВыбора = Новый СписокЗначений;
  Для Каждого ЭлементПоиска Из СписокПоиска Цикл
   ДанныеВыбора.Добавить(ЭлементПоиска.Значение, ЭлементПоиска.Представление + "; " + ЭлементПоиска.Описание);
  КонецЦикла;
  
 КонецЕсли;
 
КонецПроцедуры

Результат уже несколько лучше.

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

Синтаксис-помощник подсказывает, что представлением элемента списка может выступать как Строка, так и ФорматированнаяСтрока. Ок, это как раз наш вариант. Осталось только выделить результат поиска в описании элемента. Используя метод ПолучитьОтображение можно получить отображение результата полнотекстового поиска в HTML и XML представлениях.

<html>
<head>
    <style type="text/css">
        html { overflow:auto; }
        body { margin: 10px; font-family: Arial,sans-serif; font-size: 10pt; overflow:auto; }
        div.main { overflow:auto; height:100%; }
        div.presentation { font-size: 11pt; }
        div.textPortion { padding-bottom: 16px; }
        span.bold { font-weight: bold; }
        a { text-decoration:none; color:#0066CC; }
        a:hover { text-decoration:underline; }
    </style>
</head>
<body>
    <div class="main">
        <div class="presentation">
            <a id="FullTextSearchListItem" href="#" sel_num="0">Список товаров: Стол журнальный</a>
        </div>
        <div class="textPortion">
            Описание товара: <span class="bold" style="background-color:#CCFFCC">Стекло</span>, дуб, ковка
        </div>
    </div>
</body>
</html>

HTML-представление показалось мне неудобным для разбора, поэтому используем второй вариант. XML-представление дает на выходе объект ЧтениеXML, который в свою очередь передается в ПостроительDOM. Окончательный вариант процедуры:

Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
 
 СтандартнаяОбработка = Ложь;
 
 СписокПоиска = ПолнотекстовыйПоиск.СоздатьСписок(Параметры.СтрокаПоиска, 50);
 СписокПоиска.ОбластьПоиска.Добавить(Метаданные.Справочники.Номенклатура);   
 СписокПоиска.ПерваяЧасть();
 
 Если СписокПоиска.Количество() Тогда
  
  ОписаниеСписка = СписокПоиска.ПолучитьОтображение(ВидОтображенияПолнотекстовогоПоиска.XML);
  ЧтениеДОМ = Новый ПостроительDOM;
  ПредставлениеСписка = ЧтениеДОМ.Прочитать(ОписаниеСписка);
  СписокПредставлений = ПредставлениеСписка.ПолучитьЭлементыПоИмени("textPortion");
  МассивПредставлений = Новый Массив;
  
  ШрифтВыделения = Новый Шрифт(,,Истина);
  ЦветВыделения = WebЦвета.Зеленый;
  
  Для Каждого ЭлементПредставления Из СписокПредставлений Цикл
   
   МассивФормата = Новый Массив;
   Для Каждого ДочернийУзел Из ЭлементПредставления.ДочерниеУзлы Цикл
    
    Если ДочернийУзел.ТипУзла = ТипУзлаDOM.Текст Тогда
     ШрифтСтроки = Неопределено;     
     ЦветСтроки = Неопределено;
    ИначеЕсли ДочернийУзел.ТипУзла = ТипУзлаDOM.Элемент Тогда
     ШрифтСтроки = ШрифтВыделения;
     ЦветСтроки = ЦветВыделения;
    КонецЕсли;
    СтрокаФормата = Новый ФорматированнаяСтрока(ДочернийУзел.ТекстовоеСодержимое, ШрифтСтроки, ЦветСтроки);
    МассивФормата.Добавить(СтрокаФормата);
    
   КонецЦикла;
   
   МассивПредставлений.Добавить(МассивФормата);
   
  КонецЦикла;
   
  ДанныеВыбора = Новый СписокЗначений;
  НомерЭлемента = 0;
  Для Каждого ЭлементПоиска Из СписокПоиска Цикл
   
   НомерЭлемента = НомерЭлемента + 1;   
   Значение = ЭлементПоиска.Значение;
   Если Значение.ЭтоГруппа Тогда
    Продолжить;
   КонецЕсли;
   
   ПредставлениеЭлемента = Новый ФорматированнаяСтрока(ЭлементПоиска.Представление + ", ", МассивПредставлений[НомерЭлемента - 1]);
   ЭлементСписка = ДанныеВыбора.Добавить(ЭлементПоиска.Значение, ПредставлениеЭлемента);
   
  КонецЦикла;
  
 КонецЕсли;
 
КонецПроцедуры

Проверяем, результат получается вполне сносный.

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

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

В поле «Найти» этого диалога следует ввести образец для поиска или нажать кнопку  раскрытия списка и выбрать один из образцов, которые были использованы ранее в операциях поиска.

Чтобы различать при поиске прописные и строчные буквы, установите флажок «Учитывать регистры». При установленном флажке «Искать целые слова» будут найдены только целые слова, а не части слов.

Группа «Искать в» позволяет указать, где следует искать указанный образец. Если все флажки отключены, поиск производиться не будет.

Нажатие кнопки «Дополн.>>» открывает управляющие элементы для включения в поиск внешних отчетов и обработок.

Флажки «Искать в конфигурации» и «Искать во внешних отчетах и обработках» позволяют выбрать область поиска. Если оба флажка сняты, поиск выполняться не будет.

Если флажок «Искать во внешних отчетах и обработках» установлен, в поле «Путь» необходимо указать имя каталога, в котором располагаются внешние отчеты. Нажав кнопку «…», можно открыть стандартный диалог выбора каталога.

Для начала поиска следует нажать кнопку «Искать». В процессе поиска в окно «Список найденных вхождений» будут выдаваться строки, содержащие указанную последовательность символов.

В любого момента можно процесс поиска прервать, нажав клавишу Esc. На экран будет выдан запрос «Прервать выполнение обработки?», в котором можно подтвердить прекращение поиска, ответив «Да», или продолжить его.

По окончании поиска в окне «Список найденных вхождений» будет выдан список найденных вхождений искомой строки.

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

Из списка найденных вхождений можно также выполнить замену найденной строки. Для этого необходимо выделить строку, в которой требуется произвести замену, нажатием правой кнопки мыши вызвать контекстное меню и выбрать пункт «Заменить».

На экран будет выдан диалог «Замена во всех текстах».

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

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

Наконец, в поле «на:» диалога следует ввести строку замены или нажать кнопку  раскрытия списка и выбрать одну из строк, которые были использованы для замены ранее.

Назначение кнопок этого диалога достаточно простое:

·        кнопка «Закрыть» закрывает диалог;

·        кнопка «Заменить» выполняет замену в текущей строке и переходит к следующей строке списка найденных вхождений;

·        кнопка «Пропустить» выполняет переход к следующей строке списка найденных вхождений без выполнения замены в текущей строке;

·        кнопка «Для всех» выполняет замену сразу для всех строк списка найденных вхождений.

Содержание:

1.      Когда возникает необходимость проверить наличие реквизита 1С?

2.      Как можно получить метаданные объекта 1С?  

1.    Когда возникает необходимость проверить наличие реквизита 1С

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

В ряде типовых конфигураций 1С предлагается стандартная функция проверки наличия реквизита в объекте (расположена в модуле “ОбщегоНазначения”)

Функция ЕстьРеквизитОбъекта(ИмяРеквизита, МетаданныеОбъекта) Экспорт

            Возврат НЕ (МетаданныеОбъекта.Реквизиты.Найти(ИмяРеквизита) = Неопределено);

КонецФункции   

2. Как можно получить метаданные объекта 1С

Однако написать свою функцию также не представляет труда. В первую очередь необходимо получить метаданные объекта 1С одним из способов:

через функцию Метаданные() объекта

пример синтаксиса: СправочникСсылка.Метаданные()

                                    ДокументСсылка.Метаданные()

через свойство глобального контекста Метаданные

пример синтаксиса: Метаданные.Справочники.[ИмяСправочника]

                                    Метаданные.Документы.[ИмяДокумента]

Далее через свойство “Реквизиты” использовать функцию Найти(). В случае, если реквизит не найден, возвращается значение Неопределено.

Пример 1

Метаданные = Контрагент.Метаданные();

Если Метаданные.Реквизиты.Найти(«Ответственный») = Неопределено Тогда

            Возврат Ложь;

Иначе

            Возврат Истина;

КонецЕсли;

Пример 2

Функция ПолучитьОрганизацию(Контрагент, Пользователь)

            Если Метаданные.Справочники.Контрагенты.Реквизиты.Найти(«Организация») <> Неопределено Тогда

                        Возврат Контрагент.Организация;

            Иначе

                        Возврат Пользователь.Организация;

            КонецЕсли;

КонецФункции

Описанный алгоритм подходит для случаев проверки наличия реквизита шапки. Но что делать, когда возникает необходимость определить, существует ли реквизит в табличной части 1С (справочника или документа)? Для этого используется следующая конструкция:

Метаданные.Справочники.<ИмяСправочника>.ТабличныеЧасти.Реквизиты.Найти(<ИмяОбъектаПоиска>).

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

Пример синтаксиса:

Если НЕ ТекущаяСтрока.Свойство(«Исключить») ИЛИ НЕ ТекущаяСтрока.Исключить Тогда

            ЗаполнитьЗначенияСвойств(ТаблицаЗагрузки.Добавить(); ТекущаяСтрока);

КонецЕсли;

Специалист компании ООО «Кодерлайн»

Кондренко Анна Сергеевна

Добавить комментарий