Разработка и Конфигурация · 11 мин
Как очистить таблицу формы в 1С 8.3
Как очистить таблицу формы в 1С 8.3: методы Очистить() и Удалить(), работа с табличной частью, таблицей значений и динамическим списком, примеры кода и типичные ошибки.
Очистка таблицы на форме в 1С 8.3 — типовая задача разработчика, но способ решения зависит от того, какой именно объект стоит за элементом формы: табличная часть документа, реквизит формы типа «ТаблицаЗначений», дерево значений или динамический список. У каждого варианта свои методы и свои подводные камни: например, попытка вызвать Очистить() у динамического списка приведёт к ошибке, а очистка табличной части в обработчике на клиенте потребует учёта контекста сервера.
Чаще всего под «таблицей формы» понимают табличную часть объекта (например, «Товары» в документе) или реквизит формы с типом «ТаблицаЗначений», который выведен на форму как таблица. Для обоих случаев основной инструмент — метод Очистить(), но место его вызова и последующие действия (пересчёт итогов, модифицированность, обновление отображения) различаются. Ниже разобраны все основные сценарии с примерами кода.
Перед изменением кода формы убедитесь, что работаете в копии конфигурации или в расширении, если конфигурация на поддержке. Прямая правка типовых модулей усложнит обновление.
Определяем, какая таблица находится на форме
Прежде чем писать код, выясните, что именно отображает таблица. Откройте форму в конфигураторе и посмотрите свойство ПутьКДанным элемента «Таблица». Если путь ведёт к Объект.Товары — это табличная часть объекта. Если к реквизиту формы — это таблица значений или дерево значений, созданное разработчиком. Если таблица связана с динамическим списком (свойство «ДинамическийСписок»), очистка строк напрямую невозможна.
Также проверьте, есть ли у таблицы подчинённые данные: итоговые поля в подвале, связанные реквизиты (например, «Всего» в шапке документа), обработчики событий ПриИзменении, ПослеУдаления. Очистка таблицы программно не всегда вызывает эти обработчики, и итоги могут остаться устаревшими.
Очищайте через Объект.Товары.Очистить(), обычно в серверном контексте
Очищайте через ИмяРеквизита.Очистить(), доступно и на клиенте
Очистить() недоступен — меняйте отбор или текст запроса
Очистка табличной части документа или справочника
Табличная часть хранится в объекте, поэтому очистка выполняется через коллекцию строк: Объект.Товары.Очистить();. В модуле формы этот вызов обычно помещают в серверную процедуру, особенно если после очистки нужно выполнять серверные действия — пересчёт скидок, проверку остатков, заполнение по умолчанию.
Пример команды «Очистить товары» на форме документа:
&НаКлиенте
Процедура ОчиститьТовары(Команда)
Если Объект.Товары.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ОписаниеОповещения = Новый ОписаниеОповещения("ОчиститьТоварыЗавершение", ЭтотОбъект);
ПоказатьВопрос(ОписаниеОповещения, "Очистить табличную часть ""Товары""?", РежимДиалогаВопрос.ДаНет);
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьТоварыЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
Объект.Товары.Очистить();
Модифицированность = Истина;
КонецЕсли;
КонецПроцедуры
Обратите внимание на признак Модифицированность: очистка коллекции обычно устанавливает его автоматически, но при вызове из отдельных серверных процедур стоит проверить, что форма предложит сохранить документ при закрытии. Иначе пользователь может потерять изменения, решив, что они уже записаны.
Очистка реквизита формы типа «ТаблицаЗначений»
Если таблица на форме — это реквизит формы (данные не хранятся в объекте, а формируются программно, например результат обработки или временный отбор), очистка делается так же просто: ТаблицаРезультата.Очистить();. Такой вызов доступен и на клиенте, и на сервере, потому что таблица значений является сериализуемым реквизитом формы.
Тонкость в том, что после очистки часто нужно заново заполнить таблицу. Если таблица строится на сервере (например, запросом к базе), логично сделать одну серверную процедуру «ОбновитьТаблицу», в которой сначала вызывается Очистить(), затем выполняется заполнение. Это исключает ситуацию, когда при ошибке запроса на форме остаются устаревшие строки.
Для дерева значений метод Очистить() также работает и удаляет все строки вместе с иерархией. Если нужно удалить только строки верхнего уровня, сохранив структуру, используйте Дерево.Строки.Очистить() — эффект тот же, но такой вызов нагляднее показывает работу с коллекцией строк.
- 1Найдите в конфигураторе реквизит формы, к которому привязана таблица
- 2Добавьте команду формы и кнопку рядом с таблицей
- 3В обработчике вызовите ИмяРеквизита.Очистить()
- 4При необходимости перезаполните таблицу в той же или серверной процедуре
- 5Откройте форму в режиме предприятия и проверьте, что таблица пуста и итоги сброшены
Что делать с динамическим списком
Динамический список — это не коллекция строк, а результат запроса, поэтому методов Очистить() или Удалить() у него нет. Попытка обратиться к ним вызовет ошибку «Метод объекта не обнаружен». «Очистить» такой список можно только косвенно: установить отбор, которому ничего не соответствует, или изменить текст запроса.
Если цель — скрыть все строки до выполнения какого-то действия пользователя, типовой приём — установить отбор по заведомо пустому условию:
&НаСервере
Процедура СкрытьСтрокиСписка()
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Неопределено;
ЭлементОтбора.Использование = Истина;
КонецПроцедуры
Если же задача — физически удалить отображаемые документы, это уже не очистка таблицы формы, а удаление объектов базы. Такая операция выполняется на сервере через выборку и Удалить() у объектов, требует контроля ссылочной целостности и прав доступа. Не подменяйте одно действие другим.
Удаление отдельных строк вместо полной очистки
Не всегда нужно очищать таблицу целиком. Для удаления выбранных строк используйте метод Удалить() с указанием строки, а для удаления по условию — связку НайтиСтроки() и цикла:
// Удаление текущей строки таблицы формы
ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
Объект.Товары.Удалить(ТекущиеДанные);
КонецЕсли;
// Удаление строк по условию
СтрокиКУдалению = Объект.Товары.НайтиСтроки(Новый Структура("Отменено", Истина));
Для Каждого Строка Из СтрокиКУдалению Цикл
Объект.Товары.Удалить(Строка);
КонецЦикла;
Важно: НайтиСтроки() возвращает массив, поэтому удаление внутри цикла безопасно — коллекция строк табличной части при этом перебирается не напрямую. А вот удалять строки в цикле Для Каждого Строка Из Объект.Товары Цикл нельзя: это приведёт к пропуску строк или ошибке. Если нужен обход с удалением, идите по индексам с конца коллекции к началу.
Проверка результата и связанные данные
После очистки проверьте три вещи. Во-первых, сама таблица: Количество() коллекции должно быть равно нулю, а на форме не должно остаться визуальных «пустых» строк с данными. Во-вторых, итоги: поля «Всего», «Сумма документа», колонки с итогами в подвале таблицы. Если итоги считаются в обработчиках ПриИзменении полей строки, программная очистка их не вызовет — пересчитайте вручную.
В-третьих, связанные объекты: если по строкам табличной части строились движения, дополнительные таблицы формы или данные на других закладках, их тоже нужно синхронизировать. Хорошая практика — оформить очистку и все зависимые пересчёты одной серверной процедурой ОчиститьТаблицуНаСервере(), чтобы логика не расползалась по обработчикам.
Как проверить результат
Количество() = 0 после вызова Очистить()
Строки остались — очистка вызвана не у той коллекции
Суммы и счётчики сброшены в ноль
В шапке старая сумма — нет пересчёта после очистки
При закрытии форма предлагает записать изменения
Форма закрывается молча — изменения потеряются
Производительность при работе с большими таблицами
Метод Очистить() работает быстро даже на больших таблицах, потому что удаляет коллекцию целиком. А вот поэтапное удаление тысяч строк через Удалить() в цикле — заметно медленнее. Если нужно оставить только часть строк из большой таблицы значений, эффективнее создать новую таблицу и скопировать в неё нужные строки через Выгрузить() с отбором, чем удалять лишние по одной.
Для табличных частей объектов помните ещё об одном аспекте: физическое удаление строк из базы произойдёт только при записи объекта. Пока документ не записан, очистка существует только в данных формы. Если обработка очищает табличные части пакетно у множества документов, вызывайте Записать() у каждого объекта и оборачивайте операцию в транзакцию там, где требуется целостность.
FAQ
Чем отличается Очистить() от Удалить() у табличной части?
Очистить() удаляет все строки коллекции сразу и не принимает параметров. Удалить() удаляет одну конкретную строку — либо по объекту строки, либо по индексу. Для полной очистки всегда используйте Очистить(): это короче и быстрее.
Почему после очистки таблицы в шапке документа осталась старая сумма?
Итоговые реквизиты обычно пересчитываются в обработчиках событий изменения полей строки, а программный вызов Очистить() эти обработчики не запускает. Добавьте после очистки явный пересчёт — например, вызов процедуры, которая суммирует колонку и записывает результат в реквизит шапки.
Можно ли очистить таблицу формы на клиенте без вызова сервера?
Да, если данные доступны в клиентском контексте: реквизиты формы типа «ТаблицаЗначений» и табличные части объекта очищаются на клиенте вызовом Очистить(). Вызов сервера нужен только если после очистки требуется серверная логика — запросы к базе, пересчёт по данным регистров.
Как очистить динамический список на форме?
Напрямую — никак: у динамического списка нет метода Очистить(). Чтобы список ничего не показывал, установите отбор с заведомо невыполнимым условием или измените текст запроса. Если нужно удалить сами записи из базы, это отдельная операция с объектами на сервере.
Как удалить только строки, отмеченные пользователем флажком?
Используйте НайтиСтроки() со структурой отбора по колонке флажка: метод вернёт массив найденных строк, который безопасно обходится в цикле с вызовом Удалить() для каждой строки. Не удаляйте строки внутри прямого перебора коллекции — это приводит к пропускам.
Восстановятся ли строки, если очистить таблицу и закрыть форму без записи?
Для табличной части объекта — да: если не записывать объект, в базе останутся прежние строки. Для реквизита формы типа «ТаблицаЗначений» данные не хранятся в базе вовсе, поэтому после закрытия формы они будут потеряны независимо от записи.
Что важно запомнить
Табличную часть и таблицу значений очищайте методом Очистить(), динамический список — через отбор или запрос. После очистки пересчитайте итоги, проверьте модифицированность и запишите объект, если изменения должны сохраниться в базе. Перед удалением данных всегда запрашивайте подтверждение пользователя.