При переходе с конфигурации Зарплата и управление персоналом 2.5 на версию 3.1 многие разработчики сталкиваются с существенным изменением архитектуры учета. В версии 2.5 справочник СпособыОтраженияЗарплатыВБухУчете содержал в себе полные реквизиты проводки: счет дебета и три субконто. В ЗУП 3.1 этот справочник превратился в простой перечень наименований («статей»), так как предполагается, что вся бухгалтерская логика настраивается на стороне принимающей системы (например, 1С:Бухгалтерии 3.0).
Однако при необходимости выгрузки данных в нетиповые системы или старые конфигурации (например, в Комплексную 7.7), разработчикам приходится возвращать привычный функционал в ЗУП 3.1. В этой статье мы разберем, как программно реализовать динамическую работу со счетами и субконто на управляемых формах.
Основная сложность заключается в том, что в обычных формах (ЗУП 2.5) работа с типами данных была более прямолинейной. В управляемых формах (ЗУП 3.1) объект ЭтотОбъект заменяется на данные формы Объект, а работа с типами реквизитов требует четкого понимания контекста выполнения кода (сервер или клиент) и особенностей элементов управления.
Рассмотрим ситуацию: мы добавили в справочник реквизиты СчетДт (тип ПланСчетовСсылка.Хозрасчетный) и три реквизита СубконтоДт1, СубконтоДт2, СубконтоДт3 (тип Характеристика.ВидыСубконтоХозрасчетные). Наша цель — сделать так, чтобы при выборе счета в поле СчетДт поля субконто автоматически принимали нужный тип данных (СправочникСсылка.Номенклатура, СправочникСсылка.СтатьиЗатрат и т.д.), соответствующий настройкам плана счетов.
Проанализируем программный код, который позволяет динамически изменять значения субконто при смене счета. Нам необходимо создать обработчик события ПриИзменении для поля счета на форме. Рассмотрим алгоритм действий:
Ниже представлен пример кода, адаптированный для управляемого приложения:
&НаСервере
Процедура УстановитьТипыСубконтоНаСервере()
Счет = Объект.СчетДт;
// Проверяем, заполнен ли счет, чтобы избежать ошибок обращения к свойствам
Если НЕ ЗначениеЗаполнено(Счет) Тогда
Объект.СубконтоДт1 = Неопределено;
Объект.СубконтоДт2 = Неопределено;
Объект.СубконтоДт3 = Неопределено;
Возврат;
КонецЕсли;
ВидыСубконтоСчета = Счет.ВидыСубконто;
КоличествоВидов = ВидыСубконтоСчета.Количество();
Для Н = 1 По 3 Цикл
ИмяРеквизита = "СубконтоДт" + Н;
Если Н <= КоличествоВидов Тогда
// Получаем первый доступный тип для данного вида субконто
НужныйТип = ВидыСубконтоСчета[Н-1].ВидСубконто.ТипЗначения.Типы()[0];
// Если текущее значение не соответствует типу, создаем пустую ссылку нового типа
Если ТипЗнч(Объект[ИмяРеквизита]) <> НужныйТип Тогда
Объект[ИмяРеквизита] = Новый(НужныйТип);
КонецЕсли;
Иначе
// Если у счета меньше 3-х субконто, очищаем лишние реквизиты
Если Объект[ИмяРеквизита] <> Неопределено Тогда
Объект[ИмяРеквизита] = Неопределено;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Разберем подробнее, почему автор исходной темы мог столкнуться с проблемой «сброса» типа в Неопределено. В управляемых формах реквизиты объекта, имеющие составной тип (или тип Характеристика), ведут себя специфично. Если вы просто присваиваете значение Новый(НужныйТип), платформа пытается отобразить его в поле ввода. Но если для элемента формы (поля ввода) не ограничены доступные типы, при интерактивном выборе система может снова предложить выбрать тип из всего списка доступных ВидовСубконтоХозрасчетных.
Для корректной работы интерактивного выбора (чтобы при нажатии на кнопку выбора сразу открывался нужный справочник), рекомендуется использовать свойство СвязьПоТипу в настройках элемента формы или программно устанавливать ОграничениеТипа.
Рассмотрим, как программно ограничить выбор в поле субконто через событие НачалоВыбора:
&НаКлиенте
Процедура СубконтоДт1НачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
// Получаем виды субконто со счета (нужно реализовать получение данных со счета)
// В реальной задаче лучше кэшировать типы субконто при изменении счета
ТипСубконто = ПолучитьТипСубконтоСоСервера(Объект.СчетДт, 1);
Если ТипСубконто <> Неопределено Тогда
Элемент.ОграничениеТипа = ТипСубконто;
// Отключаем выбор типа, если тип однозначно определен
Элемент.ВыбиратьТип = Ложь;
КонецЕсли;
КонецПроцедуры
Поскольку целью данной разработки является выгрузка в Комплексную конфигурацию 7.7, проанализируем дополнительные риски:
Использование метода Новый(Тип) внутри серверной процедуры (как показано в примере выше) является наиболее эффективным способом «подсказать» системе, какой тип ссылки должен храниться в реквизите Характеристика. Это обеспечивает корректную работу метаданных при записи объекта в базу данных 1С.
Подводя итог, можно сказать, что перенос функционала из ЗУП 2.5 в 3.1 требует не просто копирования кода, а его адаптации под клиент-серверную архитектуру. Основной упор следует делать на использование серверных процедур для обработки метаданных счета и клиентских событий для управления поведением элементов формы.