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