Как снять запрет на удаление строк из табличной части в корректирующем документе «Табель» в 1С

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом
← На главную

Часто при работе с расчетными документами в решениях «1С:Зарплата и управление персоналом» или «1С:ERP Управление предприятием» пользователи и разработчики сталкиваются со следующей проблемой. При создании корректирующего документа «Табель» (когда в нем заполнен реквизит ИсправленныйДокумент) кнопка «Удалить» на форме становится недоступной, а нажатие клавиши Del на клавиатуре не дает никаких результатов. Более того, при попытке отладить этот процесс выясняется, что программа даже не заходит в обработчик события ПередУдалением табличной части.

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

Техническая причина блокировки: почему не заходит в «ПередУдалением»

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

Рассмотрим, как это свойство влияет на поведение интерфейса:

  1. Если свойство установлено в значение Истина, пользователь может свободно добавлять, копировать и удалять строки табличной части.
  2. Если свойство установлено в значение Ложь, платформа полностью блокирует любые интерактивные действия с составом строк на уровне самого интерфейса.

В типовом коде формы документа «Табель» при открытии выполняется проверка заполненности реквизита исправления. Если это корректирующий документ, срабатывает программная инструкция:

Элементы.ДанныеОВремени.ИзменятьСоставСтрок = Ложь;

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

Методологическая причина: зачем это сделано в 1С

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

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

Однако на практике возникают ситуации, когда документ-исправление был создан ошибочно или состав сотрудников в нем действительно требует ручной корректировки. Рассмотрим, как решить эту задачу.

Способ 1. Временное снятие связи с исправляемым документом (пользовательский метод)

Если вам нужно разово отредактировать состав строк без изменения программного кода и снятия конфигурации с поддержки, можно использовать следующую последовательность действий:

  1. Запишите или запомните, какой документ выбран в реквизите ИсправленныйДокумент.
  2. Очистите поле ИсправленныйДокумент на форме табеля. Если это поле заблокировано для редактирования на форме, воспользуйтесь стандартной обработкой «Групповое изменение реквизитов» (ее можно открыть через меню «Администрирование» — «Обслуживание» — «Корректировка данных»).
  3. Установите значение реквизита ИсправленныйДокумент в пустое значение для вашего табеля.
  4. Переоткройте документ «Табель». Так как связь с исходным документом временно разорвана, платформа разблокирует управление табличной частью. Вы сможете свободно удалять и добавлять строки.
  5. После удаления лишних строк снова заполните реквизит ИсправленныйДокумент ссылкой на первичный табель (вручную или через групповое изменение реквизитов) и проведите документ.

Способ 2. Программная разблокировка через расширение конфигурации

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

Разберем по шагам, как это сделать:

  1. Создайте новое расширение конфигурации или откройте существующее.
  2. Добавьте в расширение форму документа «Табель» (обычно это форма ФормаДокумента).
  3. Создайте обработчик события, выполняющийся после стандартного заполнения данных на сервере.

Напишем следующий код в модуле формы расширения:


&После("ПриЧтенииНаСервере")
Процедура Ист_ПриЧтенииНаСервере(ТекущийОбъект)
    
    // Снимаем блокировку изменения состава строк, установленную типовым кодом
    Если ЗначениеЗаполнено(Объект.ИсправленныйДокумент) Тогда
        Элементы.ДанныеОВремени.ИзменятьСоставСтрок = Истина;
    КонецЕсли;
    
КонецПроцедуры

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

Способ 3. Программное удаление строк через внешнюю обработку

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

Мы можем написать внешнюю обработку, которая будет программно находить и удалять ненужные строки из табеля, обходя любые ограничения формы. Посмотрим на пример серверного кода для удаления строки по определенному сотруднику:


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

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

← На главную