Вставка гиперссылки в форматированный документ

03.06.19

Разработка - Универсальные функции

Да, форматированный документ это умеет и сам, но возможности можно расширить!

Поводом стала вот эта тема: //infostart.ru/public/74958/
Поскольку мне пришлось немного повозиться с форматированным документом в ходе текущих работ, накидал вариант решения проблемы.

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

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

Вот полный текст механизма:

// вспомогательная к ВставитьСсылкуВВыделениеФорматированногоДокумента
&НаКлиентеНаСервереБезКонтекста
Процедура СоздатьЭлементПозиции(ФДокумент, рЗакладкаВставки, рДанныеЭлемента)
	рЭлемент=ФДокумент.Вставить(рЗакладкаВставки,рДанныеЭлемента.Текст,рДанныеЭлемента.Элемент.ТипЭлемента);
	ЗаполнитьЗначенияСвойств(рЭлемент,рДанныеЭлемента.Элемент);
	рЭлемент.НавигационнаяСсылка=?(рДанныеЭлемента.Свойство("Ссылка"),рДанныеЭлемента.Ссылка,"");
	рЭлемент.Текст=рДанныеЭлемента.Текст;
КонецПроцедуры	

&НаКлиентеНаСервереБезКонтекста
Функция ВставитьСсылкуВВыделениеФорматированногоДокумента(ФДокумент, рВыделенныйТекст, рСсылка)
Попытка
	рОбласть=ФДокумент.НайтиТекст(рВыделенныйТекст); // ищем везде
	Если рОбласть=Неопределено Тогда
		Возврат "Вставка ссылки невозможна, не определена область выделенного текста!";
	КонецЕсли;
	мЭлементов=ФДокумент.ПолучитьЭлементы(рОбласть.ЗакладкаНачала,рОбласть.ЗакладкаКонца);
	Если мЭлементов.Количество()=0 Тогда 
		Возврат "Вставка ссылки невозможна, не определён выделенный текст!";
	КонецЕсли;
	//
	// проверим, чтобы там уже не было ссылок
	Для каждого рЭлемент Из мЭлементов Цикл
		Если ТипЗнч(рЭлемент)<>Тип("ТекстФорматированногоДокумента") Тогда
			Возврат "Выделенный фрагмент захватывает не только текстовые фрагменты, вставка ссылки невозможна!";
		КонецЕсли;		
		Если Не ПустаяСтрока(рЭлемент.НавигационнаяСсылка) Тогда
			Возврат "В выделенном фрагменте уже фигурирует ссылка, необходимо сначала её убрать!";
		КонецЕсли;
	КонецЦикла;
	
	// конструируем последовательность новых элементов по их позициям согласно выделенной области
	рВесьТекст=ФДокумент.ПолучитьТекст();
	позиНачВыделения=СтрНайти(рВесьТекст,рВыделенныйТекст); // нумерация с 0!
	позиКонВыделения=позиНачВыделения+СтрДлина(рВыделенныйТекст)-1;
	//
	мНовыхЭлементов=Новый Массив;
	позиНачРаб=позиНачВыделения; // позиционирование элементов ФТ идёт встык, без +1
	позиНачЧтен=позиНачВыделения;
	рПозицияВставки=ФДокумент.ПолучитьПозициюПоЗакладке(мЭлементов[0].ЗакладкаНачала);
	//
	Для каждого рЭлемент Из мЭлементов Цикл
		позиНачЭлемента=ФДокумент.ПолучитьПозициюПоЗакладке(рЭлемент.ЗакладкаНачала);
		позиКонЭлемента=ФДокумент.ПолучитьПозициюПоЗакладке(рЭлемент.ЗакладкаКонца);
		//
		// на будущее, доработать, если кому понадобится, в т.ч. сопоставление ссылок картинкам
		рТипЭлемента=ТипЗнч(рЭлемент);
		//Если рТипЭлемента=Тип("ТекстФорматированногоДокумента") Тогда
			рСвойстваЭлемента=Новый Структура("ЦветТекста,ЦветФона,Шрифт,Текст");
		//ИначеЕсли рТипЭлемента=Тип("ПараграфФорматированногоДокумента") Тогда
		//	рСвойстваЭлемента=Новый Структура("ГоризонтальноеПоложение,МеждустрочныйИнтервал,Отступ,ТипПараграфа");
		//ИначеЕсли рТипЭлемента=Тип("КартинкаФорматированногоДокумента") Тогда
		//	рСвойстваЭлемента=Новый Структура("Ширина,Высота,Картинка");
		//КонецЕсли;
		//
		ЗаполнитьЗначенияСвойств(рСвойстваЭлемента,рЭлемент);
		рСвойстваЭлемента.Вставить("ТипЭлемента",рТипЭлемента);
		//
		Если позиНачЭлемента<позиНачРаб Тогда
			Если позиКонЭлемента>позиКонВыделения Тогда
				мНовыхЭлементов.Добавить(Новый Структура("Начало,Конец,Элемент",позиНачЭлемента,позиНачВыделения-1,рСвойстваЭлемента));
				мНовыхЭлементов.Добавить(Новый Структура("Начало,Конец,Элемент,Ссылка",позиНачВыделения,позиКонВыделения,рСвойстваЭлемента,рСсылка));
				мНовыхЭлементов.Добавить(Новый Структура("Начало,Конец,Элемент",позиКонВыделения,позиКонЭлемента,рСвойстваЭлемента));
				Прервать; // вся выделенная область целиком поместилась в один элемент
			Иначе
				мНовыхЭлементов.Добавить(Новый Структура("Начало,Конец,Элемент",позиНачЭлемента,позиНачЧтен-1,рСвойстваЭлемента));
				мНовыхЭлементов.Добавить(Новый Структура("Начало,Конец,Элемент,Ссылка",позиНачЧтен,позиКонЭлемента,рСвойстваЭлемента,рСсылка));
				позиНачРаб=позиКонЭлемента; // именно так, без +1
				позиНачЧтен=позиКонЭлемента+1;
			КонецЕсли;
		ИначеЕсли позиНачЭлемента=позиНачРаб Тогда
			Если позиКонЭлемента>позиКонВыделения Тогда
				мНовыхЭлементов.Добавить(Новый Структура("Начало,Конец,Элемент,Ссылка",позиНачЧтен,позиКонВыделения,рСвойстваЭлемента,рСсылка));
				мНовыхЭлементов.Добавить(Новый Структура("Начало,Конец,Элемент",позиКонВыделения+1,позиКонЭлемента,рСвойстваЭлемента));
				Прервать; // конечный хвостовой элемент, на котором закончилось выделение
			Иначе
				мНовыхЭлементов.Добавить(Новый Структура("Начало,Конец,Элемент,Ссылка",позиНачЧтен,позиКонЭлемента,рСвойстваЭлемента,рСсылка));
				позиНачРаб=позиКонЭлемента; // именно так, без +1
				позиНачЧтен=позиКонЭлемента+1;
			КонецЕсли;
		КонецЕсли;
		//
	КонецЦикла;
	
	// получаем тексты "кусочками"
	Для каждого знч Из мНовыхЭлементов Цикл
		знч.Вставить("Текст",Сред(рВесьТекст,знч.Начало,знч.Конец-знч.Начало+1));
	КонецЦикла;
	
	// удаляем все попавшие под обработку старые элементы
	Для й=-1*(мЭлементов.Количество()-1) По 0 Цикл
		рЭлемент=мЭлементов.Получить(-й);
		ФДокумент.Удалить(рЭлемент.ЗакладкаНачала,рЭлемент.ЗакладкаКонца);
	КонецЦикла;
	
	// создаём новые согласно указанным позициям и настройкам
	рЗакладкаВставки=ФДокумент.ПолучитьЗакладкуПоПозиции(рПозицияВставки);
	Для й=-1*(мНовыхЭлементов.Количество()-1) По 0 Цикл
		СоздатьЭлементПозиции(ФДокумент, рЗакладкаВставки, мНовыхЭлементов.Получить(-й));
	КонецЦикла;
	
	Возврат "";
Исключение
	Возврат "ВставитьСсылкуВВыделениеФорматированногоДокумента, общая ошибка: "+ОписаниеОшибки();
КонецПопытки;
КонецФункции

Вызывать это можно, например, так:

ВыдТекст=Элементы.ВашДокумент.ВыделенныйТекст;
ВашаСсылка="http://www.1c.ru";
Результат=ВставитьСсылкуВВыделениеФорматированногоДокумента(ВашДокумент,ВыдТекст,ВашаСсылка);
Если не ПустаяСтрока(Результат) Тогда
	ПоказатьПредупреждение(,рРезультат);
КонецЕсли;


Напомню, чтобы ФД не приписывал спереди e1c:// и прочую ересь, указывайте протокол, например, "http://", причём, если вы хотите использовать ФД в своих целях, туда можно напихать свои адресообразные данные, например какие-нибудь гуиды, главное, чтобы протокол был. Ну и, конечно, ловить щелчок лучше не в поле ФД, а закинув содержимое ФД в html-поле, и уж там по Click'у смотреть href.

Кстати ещё на заметку: форматирование ФД не совсем wisiwig применительно к html-полю, т.е. иногда прямо разительно отличается вид. Но писать xslt-преобразование и пытаться понять, что он каким образом показывает - это уже удовольствие отдельное.

Вступайте в нашу телеграмм-группу Инфостарт

ФорматированныйДокумент форматированный документ вставка ссылки ссылок

См. также

Универсальные функции Работа с интерфейсом Программист 1С:Предприятие 8 Бесплатно (free)

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

14.05.2025    5403    DeerCven    15    

57

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

21.05.2024    46302    dimanich70    83    

164

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    6841    6    John_d    13    

59

Универсальные функции Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    57351    atdonya    31    

68

Универсальные функции Программист 1С:Предприятие 8 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    8608    ke.92@mail.ru    17    

68

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

28.08.2023    22759    YA_418728146    8    

174
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. triviumfan 102 11.12.20 15:52 Сейчас в теме

Напомню, чтобы ФД не приписывал спереди e1c:// и прочую ересь, указывайте протокол, например, "http://", причём, если вы хотите использовать ФД в своих целях, туда можно напихать свои адресообразные данные, например какие-нибудь гуиды, главное, чтобы протокол был. Ну и, конечно, ловить щелчок лучше не в поле ФД, а закинув содержимое ФД в html-поле, и уж там по Click'у смотреть href.

У меня стоит протокол, ловить щелчок в поле форматированного документ невозможно, оно имеет лишь 1 обработчик - ПриИзменении().
На лицо такая проблема - пользователь делает клик по ссылке, но ничего не происходит)
Ссылка верна, протокол указан. Как это обрабатывать - не понятно (т.е. понятно, что нужно html-поле, но зачем тогда вообще это недоразумение в виде ФД).
Не зря все хаят этот недообъект "форматированный документ".

ЗЫ: получить ссылку ещё можно выделив её и вызвав диалог вставки сей ссылки - откроется существующая.
2. serg33rus 35 07.02.21 16:00 Сейчас в теме
(1) Ссылки срабатываю в ФД только если у ФД стоит ТолькоЧтение. Тоже на это стукался. Неприятно, приходится для редактирования вводить кнопочку, чтобы переключить ТолькоЧтение в Ложь.
3. andryandry 100 15.05.22 12:04 Сейчас в теме
(1) в режиме редактирования ссылка открывается если при клике удерживать Ctrl
4. MaCCapAkIII 27.10.22 16:12 Сейчас в теме
Подскажите пожалуйста правильно ли я понимаю, что ограничение на 255 символов вводимой гиперссылки стандартными средствами платформы никак не изменить и надо писать свой обработчик со своей формой ввода? Столкнулся со стандартной командой форматированного документа и необходимо добавлять очень длинные гиперссылки. Соответственно ни отладить, ни поменять алгоритм работы стандартной команды возможности нет. 8.3.20.1789.
Для отправки сообщения требуется регистрация/авторизация