При разработке учетных механизмов на платформе 1С часто требуется организовать ввод бухгалтерских проводок или аналитики в табличной части документа. Стандартный подход предполагает создание колонок для счета и нескольких субконто составного типа Характеристика.ВидыСубконтоХозрасчетные (или аналогичного плана видов характеристик). Для автоматического сужения типа субконто разработчики настраивают свойство Связи по типу, указывая реквизит счета и номер субконто (от 1 до 3). Однако на практике возникает ситуация: если на выбранном счете открыто меньше субконто, чем предусмотрено в строке, платформа позволяет выбрать значение абсолютно любого типа из плана видов характеристик. Выясним причину такого поведения платформы и разберем способы решения этой проблемы.
Проанализируем, как устроен механизм Связь по типу в платформе 1С. Когда в свойствах реквизита задается связь со счетом и выбирается элемент связи с определенным номером, платформа обращается к строке табличной части ВидыСубконто выбранного счета.
Если на счете настроено меньше видов субконто, чем указанный номер связи (например, указана связь по субконто № 2, а на счете задано только одно субконто), платформа не может определить целевой тип данных. В этом случае система не блокирует поле ввода и не устанавливает пустой тип данных. Вместо этого платформа возвращается к исходному составному типу реквизита, определенному в метаданных. В результате при нажатии кнопки выбора пользователю открывается полный список типов плана видов характеристик.
Важно помнить, что декларативная связь по типу решает только задачу фильтрации типов в диалоге выбора. Она не управляет доступностью элементов формы, не очищает ранее введенные значения при смене счета и не проверяет логическую корректность данных при записи. Для полноценного интерфейса требуется программная обработка.
Разберем по шагам наиболее быстрый и надежный способ предотвратить некорректный выбор. Используем обработчик события НачалоВыбора элемента формы соответствующего субконто. Если у счета отсутствует субконто с требуемым номером, мы отменяем стандартную обработку.
СубконтоНачалоВыбора на форме документа.Элементы.ТабличнаяЧасть.ТекущиеДанные.СтандартнаяОбработка = Ложь.Посмотрим на пример клиентского кода:
&НаКлиенте
Процедура ТабличнаяЧастьСубконто2НачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
ТекущаяСтрока = Элементы.ТабличнаяЧасть.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
// Проверяем доступность субконто для выбранного счета на сервере
Если Не СубконтоДоступно(ТекущаяСтрока.Счет, 2) Тогда
СтандартнаяОбработка = Ложь;
ПоказатьОповещениеПользователя("Внимание", , "У выбранного счета нет второго субконто!");
КонецЕсли;
КонецПроцедуры
Рассмотрим подробнее сценарий, когда пользователь сначала выбрал счет с тремя субконто, заполнил их, а затем изменил счет на другой, у которого открыто только одно субконто. В таком случае в строке останутся "висящие" невалидные данные. Чтобы исключить эту ситуацию, настроим событие ПриИзменении для поля выбора счета.
Посмотрим на пример реализации очистки лишних субконто:
&НаКлиенте
Процедура ТабличнаяЧастьСчетПриИзменении(Элемент)
ТекущаяСтрока = Элементы.ТабличнаяЧасть.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
ОчиститьНедоступныеСубконтоНаСервере(ТекущаяСтрока);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ОчиститьНедоступныеСубконтоНаСервере(СтрокаТЧ)
Если Не ЗначениеЗаполнено(СтрокаТЧ.Счет) Тогда
СтрокаТЧ.Субконто1 = Неопределено;
СтрокаТЧ.Субконто2 = Неопределено;
СтрокаТЧ.Субконто3 = Неопределено;
Возврат;
КонецЕсли;
КоличествоСубконто = СтрокаТЧ.Счет.ВидыСубконто.Количество();
Если КоличествоСубконто < 1 Тогда
СтрокаТЧ.Субконто1 = Неопределено;
КонецЕсли;
Если КоличествоСубконто < 2 Тогда
СтрокаТЧ.Субконто2 = Неопределено;
КонецЕсли;
Если КоличествоСубконто < 3 Тогда
СтрокаТЧ.Субконто3 = Неопределено;
КонецЕсли;
КонецПроцедуры
В управляемых формах изменение свойств Доступность или ТолькоПросмотр у элемента колонки табличной части блокирует всю колонку для всех строк разом. Чтобы отключить ввод только в тех ячейках, где субконто не предусмотрено выбранным счетом, настроим Условное оформление формы.
Субконто1Доступно, Субконто2Доступно, Субконто3Доступно (свойство СохраняемыеДанные можно отключить).ВидыСубконто счета.ТабличнаяЧастьСубконто2 установим свойство ТолькоПросмотр = Истина при условии Субконто2Доступно = Ложь. Аналогично настроим правило для третьего субконто.Такой подход обеспечивает понятный пользовательский интерфейс: недоступные ячейки визуально блокируются для редактирования сразу после выбора счета.
Вместо декларативной связи по типу в метаданных можно использовать программную установку свойства элемента формы ОграничениеТипа. Разберем этот вариант:
В обработчике ПриАктивизацииСтроки табличной части считываются типы субконто для текущего счета строки. Если субконто у счета задано, свойству элемента формы ОграничениеТипа присваивается ТипЗначения соответствующего вида субконто. Если субконто на счете отсутствует, полю назначается пустой объект Новый ОписаниеТипов(), что полностью блокирует выбор любых значений.
Даже при корректной настройке интерфейса формы данные могут быть загружены программно из внешних источников или через обмен. Для гарантированной защиты данных реализуем проверку в модуле объекта перед записью:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Для Каждого СтрокаТЧ Из ТабличнаяЧасть Цикл
Если Не ЗначениеЗаполнено(СтрокаТЧ.Счет) Тогда
Продолжить;
КонецЕсли;
КолСубконто = СтрокаТЧ.Счет.ВидыСубконто.Количество();
Если КолСубконто < 3 И ЗначениеЗаполнено(СтрокаТЧ.Субконто3) Тогда
СтрокаТЧ.Субконто3 = Неопределено;
КонецЕсли;
Если КолСубконто < 2 И ЗначениеЗаполнено(СтрокаТЧ.Субконто2) Тогда
СтрокаТЧ.Субконто2 = Неопределено;
КонецЕсли;
Если КолСубконто < 1 И ЗначениеЗаполнено(СтрокаТЧ.Субконто1) Тогда
СтрокаТЧ.Субконто1 = Неопределено;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Сочетание проверки в НачалоВыбора, очистки значений при смене счета и условного оформления обеспечивает корректную и надежную работу аналитики субконто на управляемых формах.