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