Обработка заполнения документа 1с 8.3

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

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

Поэтому в 1С видное место занимает работа с таблицами.

Таблицы в 1С также называют «табличные части». Они есть у справочников, документов и других .

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

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

//Вариант 1 – последовательный доступ к результатам запроса

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

//Вариант 2 – выгрузка в таблицу значений
Запрос = Новый Запрос(«ВЫБРАТЬ Наименование ИЗ Справочник.Номенклатура»);
//получение таблицы
Таблица = Запрос.Выполнить().Выгрузить().
//далее можем также обойти все строки
Для каждого Строка из Таблица Цикл
Сообщить(Строка.Наименование);
КонецЦикла;
//или произвольно обращаться к строкам
Строка = Таблица.Найти(«Лопата», «Наименование»);

Важная особенность – в таблице, которая получена из результата запроса, все колонки будут строго типизированы. Это значит, что запросив поле Наименование из справочника Номенклатура, Вы получите колонку вида Строка с допустимой длиной не более N символов.

Таблица на форме (толстый клиент)

Пользователь работает с таблицей, когда она размещена на форме.

Базовые принципы работы с формами мы с Вами обсуждали в уроке по и в уроке по

Итак, разместим таблицу на форме. Для этого можно перетащить таблицу с панели элементов управления. Аналогично можно выбрать в меню Форма/Вставить элемент управления.

Данные могут храниться в конфигурации – тогда нужно выбрать существующую (ранее добавленную) табличную часть того объекта конфигурации, форму которого Вы редактируете.

Нажмите кнопку «…» в свойстве Данные. Для того, чтобы увидеть список табличных частей, нужно раскрыть ветку Объект.

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

В этом же свойстве Данные Вы можете ввести произвольное имя и выбрать тип ТаблицаЗначений.

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

Нажав правой кнопкой на таблице Вы можете добавить колонку. В свойствах колонки можно указать его имя (для обращения в коде 1С), заголовок колонки на форме, связь с реквизитом табличной части (последнее – если выбрана не произвольная таблица, а табличная часть).

В свойствах таблицы на форме Вы можете указать – доступно ли пользователю добавлять/удалять строки. Более продвинутая форма – галочка ТолькоПросмотр. Эти свойства удобно использовать для организации таблиц предназначенных для вывода информации, но не редактирования.

Чтобы управлять таблицей, нужно вывести на форму командную панель. Выберите пункт меню Форма/Вставить элемент управления/Командная панель.

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

Таблица на форме (тонкий/управляемый клиент)

На управляемой форме указанные действия выглядят немного по другому. Если Вам нужно разместить на форме табличную часть – раскройте ветку Объект и перетащите одну из табличных частей влево. И все!

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

Чтобы добавить колонки, используйте меню по правой кнопке мыши на этом реквизите формы, пункт Добавить колонку реквизита.

После чего также перетащите таблицу влево.

Чтобы у таблицы появилась командная панель, в свойствах таблицы выберите значения в секции Использование – Положение командной панели.

Выгрузка таблицы в Excel

Любую таблицу 1С, расположенную на форме, можно распечатать или выгрузить в Excel.

Для этого щелкните правой кнопкой мыши на свободном месте в таблице и выберите пункт Вывести список.

В управляемом (тонком) клиент аналогичные действия можно выполнить с помощью пункта меню Все действия/Вывести список.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Блог компании 1С GOODWILL

Здесь мы научимся создавать внешнюю обработку заполнения табличной части документа в 1С 8.3 (для управляемых форм) с нуля. Рассмотренный пример обработки можно скачать по ссылке.

Возьмем самой простой пример: в табличной части «Материалы» документа «Требование-накладная» присвоим во всех строках количеству значение равное 100.

Подготовка внешней обработки в 1С 8.3

Итак, создаем внешнюю обработку. Сохраняем ее на диск.

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

По кнопке «Действия» переходим в модель объекта, где и создаем функцию:

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

Поговорим немного о значении полей.

Вид - в зависимости то предназначения обработки может принимать значения:

Отчет ЗаполнениеОбъекта Печатная форма Дополнительная обработка СозданиеСвязанныхОбъектов Дополнительный отчет

В нашем случае, для обработки заполнения табличной части, нам необходим вид обработки «ЗаполнениеОбъекта»

Назначение - в этом поле перечисляются документы, для которых эта обработка предназначена (в которых она появится после регистрации в информационной базе). Для перечисления этих документов создадим массив «Назначения» и добавим в него документ «ТребованиеНакладная».

Наименование - это наименование будет отображаться в списке дополнительных обработок.

Версия - версия нашего нового программного продукта.

Информация - этот ключ нашей структуры содержит дополнительную информацию о нашей обработке.

Безопасный режим - принимает значение Истина/Ложь. Мы будем использовать безопасный режим.

Команды - этот ключ структуры содержит перечень поставляемых нашей обработкой команд. Для команд мы создадим функцию ПолучитьТаблицуКоманд() и процедуру ДобавитьКоманду().

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

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

Идентификатор - это внутренний идентификатор команды в пределах нашей обработки

Использование - в зависимости от использования команды может принимать значения:

ВызовСерверногоМетода - из модуля обработки вызывается серверная процедура ОткрытиеФормы - используется для открытия формы обработки ВызовКлиентского метода - для вызова клиентской процедуры из модуля обработки СценарийвБезопасномРежиме - серверная процедура в безопасном режиме

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

ПоказыватьОповещение - имеет одно из двух значений: Истина/Ложь

Модификатор - дополнительный модификатор команды. Итоговый листинг нашей обработки в модуле объекта приобретает следующий вид:

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

В поле Форма обработки нажмем линзу, чтобы создать форму:

В форме добавим команду ВыполнитьКоманду

В теле обработки заполнение команды обратимся к данным формы через ВладелецФормы и изменим значение количества в табличной части материалов:

&НаКлиенте Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт Для каждого ТекущаяСтрока из ВладелецФормы.Объект.Материалы Цикл ТекущаяСтрока.Количество = 100 ; Сообщить(ТекущаяСтрока.Количество) ; КонецЦикла; КонецПроцедуры Регистрация внешней обработки в 1С 8.3 и её проверка

Теперь в режиме предприятия 1С зарегистрируем нашу внешнюю обработку для заполнения табличной части:

В списке внешних обработок нажмем кнопку Создать:

В открывшемся бланке новой внешней обработки загрузим из файла внешнюю обработку и впоследствии запишем новую обработку:

Теперь в документе «Требование-накладная» мы можем наблюдать результат регистрации нашей обработки в информационной базе. А по нажатию кнопки «Заполнить документ» можем наблюдать работу нашей обработки по заполнению табличной части.

Запись Обработка заполнения табличной части 1С 8.3 управляемые формы на примере впервые появилась Блог компании 1С GOODWILL.

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

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

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

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

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

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

Приступим!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

&НаКлиенте

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

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

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

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

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

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

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

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

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

Вот и все.

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

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

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

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

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

Графика