Обрезание длинных описаний товаров. УНФ 3.0 + Шаблоны.doc

У клиента возникла проблема — дополнительные реквизиты описания обрезались, выводилось только 1024 символа.

Я решил обойти проблему алгоритмом:

Получилось только с пятой попытки. Если интересен результат, переходите сразу на раздел «Попытка 5», пропустив мои подходы к решению задачи.

Попытка 1. Прямое получение реквизита объекта

Сначала я попробовал так:

Результат = дор_Сервер.ДатьЗначениеДопРеквизита(Объект, "ОписаниеEng");

Но объектом был заказ, а не поле. Код тоже не давал понимания, где мы находимся:

Я хотел доработать код, чтобы помещать в кэш текущую строку, но потом заметил, что при наличии библиотеки и использовании алгоритма из нее можно в качестве объекта брать не объект, а поле — «ПрименитьАлгоритмКУказанномуПолю«.

Попытка 2. Почти получилось

Создал библиотеку Доработки в добавок к имеющейся Стандартные:

Написал алгоритм:

// Параметры через точку с запятой: Язык=Eng
ПараметрыАлгоритма = Обработки.Word_ФункцииСтандартнойБиблиотеки.ПолучитьСоответствиеПараметров(ПараметрАлгоритма);
ИдентификаторПоля = "Описание" + ПараметрыАлгоритма.Получить("Язык");
Сообщить("Объект: " + Объект);
ИскСсылка = Справочник.Номенклатура.НайтиПоКоду(Объект);
Результат = дор_Сервер.ДатьЗначениеДопРеквизита(ИскСсылка, "ОписаниеEng");

Но увы, галочка «Применить алгоритм к указанному полю» опять выбирает всего лишь поле шапки:

В отладчике я увидел Null вместо значения поля в переменной Объект.

Попытка 3. С доработкой кода Шаблоны.DOC

Поэтому все же пришлось доработать код и добавить в кэш текущую строку таблицы в процедуру ПолучитьТаблицуДанных модуля Word_ФормированиеДокументовСервер:

Я обратил внимание, что в заголовке таблицы находятся названия полей:

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

Решил воспользоваться библиотекой, добавил алгоритм с двумя параметрами:

Я не смог добавить закладку со значением кода вручную, для этого надо делать экспорт из Word-документа. Решил поручить это пользователю.

Поэтому написал тестовый код, где подставлял код товара, но при этом у меня выдалось все равно обрезанное значение:

// Параметры через точку с запятой: Язык=Eng;ПолеКода=RFQ_Table_IntRef
// ПолеКода - поле в котором содержится код товара

ПараметрыАлгоритма = Обработки.Word_ФункцииСтандартнойБиблиотеки.ПолучитьСоответствиеПараметров(ПараметрАлгоритма);
ПолеКода = ПараметрыАлгоритма.Получить("ПолеКода");
ИдентификаторРеквизита = "Описание" + ПараметрыАлгоритма.Получить("Язык");

СтрокаТЗ = кэш["СтрокаТЗ"];
ТЗ = СтрокаТЗ.Владелец();

Для Каждого Колонка Из ТЗ.Колонки Цикл
	//Сообщить(Колонка.Заголовок + " - "  + ПолеКода);
 	Если Колонка.Заголовок = ПолеКода Тогда
		Код = СтрокаТЗ[Колонка.Имя];
		Код = "00000027";
		ИскСсылка = Справочники.Номенклатура.НайтиПоКоду(Код);
		Сообщить(" Код для поиска: "  + Код);
		ИдентификаторПоля = "Описание" + ПараметрыАлгоритма.Получить("Язык");
		Сообщить("Номенклатура: " + ИскСсылка);
		Результат = дор_Сервер.ДатьЗначениеДопРеквизита(ИскСсылка, ИдентификаторРеквизита);	
	КонецЕсли;
КонецЦикла;

Тогда до меня дошло, что значение реквизита берется в ПВХ через поле «Значение«.

Пришлось доработать функцию получения реквизита, чтобы извлекалось текстовое значение реквизита, а не его значение:


Функция  ДатьЗначениеДопРеквизита(Ссылка, ИдентификаторРеквизита, Свойство = "Значение") Экспорт  
	//Свойство - может быть ТекстоваяСтрока
	//Ссылка - ссылка или объект
    ДопРеквизитСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("ИдентификаторДляФормул", ИдентификаторРеквизита);
    Если Не ЗначениеЗаполнено(ДопРеквизитСсылка) Тогда
        Возврат Неопределено;
    КонецЕсли;

    ИскСтрока = Ссылка.ДополнительныеРеквизиты.Найти(ДопРеквизитСсылка, "Свойство");
    Если ИскСтрока = Неопределено Тогда
        Возврат Неопределено;
    КонецЕсли;
    Возврат ИскСтрока[Свойство];
КонецФункции  

В окончательном виде код выглядел так:

// Параметры через точку с запятой: Язык=Eng;ПолеКода=RFQ_Table_IntRef
// ПолеКода - поле в котором содержится код товара

ПараметрыАлгоритма = Обработки.Word_ФункцииСтандартнойБиблиотеки.ПолучитьСоответствиеПараметров(ПараметрАлгоритма);
ПолеКода = ПараметрыАлгоритма.Получить("ПолеКода");
ИдентификаторРеквизита = "Описание" + ПараметрыАлгоритма.Получить("Язык");

СтрокаТЗ = кэш["СтрокаТЗ"];
ТЗ = СтрокаТЗ.Владелец();

Для Каждого Колонка Из ТЗ.Колонки Цикл
	//Сообщить(Колонка.Заголовок + " - "  + ПолеКода);
 	Если Колонка.Заголовок = ПолеКода Тогда
		Код = СтрокаТЗ[Колонка.Имя];
		Код = "00000027";
		ИскСсылка = Справочники.Номенклатура.НайтиПоКоду(Код);
		Сообщить(" Код для поиска: "  + Код);
		ИдентификаторПоля = "Описание" + ПараметрыАлгоритма.Получить("Язык");
		Сообщить("Номенклатура: " + ИскСсылка);
		Результат = дор_Сервер.ДатьЗначениеДопРеквизита(ИскСсылка, ИдентификаторРеквизита, "ТекстоваяСтрока");	
	КонецЕсли;
КонецЦикла;

Пришлось сделать очень много прогонов!

Попытка 4. Рабочее решение без изменения кода

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

Все-таки начальный путь был правильный, просто я использовал ошибочно материалы вместо номенклатура.

В итоге я сделал такое правило:

И такой алгоритм:

// Параметры через точку с запятой: Язык=Eng

ПараметрыАлгоритма = Обработки.Word_ФункцииСтандартнойБиблиотеки.ПолучитьСоответствиеПараметров(ПараметрАлгоритма);
ИдентификаторРеквизита = "Описание" + ПараметрыАлгоритма.Получить("Язык");

ИскСсылка = Справочники.Номенклатура.НайтиПоКоду(Объект);
ИдентификаторПоля = "Описание" + ПараметрыАлгоритма.Получить("Язык");
Результат = дор_Сервер.ДатьЗначениеДопРеквизита(ИскСсылка, ИдентификаторРеквизита, "ТекстоваяСтрока");	

И все заработало без изменения кода обработки и дополнительных закладок!

Но подумав, я усовершенствовал алгоритм еще больше.

Попытка 5. Окончательное решение проблемы

И такой алгоритм:

// Параметры через точку с запятой: Язык=Eng

ПараметрыАлгоритма = Обработки.Word_ФункцииСтандартнойБиблиотеки.ПолучитьСоответствиеПараметров(ПараметрАлгоритма);
ИдентификаторРеквизита = "Описание" + ПараметрыАлгоритма.Получить("Язык");

ИдентификаторПоля = "Описание" + ПараметрыАлгоритма.Получить("Язык");
Результат = дор_Сервер.ДатьЗначениеДопРеквизита(Объект, ИдентификаторРеквизита, "ТекстоваяСтрока");	

Пожелания к разработчикам Шаблоны.DOC

В связи с этим опытом у меня есть пожелание к разработчикам:

  1. Добавить галочку, чтобы использовать не значение доп. реквизита, а его текстовую строку.
  2. Добавить возможность алгоритмического заполнения табличных частей с возможностью понимания в какой строке какой табличной части находится алгоритм. Потому что алгоритм над одним полем строки еще можно как-то обыграть, а если нужно обрабатывать несколько полей из строки, не получится.
  3. Добавить возможность добавления закладок вручную, без загрузки из Word.

Среда: УНФ 3.0.4.88, ШаблоныDoc: 2.0.0.0. Объем: 3 час.

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

комментария 2

  1. rzd:

    Название метода ДатьЗначениеДопРеквизита посмешило

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *