Как программно получить свойства номенклатуры и выгрузить остатки в 1С 7.7

Программист 1С v7.7 Управленческий учет Торговля и дистрибуция
← На главную

В платформе 1С:Предприятие 7.7, особенно в конфигурации «Торговля и Склад 9.2», работа со свойствами объектов реализована через механизм подчиненных справочников. Часто возникает задача отфильтровать товары по определенному свойству (например, «Выгружать на сайт») и получить по ним актуальные остатки для передачи во внешние системы через CSV или HTTP-запросы. Разберем по шагам, как это реализовать эффективно.

Анализ структуры хранения свойств в ТиС 9.2

Прежде чем приступать к написанию кода, проанализируем, как данные хранятся в базе. В типовой конфигурации «Торговля и Склад» существует основной справочник Номенклатура. Ему подчинен справочник СвойстваНоменклатуры. Каждая запись в этом справочнике содержит:

  1. Владелец — ссылка на элемент справочника Номенклатура.
  2. ВидСвойства — ссылка на справочник ВидыСвойств (например, запись «На сайт»).
  3. ЗначениеСвойства — ссылка на справочник ЗначенияСвойств (например, «Да» или «Нет»).

Для решения задачи нам необходимо найти все записи в справочнике СвойстваНоменклатуры, у которых вид и значение соответствуют нашим критериям, и получить их владельцев.

Решение 1: Использование объекта Запрос (оптимальный метод)

Рассмотрим наиболее производительный способ — использование внутреннего языка запросов 1С 7.7. Вместо того чтобы перебирать весь справочник Номенклатура и для каждого товара проверять его свойства (что приведет к огромному количеству обращений к базе), мы обратимся напрямую к справочнику свойств.

Проанализируем пример кода для реализации фильтрации:


Процедура ВыгрузитьТоварыПоСвойству()
    Перем Запрос, ТекстЗапроса;
    
    // Создаем объект Запрос
    Запрос = СоздатьОбъект("Запрос");
    
    // Настраиваем текст запроса
    // Мы выбираем Владельца (товар), фильтруя по Виду и Значению свойства
    ТекстЗапроса = 
    "//{{ЗАПРОС(ВыгрузитьТоварыПоСвойству)
    |Без итогов;
    |ТМЦ = Справочник.СвойстваНоменклатуры.Владелец;
    |Вид = Справочник.СвойстваНоменклатуры.ВидСвойства;
    |Значение = Справочник.СвойстваНоменклатуры.ЗначениеСвойства;
    |Группировка ТМЦ без групп;
    |Условие(Вид = ВыбВидСвойства);
    |Условие(Значение = ВыбЗначениеСвойства);
    |"//}}ЗАПРОС
    ;

    // Выполняем запрос
    Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
        Возврат;
    КонецЕсли;

    // Перебираем результаты
    Пока Запрос.Группировка(1) = 1 Цикл
        // Здесь мы получили конкретный товар, подходящий под фильтр
        Товар = Запрос.ТМЦ;
        Сообщить("Выгружаем: " + Товар.Наименование);
        
        // Далее можно вызывать функцию получения остатка
    КонецЦикла;
КонецПроцедуры

В этом примере ВыбВидСвойства и ВыбЗначениеСвойства — это ссылки на соответствующие элементы справочников, которые вы можете выбрать на форме или найти программно через НайтиПоНаименованию.

Решение 2: Перебор через ИспользоватьВладельца (для единичных проверок)

Если нам нужно проверить свойства конкретного товара в процессе цикла по номенклатуре, мы можем воспользоваться методом ИспользоватьВладельца(). Выясним, как это работает на практике. Этот метод ограничивает выборку справочника только теми элементами, которые принадлежат конкретному объекту-владельцу.


СпрСвойства = СоздатьОбъект("Справочник.СвойстваНоменклатуры");
СпрСвойства.ИспользоватьВладельца(ТекущийТовар);
СпрСвойства.ВыбратьЭлементы();
Пока СпрСвойства.ПолучитьЭлемент() = 1 Цикл
    Если (СпрСвойства.ВидСвойства = НужныйВид) и (СпрСвойства.ЗначениеСвойства = НужноеЗначение) Тогда
        // Товар подходит под условие
        Прервать;
    КонецЕсли;
КонецЦикла;

Важно: этот метод крайне медленный, если товаров в базе много (более 1000), так как для каждой позиции 1С будет выполнять отдельный SQL-запрос к таблице свойств.

Получение остатков товаров

После того как мы отфильтровали нужные товары, нам необходимо получить их остатки. В 1С 7.7 для этого используется объект Регистр.ОстаткиТМЦ. Рассмотрим, как получить сводный остаток по всем складам для конкретной позиции.


Функция ПолучитьОстатокТовара(Товар)
    Рег = СоздатьОбъект("Регистр.ОстаткиТМЦ");
    Возврат Рег.СводныйОстаток(Товар, , , "Количество");
КонецФункции

Однако, если вы делаете массовую выгрузку, эффективнее будет один раз выгрузить все итоги регистра в таблицу значений методом ВыгрузитьИтоги(), а затем искать в этой таблице данные по коду или ссылке товара. Это значительно ускорит работу обработки.

Формирование CSV файла и работа с кодировкой

Для записи данных в формате CSV в 1С 7.7 используется объект Текст. Проанализируем нюансы: штатный метод Записать() сохраняет файл в кодировке Windows-1251. Если ваш сайт требует UTF-8, придется использовать внешние компоненты или объект ADODB.Stream.

Пример формирования строки CSV:


ТекстФайла = СоздатьОбъект("Текст");
// Заголовок CSV
ТекстФайла.ДобавитьСтроку("Артикул;Наименование;Остаток");

// В цикле по запросу
СтрокаДанных = СокрЛП(Товар.Артикул) + ";" + СокрЛП(Товар.Наименование) + ";" + Строка(Остаток);
ТекстФайла.ДобавитьСтроку(СтрокаДанных);

// Сохранение
ТекстФайла.Записать("C:\export\items.csv");

Рекомендации по автоматизации (POST запрос)

Если задача стоит сделать выгрузку «молча» и отправить её на сервер, рассмотрим использование объекта WinHttp.WinHttpRequest.5.1. Это позволит отправить данные методом POST без участия пользователя.


Http = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
Http.Open("POST", "https://vash-sayt.ru/api/update", 0);
Http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// Подготовка тела запроса
ТелоЗапроса = "data=" + ДанныеДляОтправки;
Http.Send(ТелоЗапроса);
Если Http.Status = 200 Тогда
    Сообщить("Данные успешно отправлены");
КонецЕсли;

Подведем итоги

Для реализации задачи «минимум» (получение свойств) лучше всего подходит объект Запрос к справочнику свойств. Для задачи «максимум» (автоматическая выгрузка) необходимо комбинировать запрос к свойствам, выгрузку итогов регистров в таблицу значений для скорости и объект WinHttp для передачи данных на сервер. Не забывайте проверять реквизит ЭтоГруппа() при переборе номенклатуры, чтобы исключить папки из процесса получения остатков.

← На главную