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