gifts2017

HTML - это просто: Программное формирование HTML документа, содержащего ссылки на объекты БД

Опубликовал Дмитрий К (ll13) в раздел Программирование - Практика программирования

В данной статье рассматривается способ программного формирования HTML документа, содержащего ссылки на объекты базы данных, такие как справочники, документы и т.д. Показан пример построения обработчика события OnClick ПоляHTMLДокумента, для обработки клика на html -ссылке.

Предисловие

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

"Создан документ такой-то"

"Изменен документ такой-то" и т.д.

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

То, что в форме есть элемент управления именуемый ПолеHTMLДокумента я конечно знал, но вот представилась возможность познакомиться с ним поближе. Было решено реестр обработанных документов выводить в виде html документа содержащего ссылки на эти самые документы, а по клику на ссылке открывать форму соответствующего документа. Здесь мне многие могут возразить: "А почему бы для этих целей не использовать обычный макет, выводимый в табличный документ, а для открытия документов использовать расшифровку? И чем Ваш способ лучше?" Отвечаю: Конечно можно использовать, и мой способ ничем не лучше. Он просто другой. Ведь у хорошего программиста  для решения одной задачи должно быть в арсенале несколько инструментов :)

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

Создаем новый отчет, его форму, на форме размещаем элемент управления ПолеHTMLДокумента.

Текст модуля формы:


Процедура ДобавитьТекстHTML(ТекстHTML, Элемент);
   
// Ссылку будем формировать хитро:
    // Предполагаем что символ "-" не входит в имена объектов метаданных,
    // учавствующих в формировании html
    // Тогда ссылка будет иметь следующий вид:
    // Номенклатура-d341d377-b3b1-11dc-a100-0011d85708ff
    // Передавать нашу ссылку будем через атрибут id
   
СсылкаНаЭлемент = Элемент.Метаданные().Имя+"-"
   
+Элемент.Ссылка.УникальныйИдентификатор();
   
ТекстHTML.ДобавитьСтроку("<A id=""" + СсылкаНаЭлемент + """ href= """
   
+ Элемент + """ >"+Элемент+"</A><BR>");
КонецПроцедуры

Процедура
ДействияФормыСформировать(Кнопка)
   
Запрос = Новый Запрос("
    |ВЫБРАТЬ
    |    Номенклатура.Ссылка
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура"
);
   
ТекстHTML = Новый ТекстовыйДокумент;
   
Выборка = Запрос.Выполнить().Выбрать();
    Пока
Выборка.Следующий() Цикл
       
ДобавитьТекстHTML(ТекстHTML, Выборка.Ссылка);
    КонецЦикла;
ЭлементыФормы.ПолеHTMLДокумента.УстановитьТекст(ТекстHTML.ПолучитьТекст());
КонецПроцедуры

Ну вот html мы сформировали, теперь что бы ссылки "ожили" надо написать обработчик события OnClick элемента управления ПолеHTMLДокумента.

Процедура ПолеHTMLДокументаonclick(Элемент, pEvtObj)
   
htmlElement = НайтиСсылку(pEvtObj.srcElement);
   
// Анализируем если произошло нажание не ссылку
   
Если htmlElement <> Неопределено Тогда
       
// Если у ссылки есть идентификатор
       
Если СокрЛП(htmlElement.id) <> "" Тогда
           
// Получаем ссылку из атрибута id
           
СсылкаНаЭлемент = htmlElement.id;
           
Разделитель = Найти(СсылкаНаЭлемент,"-");
            Если
Разделитель > 0 Тогда
               
// Получаем тип элемента
               
ТипЭлемента = Лев(СсылкаНаЭлемент,Разделитель-1);
               
// Получаем УникальныйИдентификатор
               
ГУИД = Сред(СсылкаНаЭлемент,Разделитель+1);
               
Справочники[ТипЭлемента].ПолучитьСсылку(Новый УникальныйИдентификатор(ГУИД)).ПолучитьФорму().Открыть();
            КонецЕсли;
           
// Отказ от стандартной обработки клика
           
pEvtObj.returnValue = Ложь;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Функция
НайтиСсылку(Элемент)
   
Врем = Элемент;
    Пока
Врем <> Неопределено Цикл
        Если
НРег(Врем.tagName) = "a" Тогда
            Возврат
Врем;
        КонецЕсли;
       
Врем = Врем.parentElement;
    КонецЦикла;
    Возврат Неопределено;
КонецФункции

Всё можно пробовать! см. Рис.1

Заключение

Обратите внимание что ссылку я формировал следующим образом:

<ИмяОбъектаМетаданных>-<УникальныйИдентификатор> это сделано для того, чтобы в обработчике можно было определить к какому объекту метаданных относится данный УникальныйИдентификатор, потому что имея ТОЛЬКО УникальныйИдентификатор невозможно определить к какому объекту метаданных он относиться. Точнее возможно, но уж слишком долго и неудобно - путем перебора всех метаданных в цикле, для каждого объекта метаданных выполнять попытку <ОбъектМетаданных>.ПолучитьСсылку(Новый УникальныйИдентификатор(НашУникальныйИдентификатор))

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

P.S. Платформа 8.2 имеет встроенный механизм работы со ссылками на объекты БД и данная задача наверняка упростится, но это уже другая тема.

P.P.S. Как выяснилось, в ходе обсуждения этой статьи, существует и более простой способ формирования ссылки на объект БД. Выкладываю пример кода, в котором ссылка формируется по методу о котором написал в форуме Saint:


Источник: http://www.obrabotki.com/1s-create-html-1/

http://www.obrabotki.com/1s-create-html-2/

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
ФормиированиеHTML.rar
.rar 8,62Kb
16.06.15
7
.rar 8,62Kb 7 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Валерий Гуров (Saint) 20.02.10 20:54
Слишком сложное формирование ссылки объекта. Достаточно пары фукнций ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр(). А событие onclick можно обработать проще:
// Отказ от стандартной обработки клика.
pEvtObj.returnValue = Ложь;

Если ВРег(pEvtObj.srcElement.tagName) = "A" Тогда
	
	СсылкаТекст = Сред(pEvtObj.srcElement.href, 4);
	Ссылка = ЗначениеИзСтрокиВнутр(СсылкаТекст);
	Если Ссылка.Пустая() Или Ссылка.ПолучитьОбъект() = Неопределено Тогда
		
		Предупреждение("Выбранный объект был удалён.",, "Объект удалён");
		Возврат;
		
	Иначе
		ОткрытьЗначение(Ссылка);
	КонецЕсли;
	
КонецЕсли; 
...Показать Скрыть
MCitrus; awa; Новенький; Ish_2; artbear; +5 Ответить 3
2. Дмитрий К (ll13) 20.02.10 21:30
(1) Ваш вариант неработоспособен, у меня была первая мысль сделать именно так как Вы написали, но наступил на грабли.
ЗначениеВСтрокуВнутр() возвращает строку вида {"#",e18d5670-dd2f-4528-8897-d3f07ca77f21,37:a1050011d85708ff11dcb5e99d48b4a8} в html тег вы её не запихнете, точнее запихнете, но обратно не получите. Если у Вас есть работоспособная обработка формирующая и обрабатывающая ссылки с помощью
ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр() выложите плиз.
5. Валерий Гуров (Saint) 20.02.10 22:04
Отвечаю на удалённое сообщение.
Во первых я с тобой водку не пил

Это точно, ибо я спиртное не употребляю. :D
По русски понимаешь ? Пишу ещё раз: Если есть работоспособный вариант выложи его.

Я по-русски понимаю. А ты? Весь смысл обработки я тебе уже написал. Добавлю ещё раз замечание из своего удалённого ответа: сделай
"v8:" + ЗначениеВСтрокуВнутр(ТвояСсылка)

и будет тебе счастье.
6. Аркадий Кучер (Abadonna) 20.02.10 22:11
Тон не сбавите - буду все посты удалять.
7. maxp77 (maxp77) 20.02.10 22:18
Мой подход к решению:
стрOpenOrganization = "OpenInsuranceOrganization";
ОрганизацияИд	= Строка(МенеджерЗаписи_Пациент_Контакты.Контакт.Владелец.УникальныйИдентификатор());
ОрганизацияКонтакта	= "какое-то описание";
/////////////////////////////
// это кусок HTML
|			<P id=ОрганизацияКонтакта style=""DISPLAY:inline"">"+ОрганизацияКонтакта+"</P>
////////////////////////////
Процедура ПолеHTMLДокументаOnClick(Элемент, pEvtObj, Форма) Экспорт
	
	ЭлементHTML = НайтиЭлемент(pEvtObj.srcElement, "A");
	Если ЭлементHTML = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ЭлементHTML.id = "Команда" Тогда
		Попытка
			Форма.ВыполнитьКомандуФормы(ЭлементHTML.pathname, ЭлементHTML.target);
		Исключение
			// в случае неверной или недоступной по правам команды ничего не делаем
		КонецПопытки;
		pEvtObj.returnValue = Ложь;
		
	КонецЕсли;
	
КонецПроцедуры
//////////////////////////
Процедура ВыполнитьКомандуФормы(Команда, Значение) Экспорт

	Если Не ЗначениеЗаполнено(МенеджерЗаписи_Пациент_Контакты.Контакт) Тогда
		Возврат;
	КонецЕсли;

	Если Команда = "OpenInsuranceOrganization" Тогда

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

	КонецЕсли;

КонецПроцедуры

...Показать Скрыть
8. Валерий Гуров (Saint) 20.02.10 22:19
(6) У меня нормальный тон. Если человек не понимает шуток - тогда прошу прощения.
9. Аркадий Кучер (Abadonna) 20.02.10 22:21
10. maxp77 (maxp77) 20.02.10 22:22
///туда
Строка(___.УникальныйИдентификатор());
///оттуда
XMLЗначение(Тип("СправочникСсылка.___"), Значение);
11. Валерий Гуров (Saint) 20.02.10 22:22
(7) Мне кажется, что мой вариант проще и универсальнее. Но это уже дело хозяйское. ;)
12. Ярослав Радкевич (WKBAPKA) 21.02.10 12:13
2(1): + 1 первое что в голову пришло при чтении статьи
13. Ярослав Радкевич (WKBAPKA) 21.02.10 12:14
2(2): строку легко можно преобразовать к удобочитаемому виду... хотя с другой стороны, зачем козе боян, если можно сделать так как в статье )
14. Ярослав Радкевич (WKBAPKA) 21.02.10 12:17
А вот это
Если СокрЛП(htmlElement.id) <> "" Тогда

можно переписать вот так:
Если Не ПустаяСтрока(htmlElement.id)  Тогда


лучше смотриться

но идея интересная, за статью +

ПЫСЫ: вы уже и поругаться тут успели :D
15. Сергей Шестопалов (Shestik) 23.02.10 09:20
Люди подскажите, а есть более универсальный вариант обработки onclick... Данный пример заточен под справочники...Конечно труда не составляет переделать его под другие объекты метаданных...Но может есть более универсальный способ...Например, работать, как со справочниками так и с документами...
16. Валерий Гуров (Saint) 23.02.10 09:25
(15) Смотри мои 1 и 5 ответы. Изложенный в них способ универсален.
17. Сергей Шестопалов (Shestik) 23.02.10 10:21
(16) Извини не могу разобраться! Приведенный код не работает! Может есть рабочий примерчик!!Буду рад!!
18. Валерий Гуров (Saint) 23.02.10 11:31
(17) Приведенный код работает. Делать примерчик времени пока нет.
19. Дмитрий К (ll13) 24.02.10 10:47
(17) Выложил рабочий пример, по методу saint'а, см. статью
Shestik; Saint; Ish_2; +3 Ответить 1
20. apalon_pss (pavel_pss) 24.02.10 21:50
Эх, чувак, где ты был раньше :) . Но все равно полезно
21. Сергей Шестопалов (Shestik) 25.02.10 05:30
(19) Большое спасибо!! Будемс работать!!
22. Игорь Каверин (profes) 25.02.10 09:38
[+] За освоение новых технологий V8 :)
23. Алексей (Жарков) 27.02.10 12:11
Спасибо, буду использовать. Хорошая идея.

По оформлению статьи - чтобы правильно выводился код, несмотря на наличие HTML-тегов можно использовать тег CODE вместо картинок. Тогда и пользователям легче использовать будет.
24. Александр Гладких (yku) 18.03.10 22:43
(1),(2) и др. Ну что вы велосипед изобретаете? ведь есть же в типовой УТ в форме задачи пользователя:
" + ?(ТипЗнч(Содержимое) = Тип("Строка"), СтрЗаменить(Содержимое, Символы.ПС, ""), "" + Строка(Содержимое) + "") + "</td>

то бишь они берут просто ЗначениеВСтрокуВнутр() и запихивают в id, где он прекрасно сохраняется :).
25. Валерий Гуров (Saint) 18.03.10 23:25
(24) А у тебя проблемы с изобретением велосипедов? Описанный тобой способ является не более чем ещё одним способом решения указанного вопроса и не сильно отличается от предложенного мной варианта. К тому же мной этот вариант был придуман ещё тогда, когда в типовой об этом, скорее всего, нервно курили. Так что тут ещё вопрос, кто изобретает велосипед.
26. Александр Гладких (yku) 19.03.10 00:12
(25) ого - немного ошарашен тоном. Предложенный вами вариант (в том виде, в каком он здесь опубликован) все-таки не работоспособен из-за наличия символа "#" в получаемой строке. И хоть это ограничение обходится за десять секунд, но обходить-то его надо. Так что вариант из типовой - легче. А существенных отличий действительно нет.

О "велосипеде" было к слову. Сожалею, что это вас "задело".
27. Дмитрий К (ll13) 19.03.10 00:25
(26) Оба варианта, которые опубликованы в статье полностью работоспособны, 2-ой вариант который предложил saint наиболее простой и универсальный. Специально замечу что символ "#" нисколько не мешает ему работать ;)
28. Валерий Гуров (Saint) 19.03.10 00:30
(26) Меня это не задело. Просто не нужно утверждать, что типовая - это круто и только там может быть правильное решение. И прежде чем утверждать, что вариант не рабочий, это не мешало бы для начала проверить. МОЙ вариант у меня работает уже года эдак 4. Почему мне не мешает символ "#"?
29. Александр Гладких (yku) 19.03.10 00:36
(27) хм. а у меня мешает :(. Нет, серьезно. 1с стопорится при получении значения href. Пропадают все символы до #. Причем, если до последнего символа "#". То есть, если завернуть во всякие структуры, массивы и проч - теряется. может, от версии IE зависит?
30. Дмитрий К (ll13) 19.03.10 00:38
(29) Всё дело в волшебных пузырьках :D , а точнее в префиксе "v8:"
31. Александр Гладких (yku) 19.03.10 00:40
(30) да ставлю я его. проверил на другом компе - нормально. что за магия? или просто спать пора?
32. Валерий Гуров (Saint) 19.03.10 01:16
(31) Фиг его знает. Вариант нормально работал на IE, начиная с версии 6. Тем более что у меня используется не простой HTML, а преобразование XSL. И проблем не возникало никогда. Так что спать! :D
sergmorozov; +1 Ответить
33. Олег Пономаренко (O-Planet) 29.03.10 09:40
Это все замечательно... Но вот реально что хочется, так это работать внутри html с объектами 1С, как с объектами именно, т.е. обращаться к их реквизитам, изменять их при необходимости и т.д. На javascript... Эх... :(
34. Олег Пономаренко (O-Planet) 29.03.10 09:41
Поясню... Передаю, скажем, список в html, там сортирую, и он в 1С соотвественно отсортирован...
35. Валерий Гуров (Saint) 29.03.10 10:08
(34) Мда... А что мешает передать уже отсортированный средствами 1С список? HTML как бы немного не предназначен для таких операций.
36. Андрей Мухин (Muhin555) 26.03.11 00:48
А нет ли примерчика, где бы обрабатывались Checkbox-ы в теле HTML документа и значения их передавались бы в 1С????
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа