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

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С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

21.05.2024    20124    dimanich70    81    

144

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

1 стартмани

18.03.2024    4091    3    John_d    11    

57

Универсальные функции Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

12.02.2024    18059    atdonya    24    

56

Универсальные функции Программист Платформа 1С v8.3 Бесплатно (free)

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

30.11.2023    5502    ke.92@mail.ru    16    

65

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    14730    YA_418728146    7    

166

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

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3580    56    progmaster    8    

4

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    18478    171    sapervodichka    112    

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

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

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

ЗЫ: получить ссылку ещё можно выделив её и вызвав диалог вставки сей ссылки - откроется существующая.
2. serg33rus 32 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.
Оставьте свое сообщение