User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active
 

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

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

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

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

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

 

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

Приступим!



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

1C 1S 1С Предприятие создаем внешнюю обработку заполнения табличных частей

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

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

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

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

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

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

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

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

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

1С предприятие рисуем на форме

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

1С Предприятие Рисуем на форме

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

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

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

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

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

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

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

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

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

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

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

&НаКлиенте

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

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

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

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

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

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

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

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

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

Вот и все.

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

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

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

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

 

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

Вложения
Download this file (ZapolnitAvansBuh30.epf)ZapolnitAvansBuh30.epf[1С Бухгалтерия 3.0 Заполнение аванса в ведомости на выплату через кассу]7 kB

Авторизуйтесь пожалуйста

Comments   

+10 # Людмила 2015-08-18 05:55
Спасибо очень помогло!
+2 # Михаил 2016-02-03 06:22
Очень полезная статья!!! А можно то же самое без открытия формы, и проставления процентов?