1с 8 управляемые формы заполнение табличных частей. Как программно заполнить реквизиты строки табличной части

И снова здравствуйте.

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

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

Для примера возьмем простую задачку:

имеем конфигурацию 1С Бухгалтерия предприятия в редакции 3.0
в ней есть документ ВедомостьНаВыплатуЗарплатыВКассу
Этот документ умеет заполняться всем, что начисленно сотрудникам с отбором по выбранному подразделению, однако при выплате аванса начислений еще пока нет и заполнять его приходится вручную. Однако в базе есть место для хранения плановых начислений и вполне можно организовать заполнение документа процентом от оклада. Конечно, тут нет табеля чтобы проанализировать долю отработанного времени, но зарплату в 1С Бухгалтерия ведут только маленькие конторы и скорректировать потом две строчки из даже пятидесяти - не проблема.

Задача ясна, в документе будет команда заполнения, по которой будет открыт диалог ввода процента, после чего документ заполнится.

Приступим!

Создадим новую обработку и зададим ей имя. В поле форма обработки жмакнем "линзу", тем самым создадим форму.

Теперь временно покинем форму и перейдем в модуль обработки. Напишем в нем функцию ПолучитьТаблицуКоманд() и процедуру ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = ""). Их текст Вы найдете в предыдущей статье.

Теперь пишем экспортную функцию СведенияОВнешнейОбработке(). Вот её текст:

Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
МассивНазначений = Новый Массив;
МассивНазначений.Добавить("Документ.ВедомостьНаВыплатуЗарплатыВКассу");
ПараметрыРегистрации.Вставить("Вид","ЗаполнениеОбъекта");
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
ПараметрыРегистрации.Вставить("Версия", "1.0");
ПараметрыРегистрации.Вставить("Наименование", "Заполнить Аванс "+ПараметрыРегистрации.Версия);
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
ПараметрыРегистрации.Вставить("Информация", "Дополнительная обработка табличной части к документу ВедомостьНаВыплатуЗарплатыВКассу");
ТаблицаКоманд = ПолучитьТаблицуКоманд();
ДобавитьКоманду(ТаблицаКоманд,

"Заполнить Аванс "+ПараметрыРегистрации.Версия,
"ОткрытиеФормы", Истина);
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции

В качестве "назначения" зададим документ "ВедомостьНаВыплатуЗарплатыВКассу". Вид обработки " ЗаполнениеОбъекта". Использование - " ОткрытиеФормы". Безопасный режим нам не нужен.

Отличий от печатной формы - минимум. Теперь возвращаемся в форму.

В теории в параметрах формы будут переданы объекты, которые надо заполнить. Получить их можно обратившись к свойству "ОбъектыНазначения". Еще в теории их может быть много, т.к. команда заполнения появится не только в форме документа, но и в форме списка, а там доступен множественный выбор. Еще в качестве владельца формы выступает окно, в котором нажата кнопка "заполнить". Это может быть как форма документа, так и форма списка.

Это теория, на практике заказчику не нужно заполнять три ведомости на аванс сразу:)) поэтому в нашем примере из формы списка наша обработка будет падать с ошибкой. Я не призываю Вас так делать, просто в статье главное донести суть, а заказчику главное результат.

Так вот, условились, что ведомость всегда одна и кнопку жмем в документе, а не в списке. Случай жмаканья из списка допилите сами))

В форме нам понадобятся реквизиты: "ведомость" и "процент"

Так же нам нужна команда "Заполнить". Тащим реквизит "процент" и команду "заполнить" на форму.

У формы добавляем обработчик "ПрисозданииНаСервере" и пишем туда получение объекта для заполнения.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("ОбъектыНазначения") тогда
Ведомость = Параметры.ОбъектыНазначения;
КонецЕсли;
КонецПроцедуры

Собственно вот тут Вам флаг в руки и анализируйте количество переданных объектов)) если хотите, конечно.

В обработчике "ПриСозданииНаСервере" мы имеем массив ссылок. Еще мы имеем гарантию, что перед заполнением объект записали. Если документ модифицирован, то нам предложат его записать перед заполнением или отказаться от заполнения. Мне это не нравится, т.к. каждое перезаполнение требует записи, а если нам не надо записывать? Хорошее заполнение должно работать с данными формы, а не с данными записанного объекта. но чтобы отменить контроль модифицированности надо снимать конфу с поддержки и комментировать эту проверку. Из-за всей этой неурядицы мы стоим на распутье, мы можем модифицировать объект в БД и потом обновить форму (перечитать в ней данные), а можем модифицировать данные формы, которая у нас в нашем контектсе является владельцем формы обработки.

Наверное правильно будет делать так:

при создании на сервере формы обработки анализировать, откуда запущена обработка: из списка или из формы документа. Если из списка, то работаем с БД, если из формы документа, то работаем с владельцем формы обработки.

В первом варианте (при работе с объектом в БД) нам придется его записать после выполнения, что не всегда приемлемо. Это не позволяет нам посмотрев результат заполнения отказаться от него. Но в форме списка других вариантов нет.

Вообще анализ источника запуска команды заставляет нас писать две разных процедуры заполнения, т.к. одна на сервере другая на клиенте.

Но, как я уже говорил, я забил на вариант открытия из формы списка, поэтому я работаю с данными формы. Из этого вытекает, что реквизит формы "ведомость" и обработчик "приСозданииНаСервере" я писал зря)))

Вот собственно процедура заполнения:

&НаКлиенте

Процедура Заполнить(Команда)
м = ПолучитьДанные(ВладелецФормы.Объект.ПериодРегистрации);
ВладелецФормы.Объект.Зарплата.Очистить();
ВладелецФормы.Объект.СпособВыплаты = СпособВыплаты();
Для Каждого строкаДанных Из м Цикл
стрДокумента = ВладелецФормы.Объект.Зарплата.Добавить();
стрДокумента.Сотрудник = строкаДанных.Сотрудник;
стрДокумента.Подразделение = строкаДанных.Подразделение;
стрДокумента.КВыплате = строкаДанных.Размер / 100 * Процент;
КонецЦикла;
ЭтаФорма.Закрыть();
КонецПроцедуры

В первой же строке - вся соль этой статьи. К данным формы мы обращаемся через конструкцию ВладелецФормы.Объект. Из неё мы обращаемся к табличной части и к шапке, читаем и пишем.

Процедура "ПолучитьДанные()" - выполняется на сервере и собирает по плановым начислениям суммы к заполнению. Т.к. таблицы значений передавать с сервера на клиент нельзя, я использую массив структур.

Вот текст процедуры собирающей данные:

&НаСервере
Функция ПолучитьДанные(Период)
Запрос = Новый Запрос("ВЫБРАТЬ
|ПлановыеНачисленияСрезПоследних.Сотрудник,
|ПлановыеНачисленияСрезПоследних.ФизическоеЛицо,
|КадроваяИсторияСотрудниковСрезПоследних.Подразделение,
|ПлановыеНачисленияСрезПоследних.Размер
|ИЗ
|РегистрСведений.ПлановыеНачисления.СрезПоследних(&Период,) КАК ПлановыеНачисленияСрезПоследних
|ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних КАК КадроваяИсторияСотрудниковСрезПоследних
|ПО ПлановыеНачисленияСрезПоследних.Сотрудник = КадроваяИсторияСотрудниковСрезПоследних.Сотрудник
|ГДЕ
|КадроваяИсторияСотрудниковСрезПоследних.ВидСобытия <> ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.Увольнение)
|
|УПОРЯДОЧИТЬ ПО
|ПлановыеНачисленияСрезПоследних.ФизическоеЛицо.Наименование");
Запрос.УстановитьПараметр("Период", Период);
рез = Запрос.Выполнить();
м = Новый Массив;
выб = рез.Выбрать();

Пока выб.Следующий() Цикл
структураДанных = Новый Структура("Сотрудник,ФизическоеЛицо,Подразделение,Размер");
ЗаполнитьЗначенияСвойств(структураДанных, выб);
м.Добавить(структураДанных);
КонецЦикла;
Возврат м;
КонецФункции

Тут должно быть все понятно, единственным НОУХАУ является способ передачи результатов выполнения запроса с сервера на клиент. Запрос тут простой, т.к. в отличии от ЗУП в Бухии нет даты окончания в регистрах, это упрощает задачу получения данных.

Помим табличной части я еще заполняю реквизит "СпособВыплаты",а получать его тоже приходится на сервере:

&НаСервере
Функция СпособВыплаты()
Возврат Справочники.СпособыВыплатыЗарплаты.НайтиПоНаименованию("Аванс");
КонецФункции

Вот и все.

Теперь резюме:

1. Если ваша конфигурация снята с поддержки, то отключите проверку записанности объекта перед вызовом обработки заполнения.

2. Не меняйте объект БД, если можете изменить данные формы. Пока пользователь не нажал записать, его действия должны иметь возможность быть отмененными.

3. Если есть время и силы, пишите обработку для обоих случаев: вызова из формы списка и из формы объекта. Для формы объекта модифицируйте данные формы, для формы списка модифицируйте данные БД. В моем случае из формы списка команда падает с ошибкой, это не правильно.

Все спасибо, пока!

Табличные части существуют у многих объектов в 1С:

  • Справочники
  • Документы
  • Отчеты и обработки
  • Планы счетов
  • Планы видов характеристик
  • Планы видов расчета
  • Бизнес-процессы и задачи

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

Рассмотрим некоторые приемы работы с табличными частями.

Как обойти табличную часть

Для обхода табличной части можно использовать цикл Для каждого

Для каждого Строка из ТабличнаяЧасть Цикл

Сообщить(Строка. РеквизитТабличнойЧасти) ;

КонецЦикла ;

На каждой итерации в переменную Строка передается очередная строка табличной части. Значения реквизитов строки можно получить выражением Строка.ИмяРеквизита .

Как получить и обойти выделенные строки табличной части

Для вывода информации из табличной части объекта служит элемент формы Табличное поле . Для включения возможности выделения нескольких строк на табличном поле нужно установить значение Множественный у его свойства Режим выделения .

Для получения перечня выделенных строк используется следующий код:

Для того чтобы обойти выделенные строки используется цикл Для каждого :

ВыделенныеСтроки= ЭлементыФормы. ИмяТабличногоПоля. ВыделенныеСтроки;

Для каждого Строка из ВыделенныеСтроки Цикл

//содержимое цикла

КонецЦикла ;

Как программно выделить строки табличной части (табличного поля) и снять выделение

Чтобы программно снять выделение строк табличного поля:

ЭлементыФормы. ИмяТабличногоПоля. ВыделенныйСтроки. Очистить() ;

Чтобы программно выделить все строки табличного поля:

Для каждого ТекущаяСтрока Из ТабличнаяЧасть Цикл
ЭлементыФормы. ИмяТабличногоПоля. ВыделенныеСтроки. Добавить(ТекущаяСтрока) ;
КонецЦикла ;

Как очистить табличную часть

ТабличнаяЧасть. Очистить() ;

Как получить текущую строку табличной части

Текущая строка — это срока, в которой у пользователя в данный момент находится курсор. Чтобы ее получить, нужно обратиться к элементу управления на форме, который связан с табличной частью.

Для обычных форм код будет выглядеть так:

ЭлементыФормы. ИмяТабличногоПоля. ТекущиеДанные;

Для управляемых форм:

Элементы. ИмяТабличногоПоля. ТекущиеДанные;

Как добавить новую строку в табличную часть

Добавление новой строки в конец табличной части:

НоваяСтрока= ТабличнаяЧасть. Добавить() ;

Добавление новой строки в любое место табличной части (последующие строки будут сдвинуты):

НоваяСтрока= ТабличнаяЧасть. Вставить(Индекс)
//Индекс - номер добавляемой строки. Нумерация строк начинается с нуля.

НоваяСтрока. Реквизит1 = "Значение" ;

Как программно заполнить реквизиты строки табличной части

Если нужно программно заполнить реквизиты строки табличной части, которую добавляет пользователь, необходимо использовать обработчик события табличной части ПриНачалеРедактирования .

Создаваемая обработчиком процедура имеет три параметра:

  • Элемент — содержит элемент управления ТабличноеПоле .
  • НоваяСтрока — булево. Содержит значение Истина , если добавляется новая строка табличной части, и Ложь, если пользователь начал редактировать уже существующую строку.
  • Копирование — булево. Содержит значение Истина , если пользователь копирует строку, и Ложь в остальных случаях.

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

Процедура ТабличнаяЧастьПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)

//Если пользователь редактирует существующую строку, то ничего не делаем
Если НЕ НоваяСтрока Тогда
Возврат;
КонецЕсли ;

//Если же строка новая, устанавливаем счет учета
ТекСтрока = Элемент. ТекущиеДанные; //Получили текущую строку табличной части
ТекСтрока. СчетУчета = ПланыСчетов. Хозрасчетый. НужныйСчетУчета;
КонецПроцедуры

В этой статье рассмотрим процесс написания простейшей внешней обработки заполнения табличной части в 1С 8 для конфигураций, использующих обычное приложение. Для примера возьмем такую задачу: “В конфигурации 1С:Бухгалтерия 2.0 создать внешнюю обработку заполнения табличной части Товары документа Реализация товаров и услуг , данные для заполнения взять из табличной части Товары документаПоступление товаров и услуг ”. Таким образом нам необходимо заполнить товары реализации на основании товаров поступления, такая задача довольно часто встречается в реальной практике программиста 1С.

2. Создание внешней обработки

Зайдем в 1С 8 в режиме Конфигуратор . При помощи меню Файл -> Новый или пиктограммы Новый документ создадим новую внешнюю обработку .

В поле Имя укажем: “ПростейшееЗаполнениеТабличнойЧасти” и сохраним внешнюю обработку на жесткий диск используя меню Файл -> Сохранить или пиктограмму Сохранить или сочетание клавиш Ctrl + S .

Выделив ветку Реквизиты в дереве метаданных обработки и нажав кнопку Добавить (кнопка с зеленым плюсом) создадим новый реквизит внешней обработки - ДокументПоступления , выберем для него типДокументСсылка.ПоступлениеТоваровУслуг , этот реквизит нужен нам для выбора документа Поступление товаров и услуг , на основании которого будет заполняться реализация.

Для выбора документа поступления нам понадобится отдельная форма. Выделив ветку Формы и используя ту же кнопку - Добавить создадим форму внешней обработки. Откроется окно конструктора формы, на первой странице конструктора никаких изменений делать не нужно, поэтому просто нажмем кнопку Далее .

На второй странице конструктора нам необходимо выбрать реквизит ДокументПоступления (для того что бы он появился на создаваемой форме) и нажать кнопку Готово .

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

3. Программирование

Приступим к программированию обработки заполнения табличной части. Перейдем в Модуль объекта внешней обработки(на нижней панели обработки кнопка Действия -> Открыть модуль объекта ).

В нем нам необходимо создать экспортную процедуру Инициализировать .

Процедура Инициализировать Экспорт КонецПроцедуры

Обратите внимание, что процедура Инициализировать , а так же все ее параметры, являются обязательными для внешней обработки заполнения табличной части , если вы ее не создадите или не укажите все параметры, ваша обработка просто не будет работать.

Теперь приступим к написанию программного кода. В первую очередь создадим переменную для табличной части документа Реализация товаров и услуг , которую мы будем заполнять.

ТабличнаяЧасть = Объект[ИмяТабличнойЧасти];

При выполнении процедуры в параметре Объект будет содержаться объект документа, который мы заполняем, а в параметре ИмяТабличнойЧасти строка с именем табличной части, которую мы заполняем. Таким образом эта строчка кода получает табличную часть заполняемого документа по ее имени.

Нам необходимо что бы пользователь выбрал документ Поступление товаров и услуг , поэтому напишем код открытия формы выбора документа. Для начала получим эту форму в переменную, используя метод внешней обработки ПолучитьФорму(<Форма>, <Владелец>, <КлючУникальности>) . Нам достаточно заполнить только первый параметр этого метода, передав туда строку с именем нашей формы.

ФормаВыбораПоступления = ПолучитьФорму("Форма" );

Теперь откроем полученную форму, используя модальное открытие(пока форма открыта все остальные окна 1С недоступны), потому что при таком способе открытия дальнейший наш код в процедуреИнициализировать выполняться не будет, пока пользователь не закроет форму.

ФормаВыбораПоступления.ОткрытьМодально();

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

Если НЕ ЗначениеЗаполнено(ДокументПоступления) Тогда Сообщить (); Возврат ; КонецЕсли ;

Для проверки заполненности реквизита здесь используется функция глобального контекстаЗначениеЗаполнено(<Значение>) , она проверяет отличатся ли значение переданное в параметре от значения по умолчанию того же типа. Процедура Сообщить выводит указанный текст в окно сообщений 1С 8. Ключевое слово Возврат прерывает выполнение процедуры.

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

Запрос = Новый Запрос;

Запрос.УстановитьПараметр("ДокументПоступления" ,ДокументПоступления);

Напишем текст запроса, будем делать это при помощи Конструктора запроса . Писать текст запроса вручную не рекомендуется, это не эффективно и отнимает кучу времени. Для начала напишем строку:

Запрос.Текст = "" ;

Поставим курсор между символами кавычек, нажмем правую кнопку мыши и выберем пунк Конструктор запроса… . После этого появится предложение создать новый запрос, нажмем кнопку “ОК”. Откроется окно конструктора, в левой его части расположены все доступные таблицы базы данных, нам необходим документ ПоступлениеТоваровУслуг . Найдем его и раскроем при помощи символа “+”, выберем табличную часть Товары и перетащим ее во вторую часть экрана конструктора, которая называется Таблицы (Также переместить нужную таблицу можно при помощи кнопки “>”).

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

Так как нам нужны данные только одного документа поступления(который мы выбрали перед началом заполнения), то в на закладке “Условия” наложим условие на ссылку документа при помощи переданного нами параметра.

Создание текста запроса в конструкторе на этом завершено, нажмем кнопку “ОК”. В итоге у нас получился следующий текст запроса:

Запрос.Текст = "ВЫБРАТЬ |ИЗ |ГДЕ ;

Созданный запрос осталось только выполнить и выгрузить в переменную:

Результат = Запрос.Выполнить().Выгрузить();

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

ТабличнаяЧасть.Очистить();

При помощи цикла Для каждого обойдем таблицу значений с результатами запроса.

Для Каждого ЭлементРезультата из Результат Цикл КонецЦикла ;

В этом цикле создадим и заполним строки табличной части документа Реализация товаров и услуг . Создать новую строку мы можем при помощи переменной ТабличнаяЧасть , через которую можно совершать с ней любые действия.

НоваяСтрокаТЧ = ТабличнаяЧасть.Добавить();

Заполним созданную строку таб. части данными из строки результата запроса используя процедуруГлобального контекста - ЗаполнитьЗначенияСвойств(<Приемник>, <Источник>) .

ЗаполнитьЗначенияСвойств(НоваяСтрокаТЧ,ЭлементРезультата);

Но заполненных нами данных не достаточно, для того что бы документ провелся, необходимо заполнить еще счета учета номенклатуры . Для этого воспользуемся экспортной

процедурой ЗаполнитьСчетаУчетаВСтрокеТабЧасти из модуля объекта документа Реализация товаров и услуг . Вызовем ее при помощи параметра Объект (следует заметить,

что мы можем вызывать только экспортные процедуры из модуля объекта документа).

Объект.ЗаполнитьСчетаУчетаВСтрокеТабЧасти(НоваяСтрокаТЧ, ИмяТабличнойЧасти, Истина);

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

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

В следующей части стать будет рассказано, как отладить обработку заполнения табличной части и как подключить ее к документу.

4. Отладка

Довольно часто требуется отлаживать код, который вы пишите. Для того что бы отладить обработку заполнения табличной части в 1С 8 создадим у нее реквизит СсылкаНаОбъект типаДокументСсылка.РеализацияТоваровУслуг

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

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

Процедура КнопкаВыполнитьНажатие(Кнопка) Инициализировать(СсылкаНаОбъект.ПолучитьОбъект(), "Товары" ); КонецПроцедуры

Теперь необходимо сделать созданную форму основной формой обработки. Для этого выберем ее в поле “Форма обработки”.

Теперь вы можете ставить точку останова в нужном месте процедуры Инициализировать или процедурыКнопкаВыполнитьНажатие формы отладки, и запускать обработку заполнения табличной части в режиме отладки 1С:Предприятия .

5. Подключение к документу

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

Заполним принадлежность обработки, для этого воспользовавшись кнопкой Подбор выберем документРеализация товаров и услуг

И укажем, что заполнение предназначено для табличной части Товары .

Нажимаем кнопку ОК и на этом все, обработка заполнения будет доступна в меню Заполнить табличной части Товары документа Реализация товаров и услуг . Скачать обработку использованную для этого примера вы можете внизу статьи.

1. Постановка задачи

В этой статье рассмотрим процесс написания простейшей внешней обработки заполнения табличной части в 1С 8 для конфигураций, использующих обычное приложение. Для примера возьмем такую задачу: “В конфигурации 1С:Бухгалтерия 2.0 создать внешнюю обработку заполнения табличной части Товары документа , данные для заполнения взять из табличной части Товары документа Поступление товаров и услуг ”. Таким образом нам необходимо заполнить товары реализации на основании товаров поступления, такая задача довольно часто встречается в реальной практике программиста 1С.

2. Создание внешней обработки

Зайдем в 1С 8 в режиме Конфигуратор . При помощи меню Файл -> Новый или пиктограммы Новый документ создадим новую внешнюю обработку .

В поле Имя укажем: “ПростейшееЗаполнениеТабличнойЧасти” и сохраним внешнюю обработку на жесткий диск используя меню Файл -> Сохранить или пиктограмму Сохранить или сочетание клавиш Ctrl + S .

Выделив ветку Реквизиты в дереве метаданных обработки и нажав кнопку Добавить (кнопка с зеленым плюсом) создадим новый реквизит внешней обработки — ДокументПоступления , выберем для него тип ДокументСсылка.ПоступлениеТоваровУслуг , этот реквизит нужен нам для выбора документа Поступление товаров и услуг , на основании которого будет заполняться реализация.

Для выбора документа поступления нам понадобится отдельная форма. Выделив ветку Формы и используя ту же кнопку — Добавить создадим форму внешней обработки. Откроется окно конструктора формы, на первой странице конструктора никаких изменений делать не нужно, поэтому просто нажмем кнопку Далее .

На второй странице конструктора нам необходимо выбрать реквизит ДокументПоступления (для того что бы он появился на создаваемой форме) и нажать кнопку Готово .

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

3. Программирование

Приступим к программированию обработки заполнения табличной части. Перейдем в Модуль объекта внешней обработки(на нижней панели обработки кнопка Действия -> Открыть модуль объекта ).

В нем нам необходимо создать экспортную процедуру Инициализировать .

Процедура Инициализировать Экспорт КонецПроцедуры

Обратите внимание, что процедура Инициализировать , а так же все ее параметры, являются обязательными для внешней обработки заполнения табличной части , если вы ее не создадите или не укажите все параметры, ваша обработка просто не будет работать.

Теперь приступим к написанию программного кода. В первую очередь создадим переменную для табличной части документа Реализация товаров и услуг , которую мы будем заполнять.

ТабличнаяЧасть = Объект[ИмяТабличнойЧасти];

При выполнении процедуры в параметре Объект будет содержаться объект документа, который мы заполняем, а в параметре ИмяТабличнойЧасти строка с именем табличной части, которую мы заполняем. Таким образом эта строчка кода получает табличную часть заполняемого документа по ее имени.

Нам необходимо что бы пользователь выбрал документ Поступление товаров и услуг , поэтому напишем код открытия формы выбора документа. Для начала получим эту форму в переменную, используя метод внешней обработки ПолучитьФорму(<Форма>, <Владелец>, <КлючУникальности>) . Нам достаточно заполнить только первый параметр этого метода, передав туда строку с именем нашей формы.

ФормаВыбораПоступления = ПолучитьФорму("Форма" );

Теперь откроем полученную форму, используя модальное открытие(пока форма открыта все остальные окна 1С недоступны), потому что при таком способе открытия дальнейший наш код в процедуре Инициализировать выполняться не будет, пока пользователь не закроет форму.

ФормаВыбораПоступления.ОткрытьМодально();

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

Если НЕ ЗначениеЗаполнено(ДокументПоступления) Тогда Сообщить (); Возврат ; КонецЕсли ;

Для проверки заполненности реквизита здесь используется функция глобального контекста ЗначениеЗаполнено(<Значение>) , она проверяет отличатся ли значение переданное в параметре от значения по умолчанию того же типа. Процедура Сообщить выводит указанный текст в окно сообщений 1С 8. Ключевое слово Возврат прерывает выполнение процедуры.

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

Запрос = Новый Запрос;

Запрос.УстановитьПараметр("ДокументПоступления" ,ДокументПоступления);

Напишем текст запроса, будем делать это при помощи Конструктора запроса . Писать текст запроса вручную не рекомендуется, это не эффективно и отнимает кучу времени. Для начала напишем строку:

Запрос.Текст = "" ;

Поставим курсор между символами кавычек, нажмем правую кнопку мыши и выберем пунк Конструктор запроса… . После этого появится предложение создать новый запрос, нажмем кнопку “ОК”. Откроется окно конструктора, в левой его части расположены все доступные таблицы базы данных, нам необходим документ ПоступлениеТоваровУслуг . Найдем его и раскроем при помощи символа “+”, выберем табличную часть Товары и перетащим ее во вторую часть экрана конструктора, которая называется Таблицы (Также переместить нужную таблицу можно при помощи кнопки “>”).

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

Так как нам нужны данные только одного документа поступления(который мы выбрали перед началом заполнения), то в на закладке “Условия” наложим условие на ссылку документа при помощи переданного нами параметра.

Создание текста запроса в конструкторе на этом завершено, нажмем кнопку “ОК”. В итоге у нас получился следующий текст запроса:

Запрос.Текст = "ВЫБРАТЬ |ИЗ |ГДЕ ;

Созданный запрос осталось только выполнить и выгрузить в переменную:

Результат = Запрос.Выполнить().Выгрузить();

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

ТабличнаяЧасть.Очистить();

При помощи цикла Для каждого обойдем таблицу значений с результатами запроса.

Для Каждого ЭлементРезультата из Результат Цикл КонецЦикла ;

В этом цикле создадим и заполним строки табличной части документа Реализация товаров и услуг . Создать новую строку мы можем при помощи переменной ТабличнаяЧасть , через которую можно совершать с ней любые действия.

НоваяСтрокаТЧ = ТабличнаяЧасть.Добавить();

Заполним созданную строку таб. части данными из строки результата запроса используя процедуру Глобального контекста ЗаполнитьЗначенияСвойств(<Приемник>, <Источник>) .

ЗаполнитьЗначенияСвойств(НоваяСтрокаТЧ,ЭлементРезультата);

Но заполненных нами данных не достаточно, для того что бы документ провелся, необходимо заполнить еще счета учета номенклатуры . Для этого воспользуемся экспортной

процедурой ЗаполнитьСчетаУчетаВСтрокеТабЧасти из модуля объекта документа Реализация товаров и услуг . Вызовем ее при помощи параметра Объект (следует заметить,

что мы можем вызывать только экспортные процедуры из модуля объекта документа).

Объект.ЗаполнитьСчетаУчетаВСтрокеТабЧасти(НоваяСтрокаТЧ, ИмяТабличнойЧасти, Истина);

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

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

В следующей части стать будет рассказано, как отладить обработку заполнения табличной части и как подключить ее к документу.

4. Отладка

Довольно часто требуется отлаживать код, который вы пишите. Для того что бы отладить обработку заполнения табличной части в 1С 8 создадим у нее реквизит СсылкаНаОбъект типа ДокументСсылка.РеализацияТоваровУслуг

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

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

Процедура КнопкаВыполнитьНажатие(Кнопка) Инициализировать(СсылкаНаОбъект.ПолучитьОбъект(), "Товары" ); КонецПроцедуры

Теперь необходимо сделать созданную форму основной формой обработки. Для этого выберем ее в поле “Форма обработки”.

Теперь вы можете ставить точку останова в нужном месте процедуры Инициализировать или процедуры КнопкаВыполнитьНажатие формы отладки, и запускать обработку заполнения табличной части в режиме отладки 1С:Предприятия .

5. Подключение к документу

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

Заполним принадлежность обработки, для этого воспользовавшись кнопкой Подбор выберем документ Реализация товаров и услуг

И укажем, что заполнение предназначено для табличной части Товары .

Нажимаем кнопку ОК и на этом все, обработка заполнения будет доступна в меню Заполнить табличной части Товары документа Реализация товаров и услуг . Скачать обработку использованную для этого примера вы можете по .

В рамках данной статьи мы напишем обработку заполнения табличной части в 1С 8.3 для типовой конфигурации 1С:ERP 2.1. Предположим, что целью поставленной задачи стоит установка ручной скидки в размере 5% для всех номенклатурных позиций данного документа. Пример из статьи можно скачать по или другой аналогичной обработки по .

Данная инструкция предназначена для управляемых форм (8.2 и 8.3). Для обычных форм (8.1, 8.2) можно воспользоваться .

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

Откройте модуль объекта и пропишите код, приведенный ниже (его также можно взять из данной выше обработки). В целом, структура не будет меняться в зависимости от ситуации. Редактируются только некоторые параметры настроек, а так же при необходимости имена переменных.

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

Заполнение табличной части документа

Создадим новую форму обработки.

Теперь нам необходимо добавить на созданной форме новую команду. Предполагается, что она будет автоматически менять данные в табличной части как одного, так и нескольких документов (их формы списка) одновременно, записывая их впоследствии.

В рамках нашего примера будет произведена обработка уже существующей табличной части «Товары». Для каждой строки будет установлена ручная скидка в размере 5%. Так же, мы рассчитаем саму сумму данной скидки, равную сумме товаров в строке, умноженных на 0,05.

&НаСервере Процедура ВыполнитьКоманду(Команда, ОбъектыНазначения) Для каждого ЗаказКлиента из ОбъектыНазначения Цикл ЗаказКлиентаОбъект = ЗаказКлиента. ПолучитьОбъект() ; Для каждого СтрокаТЗ из ЗаказКлиентаОбъект. Товары Цикл СтрокаТЗ. ПроцентРучнойСкидки = 5 ; СтрокаТЗ. СуммаРучнойСкидки = СтрокаТЗ. Сумма * 0 . 05 ; КонецЦикла ; ЗаказКлиентаОбъект. Записать() ; КонецЦикла ; КонецПроцедуры

Регистрация внешней обработки

Запустите 1С в режиме «Предприятие» и откройте справочник «Дополнительные отчеты и обработки». Найдем его через меню «Все функции».

Создайте новый элемент в открывшемся справочнике и по одноименной кнопке загрузите из файла свою обработку. Разместим ее одновременно и на форме списка и на форме самой карточки документа.

Теперь в форме списка документов «Заказ клиента» появится кнопку «Заполнение…», которая позволит произвести изменить ручные скидки товаров сразу у нескольких документов.

Так же данная кнопка будет доступна и в карточке самого документа.