При автоматизации расчетов в документах 1С часто возникает типовая задача: необходимо обойти строки табличной части, проверить заполнение определенного реквизита и, если он пустой, пропустить обработку и перейти к следующей строке. Если же данные присутствуют, выполняется определенный алгоритм расчета. Разберем по шагам, какие типовые ошибки возникают при реализации этого сценария, как правильно организовать обход коллекции и как грамотно оформить переход между итерациями.
Начинающие разработчики нередко пытаются применить функцию ПустаяСтрока() ко всем подряд реквизитам. Однако важно помнить о строгой типизации данных в платформе 1С:
ПустаяСтрока() предназначена исключительно для строковых значений. Если передать в нее значение ссылочного типа (например, ссылку на элемент справочника ХарактеристикиНоменклатуры), платформа не сможет корректно обработать тип данных, либо результат проверки будет некорректным.ЗначениеЗаполнено() либо специализированным методом ссылки ПустаяСсылка().Функция ЗначениеЗаполнено() является универсальной: она возвращает Ложь, если переданное значение равно пустой строке, числу 0, пустой дате '00010101', пустой ссылке любого справочника или документа, а также значению Неопределено или NULL.
Еще одна типичная архитектурная ошибка — попытка реализовать пропуск строки через метки и безусловный переход (Перейти ~Метка;). Использование оператора Перейти ломает линейность чтения кода, усложняет отладку и считается плохой практикой разработки. В языке 1С для досрочного перехода к следующей итерации цикла существует штатный оператор Продолжить.
Когда интерпретатор встречает оператор Продолжить, выполнение текущего шага цикла немедленно прерывается, и управление передается в начало следующей итерации (к следующему элементу коллекции).
Рассмотрим типовую конструкцию обхода строк табличной части документа на сервере. Предположим, у документа есть табличная часть Товары с реквизитами ХарактеристикаНоменклатуры и Партия. Нам необходимо пропустить строки с незаполненными характеристиками, а для заполненных — сформировать реквизит партии.
Для Каждого СтрокаТабличнойЧасти Из ЭтотОбъект.Товары Цикл
// Проверяем заполненность реквизита строки
Если Не ЗначениеЗаполнено(СтрокаТабличнойЧасти.ХарактеристикаНоменклатуры) Тогда
// Пропускаем дальнейшие действия и берем следующую строку
Продолжить;
КонецЕсли;
// Ниже выполняется основной алгоритм для заполненной строки
// Например, расчет сопутствующих данных или заполнение реквизитов
СтрДляРазбора = Строка(СтрокаТабличнойЧасти.ХарактеристикаНоменклатуры);
// Выполняем требуемые манипуляции
Если СтрНайти(СтрДляРазбора, "Срочный") > 0 Тогда
СтрокаТабличнойЧасти.Партия = "Приоритетная";
КонецЕсли;
КонецЦикла;
Если задача решается в модуле формы (например, в обработчике события ПриИзменении), важно учитывать контекст клиент-серверного взаимодействия:
Элементы.ИмяТаблицы.ТекущиеДанные.Посмотрим на пример правильной обработки изменения конкретной строки в модуле формы:
&НаКлиенте
Процедура ТоварыХарактеристикаНоменклатурыПриИзменении(Элемент)
ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
// Если характеристика очищена пользователем — очищаем зависимое поле
Если Не ЗначениеЗаполнено(ТекущаяСтрока.ХарактеристикаНоменклатуры) Тогда
ТекущаяСтрока.Партия = "";
Возврат;
КонецЕсли;
// Вызываем серверную процедуру для расчета параметров
РассчитатьПараметрыСтрокиНаСервере(ТекущаяСтрока.НомерСтроки);
КонецПроцедуры
Разберем ситуацию, когда из строкового представления характеристики пытаются извлечь дату или номер смены. Разбор строк с помощью функций Сред(), Прав() или Лев() несет в себе критические архитектурные риски:
Дата("Строка") требует строгого формата ГГГГММДДЧЧММСС. Попытка передать строку вида "01.01.2024" без явного выделения чисел года, месяца и дня вызовет аварийное завершение работы программы. Для безопасного формирования даты из отдельных частей необходимо использовать явное приведение к числу: Дата(Число(Год), Число(Месяц), Число(День)).