Обрезание длинных описаний товаров. УНФ 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
В связи с этим опытом у меня есть пожелание к разработчикам:
- Добавить галочку, чтобы использовать не значение доп. реквизита, а его текстовую строку.
- Добавить возможность алгоритмического заполнения табличных частей с возможностью понимания в какой строке какой табличной части находится алгоритм. Потому что алгоритм над одним полем строки еще можно как-то обыграть, а если нужно обрабатывать несколько полей из строки, не получится.
- Добавить возможность добавления закладок вручную, без загрузки из Word.
Среда: УНФ 3.0.4.88, ШаблоныDoc: 2.0.0.0. Объем: 3 час.
Название метода ДатьЗначениеДопРеквизита посмешило
ну тут уж на вкус и цвет.