Многие пользователи и начинающие разработчики платформы 1С:Предприятие сталкиваются с необходимостью отображения изменяемых наборов данных прямо в интерфейсе документа или справочника. Стандартные табличные части подходят для хранения данных в базе, но иногда требуется временный список, который не сохраняется в регистры или таблицы базы данных. Именно здесь на сцену выходит динамический список — мощный инструмент для построения гибких форм ввода.

В отличие от обычных полей формы, динамический список позволяет пользователю добавлять, удалять и редактировать строки интерактивно, используя встроенные механизмы платформы. Это решение идеально подходит для создания подборов товаров, временных расчетов или формирования сложных составов документов без привязки к жесткой структуре метаданных. Понимание принципов работы с СписокЗначений и ТабличноеПоле открывает новые горизонты в проектировании эргономичного интерфейса.

В данной статье мы подробно разберем алгоритм создания такого списка от объявления переменной до написания кода обработчиков событий. Мы затронем вопросы привязки данных, настройки колонок и реализации логики пересчета сумм на лету. Особое внимание уделим типичным ошибкам, которые допускают разработчики при работе с динамическими структурами в управляемых формах.

⚠️ Внимание: Поведение динамических списков может отличаться в зависимости от версии платформы 1С и режима совместимости конфигурации. В новых релизах механизмы работы с СписокЗначений становятся строже к типам данных, поэтому всегда проверяйте актуальность синтаксиса в справке по вашей версии платформы.

Подготовка структуры метаданных и переменных

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

Откройте редактор формы в конфигураторе и перейдите на вкладку «Переменные формы». Создайте новую переменную, например, с именем ВременныйСписок. В колонке «Тип» необходимо добавить тип СписокЗначений. Важно отметить, что для корректной работы с управляемыми формами тип переменной должен быть строго определен, иначе клиентская часть не сможет корректно отобразить данные. Если вы планируете хранить сложные структуры, можно также использовать тип Массив, но СписокЗначений предоставляет более удобный API для работы с колонками.

После создания переменной необходимо инициализировать её в модуле формы. Обычно это делается в обработчике события ПриСозданииНаСервере. Здесь мы создаем новый экземпляр объекта и добавляем в него необходимые колонки. Каждая колонка соответствует будущему столбцу в таблице на экране пользователя. Вы можете задать имя колонки, её тип и даже длину строки, если это необходимо для ограничения ввода.

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

ВременныйСписок = Новый СписокЗначений;

ВременныйСписок.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));

ВременныйСписок.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(15, 2)));

ВременныйСписок.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(15, 2)));

ВременныйСписок.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(15, 2)));

КонецПроцедуры

Определение типов колонок через ОписаниеТипов является критически важным моментом. Без явного указания типов система не сможет корректно создать ячейки ввода на клиенте, и пользователи столкнутся с ошибками при попытке ввести данные. Используйте квалификаторы для ограничения разрядности чисел, чтобы избежать переполнения или некорректных расчетов в дальнейшем.

Размещение элементов управления на форме

После того как переменная создана и инициализирована, необходимо вывести её на экран пользователя. Для этого в редакторе формы добавьте новый элемент управления типа ТабличноеПоле. Разместите его в нужной области формы, например, в группе «Товары» или «Состав». Свойство Поле у этого элемента должно быть связано с вашей переменной формы ВременныйСписок.

Настройка колонок табличного поля осуществляется через палитру свойств элемента. Вы можете вручную добавить колонки, соответствующие тем, что вы создали в списке значений, или позволить платформе сгенерировать их автоматически. Для каждой колонки задайте заголовок, который будет видеть пользователь, и укажите поле данных из списка значений. Например, для колонки с ценой укажите поле Цена.

Особое внимание уделите настройкам редактирования. Убедитесь, что свойство Редактирование установлено в значение Да или НаФорме, чтобы пользователи могли вносить изменения непосредственно в таблице. Также можно настроить ширину колонок и выравнивание текста. Для числовых полей рекомендуется использовать выравнивание по правому краю, а для текстовых — по левому, что улучшает восприятие информации.

  • 📊 Используйте группировку элементов для логического разделения статических данных и динамического списка.
  • ✏️ Включите режим «Только чтение» для расчетных колонок, таких как «Сумма», чтобы пользователи не могли изменить их вручную.
  • 🔍 Добавьте командную панель к табличному полю для быстрого доступа к функциям добавления и удаления строк.

Если вы хотите, чтобы список выглядел более презентабельно, можно настроить условное оформление. Например, выделять строки цветом, если количество товара превышает доступный остаток. Это делается через настройки условного оформления формы, где в качестве условия выступает выражение, проверяющее значение в колонке Количество.

📊 Какой способ создания списков вы используете чаще?
Табличные части документов
СписокЗначений на форме
Временные таблицы
Другое

Реализация логики добавления и удаления строк

Статический список, созданный на сервере, бесполезен без возможности управления им со стороны пользователя. Вам необходимо реализовать команды для добавления новых строк и удаления существующих. Создайте две команды в форме: ДобавитьСтроку и УдалитьСтроку. Обработчики этих команд будут содержать логику модификации объекта СписокЗначений.

В обработчике команды добавления вы создаете новый элемент списка и заполняете его начальными значениями. Часто требуется установить значения по умолчанию, например, текущую дату или единицу измерения. После добавления элемента в список необходимо обновить форму, чтобы изменения отобразились на экране. В управляемых приложениях это происходит автоматически при изменении коллекции, но иногда требуется явный вызов методов обновления.

&НаКлиенте

Процедура ДобавитьСтроку(Команда)

НовыйЭлемент = ВременныйСписок.Добавить();

НовыйЭлемент.Значение = ""; // Или структура, если используется

// Если список значений хранит значения, а не структуры, логика проще

// Но для нескольких колонок лучше использовать Структуру или ТаблицуЗначений внутри

КонецПроцедуры

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

При удалении строк важно предусмотреть проверку на выделение. Пользователь должен выделить строку, которую хочет удалить. Если выделение не сделано, выведите предупреждение. Используйте свойство ТекущиеДанные табличного поля для получения ссылки на активную строку. Это обеспечивает интуитивно понятный интерфейс, схожий со стандартными документами 1С.

⚠️ Внимание: При удалении элементов из коллекции во время перебора может возникнуть ошибка итерации. Всегда используйте корректные циклы или удаляйте элементы по индексу с учетом смещения, либо используйте метод Очистить для полного сброса списка.

Автоматический пересчет данных в реальном времени

Одной из главных ценностей динамического списка является возможность мгновенного пересчета итогов. Например, при изменении количества товара сумма строки должна обновляться автоматически, а общий итог по документу — пересчитываться с учетом всех строк списка. Для этого используется механизм событий изменения данных на клиенте.

В модуле формы создайте обработчик события ПриИзменении для соответствующих колонок табличного поля. В этом обработчике вы получаете доступ к измененной строке, считываете новые значения и производите необходимые арифметические операции. Результат записывается обратно в ячейку строки. Поскольку событие срабатывает на клиенте, пользователь видит результат мгновенно, без обращения к серверу.

Для пересчета общих итогов (например, «Итого по документу») можно использовать событие ПриИзменении у самой таблицы или отдельный регистр накопления на форме. Однако, более производительным способом является создание вычисляемого поля в форме, которое обновляется при каждом изменении списка. Вы можете написать функцию, которая проходит циклом по всем строкам ВременныйСписок и суммирует значения колонки «Сумма».

  • ⚡ Используйте клиентские события для мгновенной реакции интерфейса на действия пользователя.
  • 🧮 Реализуйте проверку на деление на ноль при расчете удельных показателей.
  • 🔄 Синхронизируйте данные динамического списка с основными реквизитами документа перед записью.

Важно помнить о производительности. Если список содержит тысячи строк, цикл пересчета на клиенте может подтормаживать интерфейс. В таких случаях стоит ограничить количество строк или перенести тяжелые вычисления на сервер, вызывая их только по нажатию кнопки «Обновить» или при записи документа. Для стандартных задач торговли и склада клиентский пересчет работает отлично.

☑️ Проверка динамического списка

Выполнено: 0 / 5

Сохранение данных в информационную базу

Динамический список существует только в оперативной памяти формы до момента записи объекта. Чтобы данные не потерялись, их необходимо перенести в постоянную структуру хранения — обычно это табличная часть документа или отдельный регистр сведений. Этот процесс происходит в обработчике события ПередЗаписью на сервере.

В процедуре ПередЗаписью вы должны очистить соответствующую табличную часть документа и заполнить её данными из вашего временного списка. Это делается через цикл по элементам ВременныйСписок. Для каждой строки создается новая строка в табличной части, и значения копируются из колонок списка в реквизиты строки табличной части. После этого объект готов к стандартной процедуре записи в базу данных.

&НаСервере

Процедура ПередЗаписью(Отказ, РежимЗаписи, ПараметрыЗаписи)

// Очищаем старую табличную часть

Объект.Товары.Очистить();

// Переносим данные из динамического списка

Для Каждого ЭлементСписка Из ВременныйСписок Цикл

НоваяСтрока = Объект.Товары.Добавить();

НоваяСтрока.Номенклатура = ЭлементСписок.Номенклатура;

НоваяСтрока.Количество = ЭлементСписок.Количество;

НоваяСтрока.Цена = ЭлементСписок.Цена;

НоваяСтрока.Сумма = ЭлементСписок.Сумма;

КонецЦикла;

КонецПроцедуры

Обратная операция — чтение данных из базы при открытии формы — выполняется в обработчике ПриЧтенииНаСервере. Здесь вы загружаете данные из табличной части документа во временный список, чтобы пользователь мог продолжить работу с ними. Следите за тем, чтобы типы данных совпадали, иначе могут возникнуть ошибки преобразования типов при присваивании значений.

💡

Перед переносом данных в табличную часть всегда проверяйте список на наличие дублей номенклатуры. Объединение одинаковых позиций упростит учет и предотвратит разрастание базы данных.

Оптимизация и обработка ошибок

Работа с динамическими структурами требует внимательного отношения к обработке исключительных ситуаций. Пользователь может ввести некорректные данные, например, отрицательное количество или текст вместо числа. Чтобы предотвратить падение приложения, используйте конструкции Попытка...Исключение в критических участках кода, особенно при преобразовании типов или обращении к базе данных.

Также стоит реализовать валидацию данных перед записью. Проверьте, заполнены ли все обязательные колонки, не превышает ли сумма лимиты и т.д. Если проверка не пройдена, установите параметр Отказ в значение Истина и выведите понятное сообщение пользователю. Это поможет избежать появления в базе «мусорных» записей с некорректными данными.

Для больших списков рассмотрите возможность использования виртуальных таблиц или отложенной загрузки данных, если функционал формы позволяет. Хотя СписокЗначений хранится в памяти, чрезмерное заполнение может потреблять много ресурсов клиента. Оптимизируйте состав колонок: не выводите те поля, которые не нужны пользователю для визуального контроля.

Этап работы Место выполнения Ключевой метод Назначение
Инициализация Сервер ПриСозданииНаСервере Создание структуры списка
Добавление строки Клиент Добавить() Расширение списка
Пересчет Клиент ПриИзменении Обновление итогов
Сохранение Сервер ПередЗаписью Фиксация в БД

⚠️ Внимание: При работе в тонком клиенте в режиме управляемого приложения убедитесь, что все методы, изменяющие данные, которые влияют на последующую запись, корректно помечены контекстом выполнения (НаКлиенте, НаСервере). Ошибки контекста — самая частая причина неработоспособности форм.

Секреты производительности

Для списков более 1000 строк рассмотрите использование временных таблиц вместо СписокЗначений, так как они оптимизированы для работы с большими объемами данных и поддерживают индексацию.

💡

Динамический список на форме — это мост между удобным интерфейсом и строгой структурой базы данных, позволяющий гибко управлять вводом информации без изменения конфигурации.

Часто задаваемые вопросы

Можно ли использовать динамический список для работы с большими объемами данных?

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

Как сделать колонку списка доступной только для чтения?

В свойствах колонки табличного поля на форме установите параметр ТолькоПросмотр в значение Истина. Также можно программно управлять этим свойством в зависимости от условий, например, блокировать редактирование цены, если товар уже проведен.

Почему данные из динамического списка не сохраняются в документе?

Чаще всего проблема заключается в отсутствии кода переноса данных в обработчике ПередЗаписью. Динамический список живет только в памяти формы, поэтому явный код копирования данных в табличную часть документа обязателен.

Можно ли добавить кнопку проведения для каждой строки списка?

Да, вы можете добавить колонку типа ПолеФормы с элементом управления Кнопка в табличное поле. Обработчик нажатия такой кнопки позволит выполнять действия конкретно с выбранной строкой, например, резервировать товар.