В практике разработки на платформе 1С:Предприятие 8 часто возникает задача автоматизации ввода данных. Типичный пример: при выборе определенных параметров в шапке объекта (например, справочника или документа) система должна автоматически найти связанные данные в других регистрах или справочниках и заполнить ими табличную часть. Рассмотрим ситуацию, когда у нас есть справочник РабочиеМеста, и нам нужно подтянуть данные из ШтатногоРасписания сразу после выбора подразделения и должности.
Представим, что в справочнике РабочиеМеста созданы два реквизита: Подразделение и Должность. Это ссылки на соответствующие справочники. Также имеется табличная часть ПозицииШтатногоРасписания, где основным реквизитом является ссылка на справочник ШтатноеРасписание. Наша цель — сделать так, чтобы пользователь не выбирал позицию вручную, а система сама находила нужный элемент, где комбинация подразделения и должности совпадает с выбранными значениями.
Проанализируем механику: поиск по текстовому наименованию («Подразделение + Должность») является ненадежным, так как малейшая лишняя точка или пробел приведет к ошибке. Поэтому мы будем строить логику на поиске по ссылкам.
Для того чтобы система реагировала на действия пользователя «на лету», нам необходимо использовать события элементов формы. Разберем по шагам, как настроить эти события:
РабочиеМеста.Подразделение найдем в палитре свойств событие ПриИзменении и создадим соответствующую процедуру на клиенте.Должность.Чтобы не дублировать сложный код поиска в двух местах, мы создадим одну общую серверную процедуру, которую будем вызывать из обоих обработчиков. Это обеспечит чистоту кода и удобство отладки.
&НаКлиенте
Процедура ПодразделениеПриИзменении(Элемент)
ОбновитьПозициюШтатногоРасписания();
КонецПроцедуры
&НаКлиенте
Процедура ДолжностьПриИзменении(Элемент)
ОбновитьПозициюШтатногоРасписания();
КонецПроцедуры
Теперь рассмотрим основную логику. Нам нужно проверить, заполнены ли оба реквизита, и если да — выполнить запрос к базе данных. Использование запроса — это наиболее производительный способ получения данных в 1С.
Выясним причину, почему лучше использовать &НаСервере. Поиск данных в справочнике ШтатноеРасписание требует обращения к базе данных, что невозможно сделать непосредственно на клиенте. Мы передадим в запрос ссылки на выбранные объекты и получим результат.
&НаСервере
Процедура ОбновитьПозициюШтатногоРасписания()
// Проверяем заполненность ключевых полей
Если НЕ ЗначениеЗаполнено(Объект.Подразделение) Или НЕ ЗначениеЗаполнено(Объект.Должность) Тогда
Возврат;
КонецЕсли;
// Формируем запрос для поиска позиции
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ШтатноеРасписание.Ссылка КАК Ссылка
|ИЗ
| Справочник.ШтатноеРасписание КАК ШтатноеРасписание
|ГДЕ
| ШтатноеРасписание.Подразделение = &Подразделение
| И ШтатноеРасписание.Должность = &Должность
| И ШтатноеРасписание.ПометкаУдаления = ЛОЖЬ";
Запрос.УстановитьПараметр("Подразделение", Объект.Подразделение);
Запрос.УстановитьПараметр("Должность", Объект.Должность);
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
// Очищаем старые данные и добавляем новую позицию
Объект.ПозицииШтатногоРасписания.Очистить();
НоваяСтрока = Объект.ПозицииШтатногоРасписания.Добавить();
НоваяСтрока.ПозицияШтатногоРасписания = Выборка.Ссылка;
Иначе
// Если ничего не найдено, можно уведомить пользователя
Объект.ПозицииШтатногоРасписания.Очистить();
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Позиция в штатном расписании для данных подразделения и должности не найдена!";
Сообщение.Сообщить();
КонецЕсли;
КонецПроцедуры
В более сложных конфигурациях, таких как 1С:ЗУП 3.1, штатное расписание может вестись с учетом истории изменений. В этом случае данные хранятся не просто в справочнике, а в регистрах сведений. Проанализируем ситуацию: если нам нужно получить актуальную позицию на текущую дату, обычного запроса к справочнику может быть недостаточно.
Для решения этой задачи мы рекомендуем использовать метод СрезПоследних. Рассмотрим пример логики, если бы позиции хранились в регистре:
// Пример получения данных из регистра сведений
Запрос.Текст =
"ВЫБРАТЬ
| ИсторияШтатногоРасписанияСрезПоследних.Позиция КАК Позиция
|ИЗ
| РегистрСведений.ИсторияШтатногоРасписания.СрезПоследних(&Период, Подразделение = &Подразделение И Должность = &Должность) КАК ИсторияШтатногоРасписанияСрезПоследних";
Запрос.УстановитьПараметр("Период", ТекущаяДата());
При заполнении табличной части важно учитывать несколько нюансов:
Объект.ПозицииШтатногоРасписания.Очистить() необходим, чтобы при смене подразделения в шапке старые (неактуальные) строки не оставались в списке.ЗаполнитьЗначенияСвойств(НоваяСтрока, Источник). Это значительно сокращает код и уменьшает вероятность ошибок при добавлении новых полей.&НаСервереБезКонтекста для поиска ссылки. Это ускоряет работу формы, так как на сервер не передается весь массив данных объекта, а только необходимые параметры. Однако в нашем случае, так как мы модифицируем Объект (табличную часть), использование &НаСервере оправдано.Если автоматическое заполнение не должно быть «жестким», и вы хотите позволить пользователю выбирать позицию вручную, но с фильтром, используйте механизм Связи параметров выбора.
Разберем, как это настроить в конфигураторе:
ПозицияШтатногоРасписания в табличной части справочника.Отбор.Подразделение был связан с полем Объект.Подразделение.Это позволит системе автоматически ограничивать список выбора в табличной части только теми позициями, которые относятся к выбранному подразделению в шапке, даже без написания программного кода.
Таким образом, комбинируя программный поиск через Запрос и стандартные механизмы платформы 1С, мы получаем надежное и удобное решение для автоматизации ввода данных в справочнике.