Работа с табличными частями документов в версии 1С 7.7 имеет ряд существенных отличий от современной платформы 1С 8.x. Основная сложность для начинающих разработчиков заключается в понимании того, как позиционироваться на конкретном документе и как эффективно извлечь данные его строк, не создавая избыточной нагрузки на систему. В рамках данной статьи мы подробно разберем несколько способов решения этой задачи, проанализируем типичные ошибки и выясним, как правильно работать с единицами измерения и налогами.
Этот способ является наиболее классическим и понятным. Его удобно использовать, когда у вас уже есть ссылка на документ (например, полученная из Таблицы Значений, результата запроса или при выборочном переносе данных между базами), и вам нужно совершить итерацию по его строкам. Рассмотрим алгоритм действий:
Документ нужного вида (или универсальный объект, если вид неизвестен).НайтиДокумент() для позиционирования на конкретной записи базы данных.ВыбратьСтроки(), чтобы инициализировать выборку табличной части.Пока ... ПолучитьСтроку() = 1.Проанализируем пример кода:
// Предположим, что СсылкаНаДокумент у нас уже есть
Док = СоздатьОбъект("Документ.ЗаявкаПокупателя");
Если Док.НайтиДокумент(СсылкаНаДокумент) = 1 Тогда
// Инициализируем выборку строк
Док.ВыбратьСтроки();
// Перебираем строки документа
Пока Док.ПолучитьСтроку() = 1 Цикл
Сообщить("Товар: " + Док.Номенклатура);
Сообщить("Количество: " + Док.Количество);
КонецЦикла;
КонецЕсли;
Важное замечание: Часто новички пытаются использовать метод ВыбратьДокументы(), передавая туда ссылку. Это грубая ошибка. Метод ВыбратьДокументы(ДокСсылка) в 1С 7.7 открывает выборку всех документов данного вида, начиная с указанного и до конца установленного периода. Для работы с конкретным экземпляром всегда используйте НайтиДокумент().
Если ваша задача — обработать большое количество документов, использование СоздатьОбъект внутри цикла по результатам запроса приведет к крайне низкой производительности (так называемая проблема "N+1"). Вместо этого мы можем заставить систему выдать нам строки документов сразу в тексте запроса. Для этого используется специальная группировка СтрокаДокумента.
Рассмотрим, как это реализовать:
ТекстЗапроса = "
|Период с ВыбНачПериода по ВыбКонПериода;
|ТекДок = Документ.ЗаявкаПокупателя.ТекущийДокумент;
|Товар = Документ.ЗаявкаПокупателя.Номенклатура;
|Кво = Документ.ЗаявкаПокупателя.Количество;
|Группировка ТекДок;
|Группировка СтрокаДокумента; // Это ключ к получению строк ТЧ
|";
Запрос = СоздатьОбъект("Запрос");
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
Пока Запрос.Группировка("ТекДок") = 1 Цикл
// Здесь мы в шапке документа
Сообщить("Обработка документа: " + Запрос.ТекДок);
Пока Запрос.Группировка("СтрокаДокумента") = 1 Цикл
// Здесь мы работаем со строкой конкретного документа
Сообщить("--- Номенклатура: " + Запрос.Товар + " Кол-во: " + Запрос.Кво);
КонецЦикла;
КонецЦикла;
КонецЕсли;
Такой подход работает значительно быстрее, так как платформа оптимизирует обращение к таблицам базы данных (DH — шапки и DT — таблицы строк) на уровне SQL-запроса или внутреннего движка базы данных.
При переборе табличной части "Товары" важно помнить техническую особенность 1С 7.7: реквизит Количество в строке документа хранится в тех единицах, которые выбрал пользователь. Если вам необходимо получить данные для управленческого учета или синхронизации с другими системами (например, для выгрузки товаров и остатков в МойСклад в базовых единицах), обязательно учитывайте Коэффициент.
Проанализируем ситуацию на примере:
// В строке документа: Товар "Сахар", Кол-во 1, Ед. Изм. "Мешок (50кг)", Коэффициент 50
// Базовая единица - "кг"
КоличествоВБазовых = Док.Количество * Док.Коэффициент;
// Результат будет 50 (кг), в то время как Док.Количество вернет 1 (мешок)
Помните: коэффициент в 7.7 обычно является реквизитом самой табличной части документа, который заполняется при выборе единицы измерения. Если его игнорировать, данные в выгрузке будут некорректными.
Для глубокого понимания процесса программисту полезно знать, как данные лежат "под капотом" (особенно в SQL-версиях 1С 7.7, где также важно уметь отслеживать блокировки базы данных):
IDDOC.Если ваша задача — выгрузка в JSON (как, например, в решении для технической выгрузки номенклатуры в JSON), и вы используете прямые SQL-запросы (через 1С++), вы можете соединить эти таблицы одним JOIN, что позволит мгновенно получать плоскую таблицу данных для последующей сериализации.
Поскольку в 1С 7.7 нет встроенного объекта Структура или Соответствие, сборка JSON-строки выполняется вручную. При переборе документов и их строк мы рекомендуем использовать следующий алгоритм:
[.{ ... }."items": [.ПолучитьСтроку()) добавляем объекты товаров.Пример обработки спецсимволов для JSON в 7.7:
Функция ЭкранироватьJSON(Знач Стр)
Стр = СтрЗаменить(Стр, "\", "\\");
Стр = СтрЗаменить(Стр, """", "\""");
Стр = СтрЗаменить(Стр, РазделительСтрок, "\n");
Возврат Стр;
КонецФункции
Подведем итог: Для разовых операций или работы в интерактивных формах используйте НайтиДокумент() и ВыбратьСтроки(). Для массовой обработки данных и выгрузок всегда отдавайте предпочтение Запросу с группировкой по строкам документа. Это обеспечит стабильность и быстродействие вашей системы даже при больших объемах данных.