При интеграции систем на базе 1С через COMConnector разработчики часто сталкиваются с ситуацией, когда табличная часть (ТЧ) документа кажется «заблокированной» для изменений. Мы можем прочитать данные, но попытки вызвать методы Очистить() или Загрузить() приводят к ошибкам или сообщениям о недоступности объекта. В этой статье мы разберем причины такого поведения и рассмотрим проверенные способы модификации данных в удаленной базе.
Разберем типичную ошибку: попытку редактирования табличной части, полученной напрямую из ссылки. В 1С ДокументСсылка предназначена только для чтения. Чтобы получить возможность изменять реквизиты или табличные части, необходимо получить объект документа. Проанализируем правильную последовательность действий:
// Получаем ссылку на документ в удаленной базе
СсылкаУдаленнойБазы = COMСоединение.Документы.ТребованиеНакладная.НайтиПоНомеру("УТ000000345", ТекущаяДата);
Если НЕ СсылкаУдаленнойБазы.Пустая() Тогда
// ПЕРЕХОДИМ ОТ ССЫЛКИ К ОБЪЕКТУ
ОбъектУдаленнойБазы = СсылкаУдаленнойБазы.ПолучитьОбъект();
// Теперь табличная часть доступна для редактирования
ТЧ = ОбъектУдаленнойБазы.Материалы;
Иначе
Сообщить("Документ не найден!");
КонецЕсли;
Важно: Табличная часть, полученная через Ссылка.Материалы, позволит вам прочитать строки, но метод Загрузить() выдаст исключительную ситуацию «Объект недоступен для изменения».
Иногда даже при работе с объектом разработчики обнаруживают, что привычный метод Очистить() отсутствует в списке доступных команд COM-объекта. Это связано с особенностями реализации интерфейса IDispatch для коллекций в COM-соединении. Если Объект.ИмяТЧ.Очистить() не срабатывает, рассмотрим альтернативный способ полной очистки через цикл:
ТЧ_Объекта = ОбъектУдаленнойБазы.Товары;
ВсегоСтрок = ТЧ_Объекта.Количество();
// Удаляем строки с конца, чтобы не сбивались индексы
Пока ВсегоСтрок > 0 Цикл
ТЧ_Объекта.Удалить(ВсегоСтрок - 1);
ВсегоСтрок = ВсегоСтрок - 1;
КонецЦикла;
Метод Загрузить() требует, чтобы передаваемая в него ТаблицаЗначений была создана в том же самом контексте, где живет сам документ. Вы не можете создать таблицу значений в текущей базе (например, в БП) и передать её методу Загрузить() документа из внешней базы (например, УТ 10.3). Для системы это объекты разных типов.
Выясним, как правильно подготовить данные для загрузки:
ValueTable внутри COM-соединения.Загрузить().Посмотрим на пример загрузки результата запроса, выполненного в той же удаленной базе:
ЗапросВУдаленнойБазе = COMСоединение.NewObject("Запрос");
ЗапросВУдаленнойБазе.Текст = "ВЫБРАТЬ * ИЗ ..."; // Ваш запрос
// Выгружаем результат в ТЗ, созданную в контексте удаленной базы
ТЗ_Для_Загрузки = ЗапросВУдаленнойБазе.Выполнить().Выгрузить();
// Теперь метод Загрузить отработает корректно
ОбъектУдаленнойБазы.Товары.Загрузить(ТЗ_Для_Загрузки);
ОбъектУдаленнойБазы.Записать();
Если вам нужно перенести данные из локальной базы, самым надежным (хоть и не самым быстрым) способом будет построчное добавление. Разберем этот процесс:
Для Каждого СтрокаИсточник Из МояЛокальнаяТЗ Цикл
НоваяСтрока = ОбъектУдаленнойБазы.Товары.Добавить();
// ВАЖНО: Для ссылочных полей (Номенклатура, Склады)
// нужно найти соответствующую ссылку в удаленной базе
СсылкаНоменклатура = COMСоединение.Справочники.Номенклатура.НайтиПоКоду(СтрокаИсточник.Код);
НоваяСтрока.Номенклатура = СсылкаНоменклатура;
НоваяСтрока.Количество = СтрокаИсточник.Количество;
// ... заполнение остальных реквизитов
КонецЦикла;
ОбъектУдаленнойБазы.Записать(COMСоединение.РежимЗаписиДокумента.Запись);
Проанализируем несколько важных нюансов при работе через COMConnector:
Добавить() в цикле) — это отдельный сетевой вызов. Если строк сотни или тысячи, это будет работать медленно.Записать(). Выполняйте все изменения ТЧ и записывайте объект один раз в конце.Подведем итог: для успешной работы с табличными частями через COMConnector всегда используйте ПолучитьОбъект(), следите за тем, чтобы передаваемые таблицы значений создавались через COMСоединение.NewObject("ValueTable"), и помните о необходимости конвертации ссылочных типов данных в контекст удаленной базы.