Как работать с табличной частью документа через COMConnector: методы Загрузить() и Очистить()

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При интеграции систем на базе 1С через COMConnector разработчики часто сталкиваются с ситуацией, когда табличная часть (ТЧ) документа кажется «заблокированной» для изменений. Мы можем прочитать данные, но попытки вызвать методы Очистить() или Загрузить() приводят к ошибкам или сообщениям о недоступности объекта. В этой статье мы разберем причины такого поведения и рассмотрим проверенные способы модификации данных в удаленной базе.

Главная причина: Ссылка против Объекта

Разберем типичную ошибку: попытку редактирования табличной части, полученной напрямую из ссылки. В 1С ДокументСсылка предназначена только для чтения. Чтобы получить возможность изменять реквизиты или табличные части, необходимо получить объект документа. Проанализируем правильную последовательность действий:


// Получаем ссылку на документ в удаленной базе
СсылкаУдаленнойБазы = COMСоединение.Документы.ТребованиеНакладная.НайтиПоНомеру("УТ000000345", ТекущаяДата);

Если НЕ СсылкаУдаленнойБазы.Пустая() Тогда
    // ПЕРЕХОДИМ ОТ ССЫЛКИ К ОБЪЕКТУ
    ОбъектУдаленнойБазы = СсылкаУдаленнойБазы.ПолучитьОбъект();
    
    // Теперь табличная часть доступна для редактирования
    ТЧ = ОбъектУдаленнойБазы.Материалы;
Иначе
    Сообщить("Документ не найден!");
КонецЕсли;

Важно: Табличная часть, полученная через Ссылка.Материалы, позволит вам прочитать строки, но метод Загрузить() выдаст исключительную ситуацию «Объект недоступен для изменения».

Ограничения COM-прокси и метод Очистить()

Иногда даже при работе с объектом разработчики обнаруживают, что привычный метод Очистить() отсутствует в списке доступных команд COM-объекта. Это связано с особенностями реализации интерфейса IDispatch для коллекций в COM-соединении. Если Объект.ИмяТЧ.Очистить() не срабатывает, рассмотрим альтернативный способ полной очистки через цикл:


ТЧ_Объекта = ОбъектУдаленнойБазы.Товары;
ВсегоСтрок = ТЧ_Объекта.Количество();

// Удаляем строки с конца, чтобы не сбивались индексы
Пока ВсегоСтрок > 0 Цикл
    ТЧ_Объекта.Удалить(ВсегоСтрок - 1);
    ВсегоСтрок = ВсегоСтрок - 1;
КонецЦикла;

Как правильно использовать метод Загрузить()

Метод Загрузить() требует, чтобы передаваемая в него ТаблицаЗначений была создана в том же самом контексте, где живет сам документ. Вы не можете создать таблицу значений в текущей базе (например, в БП) и передать её методу Загрузить() документа из внешней базы (например, УТ 10.3). Для системы это объекты разных типов.

Выясним, как правильно подготовить данные для загрузки:

  1. Создайте объект ValueTable внутри COM-соединения.
  2. Программно воссоздайте в ней структуру колонок, идентичную табличной части.
  3. Заполните её данными, создавая COM-объекты для ссылочных типов.
  4. Вызовите метод Загрузить().

Посмотрим на пример загрузки результата запроса, выполненного в той же удаленной базе:


ЗапросВУдаленнойБазе = COMСоединение.NewObject("Запрос");
ЗапросВУдаленнойБазе.Текст = "ВЫБРАТЬ * ИЗ ..."; // Ваш запрос

// Выгружаем результат в ТЗ, созданную в контексте удаленной базы
ТЗ_Для_Загрузки = ЗапросВУдаленнойБазе.Выполнить().Выгрузить();

// Теперь метод Загрузить отработает корректно
ОбъектУдаленнойБазы.Товары.Загрузить(ТЗ_Для_Загрузки);
ОбъектУдаленнойБазы.Записать();

Построчное добавление данных

Если вам нужно перенести данные из локальной базы, самым надежным (хоть и не самым быстрым) способом будет построчное добавление. Разберем этот процесс:


Для Каждого СтрокаИсточник Из МояЛокальнаяТЗ Цикл
    НоваяСтрока = ОбъектУдаленнойБазы.Товары.Добавить();
    
    // ВАЖНО: Для ссылочных полей (Номенклатура, Склады) 
    // нужно найти соответствующую ссылку в удаленной базе
    СсылкаНоменклатура = COMСоединение.Справочники.Номенклатура.НайтиПоКоду(СтрокаИсточник.Код);
    
    НоваяСтрока.Номенклатура = СсылкаНоменклатура;
    НоваяСтрока.Количество = СтрокаИсточник.Количество;
    // ... заполнение остальных реквизитов
КонецЦикла;

ОбъектУдаленнойБазы.Записать(COMСоединение.РежимЗаписиДокумента.Запись);

Советы по оптимизации

Проанализируем несколько важных нюансов при работе через COMConnector:

Подведем итог: для успешной работы с табличными частями через COMConnector всегда используйте ПолучитьОбъект(), следите за тем, чтобы передаваемые таблицы значений создавались через COMСоединение.NewObject("ValueTable"), и помните о необходимости конвертации ссылочных типов данных в контекст удаленной базы.

← На главную