Как исправить ошибку «Параметр номер 2» при программном копировании строк в 1С:УТ 11

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При разработке расширений для 1С:Управление торговлей 11 (УТ 11) программисты часто сталкиваются с необходимостью автоматизировать рутинные действия пользователей. Одной из таких задач является автоматическое обновление данных в документе «Установка цен номенклатуры» при изменении цен в «Приобретении товаров и услуг». Однако попытка программно вызвать штатный механизм «Скопировать строки» часто приводит к трудноуловимой ошибке в общих модулях: «Недопустимое значение параметра (параметр номер '2')». В этой статье мы подробно разберем причины этой проблемы и найдем несколько способов её решения.

Анализируем причину возникновения ошибки

Давайте проанализируем ситуацию: ошибка возникает в общем модуле ОбщегоНазначенияУТКлиентСервер в функции ЕстьРеквизитОбъекта. Код стопорится на строке:

ЗаполнитьЗначенияСвойств(СтруктураРеквизита, Объект);

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

Важно понимать различие в управляемых формах: коллекция ВыделенныеСтроки содержит не индексы (0, 1, 2...) и не номера строк (1, 2, 3...), а уникальные идентификаторы строк текущего сеанса формы.

Решение №1: Правильное программное выделение строк

Если нам необходимо имитировать выделение всех строк пользователем, чтобы отработала стандартная команда СкопироватьСтроки, мы не можем просто добавлять туда порядковые номера. Вместо этого мы должны получить системный идентификатор каждой строки. Рассмотрим правильный код:


// В контексте клиентской процедуры формы
Для каждого Стр Из Объект.Товары Цикл
    // Используем метод ПолучитьИдентификатор(), чтобы получить ID строки для коллекции
    Элементы.Товары.ВыделенныеСтроки.Добавить(Стр.ПолучитьИдентификатор());
КонецЦикла;

// Теперь можно безопасно вызывать программно команду копирования
СкопироватьСтрокиНаСервере("Товары");

Почему это работает: Метод ПолучитьИдентификатор() возвращает число, которое форма сопоставляет с конкретным объектом строки табличной части. Когда штатный механизм копирования получает этот идентификатор, он успешно находит строку через НайтиПоИдентификатору() и получает полноценный объект строки, у которого есть все необходимые реквизиты для функции ЗаполнитьЗначенияСвойств.

Решение №2: Использование Таблицы Значений и прямого обращения к буферу

Иногда использование коллекции ВыделенныеСтроки неудобно или приводит к лишним срабатываниям событий формы (например, ПриАктивизацииЯчейки). В таком случае мы можем реализовать более «чистое» решение, подготовив данные самостоятельно и поместив их в буфер обмена 1С. Разберем этот алгоритм по шагам:

  1. Выгружаем строки табличной части в ТаблицуЗначений.
  2. Очищаем таблицу от служебных колонок, которые не должны переноситься (идентификаторы, ключи связи).
  3. Используем метод ОбщегоНазначения.СкопироватьВБуферОбмена.

Пример реализации такой процедуры:


Процедура АЗЦ_СкопироватьВсеСтрокиВБуфер()
    // Выгружаем данные ТЧ документа
    ТаблицаДанных = Объект.Товары.Выгрузить();
    
    // Удаляем технические колонки, которые могут помешать вставке в другой документ
    МассивИсключений = Новый Массив;
    МассивИсключений.Добавить("ИдентификаторСтроки");
    МассивИсключений.Добавить("КлючСвязи");
    
    Для Каждого ИмяКолонки Из МассивИсключений Цикл
        Если ТаблицаДанных.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда
            ТаблицаДанных.Колонки.Удалить(ИмяКолонки);
        КонецЕсли;
    КонецЦикла;
    
    // Помещаем в буфер обмена 1С (стандартный механизм "КопированиеВставкаСтрок")
    ОбщегоНазначения.СкопироватьВБуферОбмена(ТаблицаДанных, "КопированиеВставкаСтрок");
КонецПроцедуры

Преимущество этого метода в том, что он работает стабильнее и не зависит от текущего состояния элементов интерфейса (фокуса, выделения или видимости колонок).

Решение №3: Архитектурно верный подход (Заполнение по основанию)

Давайте выясним, зачем вообще использовать буфер обмена? Имитация нажатия кнопок пользователем — это всегда риск. В типовой конфигурации УТ 11 документ «Установка цен номенклатуры» уже умеет заполняться на основании «Приобретения товаров и услуг».

Вместо программного копирования строк через буфер, проанализируем возможность использования штатного механизма:

Рассмотрим пример открытия формы с заполнением:


ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Основание", Объект.Ссылка);
ОткрытьФорму("Документ.УстановкаЦенНоменклатуры.ФормаОбъекта", ПараметрыФормы);

Проблема события «ПриАктивизацииЯчейки»

Часто ошибка «Параметр номер 2» проявляется косвенно через событие ТоварыПриАктивизацииЯчейки. Когда мы программно меняем выделение строк, форма пытается обновить связанные данные (например, номенклатуру партнера или ГТД). Если в этот момент Элементы.Товары.ТекущиеДанные возвращают Неопределено (что бывает при пакетном изменении выделения), код падает.

Чтобы этого избежать, всегда добавляйте проверку в начало обработчика события:


&НаКлиенте
Процедура ТоварыПриАктивизацииЯчейки(Элемент)
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    // ... далее ваш код
КонецПроцедуры

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

Мы выяснили, что причина ошибки кроется в попытке передать в методы обработки строк НомерСтроки вместо ИдентификатораСтроки. Для решения проблемы мы рекомендуем:

  1. Использовать Стр.ПолучитьИдентификатор() при работе с коллекцией ВыделенныеСтроки.
  2. Для надежной передачи данных между документами использовать выгрузку в ТаблицуЗначений и метод СкопироватьВБуферОбмена.
  3. По возможности отдавать предпочтение штатным механизмам заполнения по основанию, а не имитации действий пользователя.

Соблюдение этих правил сделает ваш код в УТ 11 устойчивым к обновлениям и избавит пользователей от внезапных ошибок при записи документов.

← На главную