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