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

Программист 1С v7.7
← На главную

Работа с табличными частями документов в версии 1С 7.7 имеет ряд существенных отличий от современной платформы 1С 8.x. Основная сложность для начинающих разработчиков заключается в понимании того, как позиционироваться на конкретном документе и как эффективно извлечь данные его строк, не создавая избыточной нагрузки на систему. В рамках данной статьи мы подробно разберем несколько способов решения этой задачи, проанализируем типичные ошибки и выясним, как правильно работать с единицами измерения и налогами.

Способ 1. Получение строк через объектную модель (метод НайтиДокумент)

Этот способ является наиболее классическим и понятным. Его удобно использовать, когда у вас уже есть ссылка на документ (например, полученная из Таблицы Значений, результата запроса или при выборочном переносе данных между базами), и вам нужно совершить итерацию по его строкам. Рассмотрим алгоритм действий:

  1. Создаем объект типа Документ нужного вида (или универсальный объект, если вид неизвестен).
  2. Используем метод НайтиДокумент() для позиционирования на конкретной записи базы данных.
  3. Вызываем метод ВыбратьСтроки(), чтобы инициализировать выборку табличной части.
  4. Организуем цикл Пока ... ПолучитьСтроку() = 1.

Проанализируем пример кода:


// Предположим, что СсылкаНаДокумент у нас уже есть
Док = СоздатьОбъект("Документ.ЗаявкаПокупателя");

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

Важное замечание: Часто новички пытаются использовать метод ВыбратьДокументы(), передавая туда ссылку. Это грубая ошибка. Метод ВыбратьДокументы(ДокСсылка) в 1С 7.7 открывает выборку всех документов данного вида, начиная с указанного и до конца установленного периода. Для работы с конкретным экземпляром всегда используйте НайтиДокумент().

Способ 2. Оптимальное получение строк через Запрос (Query)

Если ваша задача — обработать большое количество документов, использование СоздатьОбъект внутри цикла по результатам запроса приведет к крайне низкой производительности (так называемая проблема "N+1"). Вместо этого мы можем заставить систему выдать нам строки документов сразу в тексте запроса. Для этого используется специальная группировка СтрокаДокумента.

Рассмотрим, как это реализовать:


ТекстЗапроса = "
|Период с ВыбНачПериода по ВыбКонПериода;
|ТекДок = Документ.ЗаявкаПокупателя.ТекущийДокумент;
|Товар = Документ.ЗаявкаПокупателя.Номенклатура;
|Кво = Документ.ЗаявкаПокупателя.Количество;
|Группировка ТекДок;
|Группировка СтрокаДокумента; // Это ключ к получению строк ТЧ
|";

Запрос = СоздатьОбъект("Запрос");
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
    Пока Запрос.Группировка("ТекДок") = 1 Цикл
        // Здесь мы в шапке документа
        Сообщить("Обработка документа: " + Запрос.ТекДок);
        
        Пока Запрос.Группировка("СтрокаДокумента") = 1 Цикл
            // Здесь мы работаем со строкой конкретного документа
            Сообщить("--- Номенклатура: " + Запрос.Товар + " Кол-во: " + Запрос.Кво);
        КонецЦикла;
    КонецЦикла;
КонецЕсли;

Такой подход работает значительно быстрее, так как платформа оптимизирует обращение к таблицам базы данных (DH — шапки и DT — таблицы строк) на уровне SQL-запроса или внутреннего движка базы данных.

Работа с единицами измерения и коэффициентами

При переборе табличной части "Товары" важно помнить техническую особенность 1С 7.7: реквизит Количество в строке документа хранится в тех единицах, которые выбрал пользователь. Если вам необходимо получить данные для управленческого учета или синхронизации с другими системами (например, для выгрузки товаров и остатков в МойСклад в базовых единицах), обязательно учитывайте Коэффициент.

Проанализируем ситуацию на примере:


// В строке документа: Товар "Сахар", Кол-во 1, Ед. Изм. "Мешок (50кг)", Коэффициент 50
// Базовая единица - "кг"

КоличествоВБазовых = Док.Количество * Док.Коэффициент;
// Результат будет 50 (кг), в то время как Док.Количество вернет 1 (мешок)

Помните: коэффициент в 7.7 обычно является реквизитом самой табличной части документа, который заполняется при выборе единицы измерения. Если его игнорировать, данные в выгрузке будут некорректными.

Особенности структуры хранения данных (DH и DT)

Для глубокого понимания процесса программисту полезно знать, как данные лежат "под капотом" (особенно в SQL-версиях 1С 7.7, где также важно уметь отслеживать блокировки базы данных):

Если ваша задача — выгрузка в JSON (как, например, в решении для технической выгрузки номенклатуры в JSON), и вы используете прямые SQL-запросы (через 1С++), вы можете соединить эти таблицы одним JOIN, что позволит мгновенно получать плоскую таблицу данных для последующей сериализации.

Формирование JSON с вложенными строками

Поскольку в 1С 7.7 нет встроенного объекта Структура или Соответствие, сборка JSON-строки выполняется вручную. При переборе документов и их строк мы рекомендуем использовать следующий алгоритм:

  1. Открываем основной массив JSON символом [.
  2. Для каждого документа формируем объект { ... }.
  3. Внутри объекта документа создаем ключ "items": [.
  4. В цикле по строкам (ПолучитьСтроку()) добавляем объекты товаров.
  5. Аккуратно обрабатываем запятые (запятая ставится перед каждым элементом, кроме первого).

Пример обработки спецсимволов для JSON в 7.7:


Функция ЭкранироватьJSON(Знач Стр)
    Стр = СтрЗаменить(Стр, "\", "\\");
    Стр = СтрЗаменить(Стр, """", "\""");
    Стр = СтрЗаменить(Стр, РазделительСтрок, "\n");
    Возврат Стр;
КонецФункции

Подведем итог: Для разовых операций или работы в интерактивных формах используйте НайтиДокумент() и ВыбратьСтроки(). Для массовой обработки данных и выгрузок всегда отдавайте предпочтение Запросу с группировкой по строкам документа. Это обеспечит стабильность и быстродействие вашей системы даже при больших объемах данных.

← На главную