World 1C

Блог для программистов и пользователей платформы 1С:Предприятие

Дополнительная вычисляемая колонка в табличной части

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

Реализация на платформе 1С: Предприятие 8.1

В начале коротко о том, как добавить дополнительную колонку в табличное поле на платформе 1С 8.1. Предположим, что у нас есть некий документ с табличной частью “Товары” (с колонками “Номенклатура” и “Количество”) и нам нужно вывести дополнительную колонку “Цена”, которая бы содержала данные реквизита “Цена” элементов справочника “Номенклатура”, выбранных в строках табличной части. Для этого нам достаточно добавить в форме документа новую колонку “Цена” в табличное поле, содержащее данные табличной части документа и написать следующий код в обработчике события “ПриПолученииДанных” этого табличного поля:

// обработчик события "ПриПолученииДанных" табличного поля "Товары"
Процедура ТоварыПриПолученииДанных(Элемент, ОформленияСтрок)
	Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
		Номенклатура = ОформлениеСтроки.ДанныеСтроки.Номенклатура;
		Если ЗначениеЗаполнено(Номенклатура) Тогда
			ОформлениеСтроки.Ячейки.Цена.ОтображатьТекст = Истина;
			ОформлениеСтроки.Ячейки.Цена.Текст = Формат(Номенклатура.Цена,"ЧЦ=15; ЧДЦ=2");
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

Хочу обратить внимание на то, что строки табличного поля обрабатываются порциями, по мере прокрутки списка.

Реализация на платформе 1С: Предприятие 8.2

На платформе 8.2 с использованием управляемых форм решение данной задачи потребует бóльших усилий. Это связано с тем, что за счет своей клиент-серверной ориентированности в платформе 8.2 в управляемом режиме отсутствуют некоторые привычные возможности – например, у табличного поля отсутствуют обработчики событий “ПриПолученииДанных” и “ПриВыводеСтроки”, которые мы могли бы использовать для этих целей в 1С 8.1 или 8.2 в обычных формах.
Пусть в нашей конфигурации есть документ “ВводОстатковДолга” с табличной частью “Контрагенты” (с колонками “Контрагент” и “Сумма”). В свою очередь у справочника “Контрагенты” есть реквизит “ИНН”, значение которого необходимо выводить в строках табличного поля.
Откроем управляемую форму документа, добавим новую колонку “ИНН” реквизита “Контрагенты” и перенесём её на закладку “Элементы” (для отображения в форме).
Добавление колонки ИНН
Откроем палитру свойств поля “КонтрагентыКонтрагент” и добавим обработчик события “ПриИзменении”

// служебная функция получения значения реквизита объекта (выполняется на сервере)
&НаСервере
Функция ЗначениеРеквизита(Объект,ИмяРеквизита);
	Возврат Объект[ИмяРеквизита];
КонецФункции

// обработчик события "ПриИзменении" поля "Контрагент" в табличном поле "Контрагенты"
&НаКлиенте
Процедура КонтрагентыКонтрагентПриИзменении(Элемент)
	ТекДанные = Элементы.Контрагенты.ТекущиеДанные;
	ТекДанные.ИНН = ЗначениеРеквизита(ТекДанные.Контрагент,"ИНН");
КонецПроцедуры

Это обеспечит нам изменение значения поля “ИНН” при выборе контрагента в строке табличного поля.
Теперь необходимо предусмотреть заполнение колонки “ИНН” при открытии формы документа, а так же после записи и при чтении на сервере. Обновление данных после записи и при чтении на сервере необходимо в связи с тем, что иначе значения колонки “ИНН” будут очищаться каждый раз при возникновении этих событий. Для заполнения колонки “ИНН” опишем в модуле формы служебную серверную процедуру

// служебная процедура для заполнения колонки "ИНН" табличного поля "Контрагенты"
&НаСервере
Процедура ОбновитьДанныеКолонкиИНН()
	Запрос = Новый Запрос(
	"ВЫБРАТЬ РАЗРЕШЕННЫЕ
	|	Контрагенты.Ссылка КАК Контрагент,
	|	Контрагенты.ИНН
	|ИЗ
	|	Справочник.Контрагенты КАК Контрагенты
	|ГДЕ
	|	Контрагенты.Ссылка В(&СписокКонтрагентов)"
	);
	Запрос.УстановитьПараметр("СписокКонтрагентов",Объект.Контрагенты.Выгрузить().ВыгрузитьКолонку("Контрагент"));
	Выборка = Запрос.Выполнить().Выбрать();
	Для Каждого Стр Из Объект.Контрагенты Цикл
		Если Выборка.НайтиСледующий(Стр.Контрагент,"Контрагент") Тогда
			Стр.ИНН = Выборка.ИНН;
		Иначе
			Стр.ИНН = "";
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

Затем добавим в модуль формы документа обработчики событий “ПриОткрытии”, “ПриЧтенииНаСервере” и “ПослеЗаписиНаСервере”, в каждой из которых будем вызвать описанную ранее служебную процедуру “ОбновитьДанныеКолонкиИНН”

&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
	ОбновитьДанныеКолонкиИНН();
КонецПроцедуры

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
	ОбновитьДанныеКолонкиИНН();
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	ОбновитьДанныеКолонкиИНН();
КонецПроцедуры

Всё готово. Можно посмотреть на результат.

Форма документа "Ввод остатков долга"
Скачать пример

Поделиться
  • Twitter
  • Добавить ВКонтакте заметку об этой странице
  • Facebook
  • Одноклассники
  • LiveJournal
  • Мой Мир
  • В закладки Google
  • FriendFeed
  • Блог Я.ру

,

12 комментария(ев) к “Дополнительная вычисляемая колонка в табличной части
  • [...] из моих предыдущих статей (например, из статьи Дополнительная вычисляемая колонка в табличной части). Добавим новый план видов характеристик “Виды [...]

  • Павел:

    Описанные Вами вариант возможно использовать без добавления дополнительных процедур, просто сделав “Откроем управляемую форму документа, добавим новую колонку “ИНН” реквизита “Контрагенты” и перенесём её на закладку “Элементы” (для отображения в форме).”. По крайней мере, на платформе, начиная с 8.2.17.

    Лучше бы описали ситуации, когда необходимо поле, которое вообще невозможно взять из объектов, т.е. например у нас есть колонка Документ, но ее тип составной из двух документов, у каждого документа есть реквизит “ДатаВходящегоДокумента”, и его надо также вывести в табличную форму, но описанный Вами метод этого не поможет сделать. Вот меня интересует как

    • admin:

      Вы правы. В последних версиях платформы действительно есть возможность вывода реквизитов полей табличной части в отдельных колонках табличного поля. До некоторых пор такой возможности в управляемых формах платформы 8.2 скорее всего не было (иначе, я вряд ли стал писать данную статью). Однако, и сейчас не всё так просто. Как Вы правильно заметили, для реквизитов составного типа без дополнительных усилий это сделать нельзя. И вот тут описанный метод как раз таки и будет полезен. Он работает, я только что это проверил. Кроме того без такого приёма не обойтись и в том случае, если нужно выводить данные не из реквизитов, а из других, связанных объектов, например, из регистров.

      • Михаил:

        Это всё замечательно, но как обновлять вычисляемые поля, если их добавлять не интерактивно, а программно? Не нашёл возможности программной установки флага “Использовать всегда”, поэтому не могу их увидеть на стороне сервера.

  • Олег Ковалев:

    Спасибо. Помогло.

  • Юлия:

    Спасибо. Статья очень помогла

  • Евгений:

    Спасибо, но тут еще вариант по лучше
    http://v8.1c.ru/metod/faq2/answer.jsp?id=540
    http://www.cyberforum.ru/1c/thread877075.html
    почитал все стало все понятно.

  • HystriX:

    Вызов процедуры некорректно размещен в событиях формы.

    Во-первых, при открытии формы существующего объекта получение данных выполнится дважды – в событии “ПриЧтенииНаСервере”, а затем в событии “ПриОткрытии”.

    Во-вторых, событие “ПриОткрытии” является клиентским, в корне неправильно делать лишний серверный вызов в этом событии.

    Правильным вариантом является подход используемый в типовых конфигурациях:

    - В событии “ПриСозданииНаСервере” чтение дополнительных реквизитов должно выполняться только для новых объектов, то есть должно проверяться условие “Если Не ЗначениеЗаполнено(Объект.Ссылка)”.
    - В событии “ПриЧтенииНаСервере” чтение дополнительных реквизитов должно выполняться всегда, это событие вызывается только для существующих объектов.

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

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>